From patchwork Wed Apr 5 14:03:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 79719 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp363505vqo; Wed, 5 Apr 2023 07:48:29 -0700 (PDT) X-Google-Smtp-Source: AKy350Ywx5n/lm+/AdQVMgThlwGim2bIl3A4qtAytF2U8/+r36C3kIzdXv86zRjpjOgS00icxHfx X-Received: by 2002:a05:6402:1001:b0:501:d43e:d1e5 with SMTP id c1-20020a056402100100b00501d43ed1e5mr2124068edu.2.1680706109305; Wed, 05 Apr 2023 07:48:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680706109; cv=none; d=google.com; s=arc-20160816; b=dkxXL5qFJQm+mJj64bb1JvXvYxBvEAHmwrAfq59KAVGKf6N/lTX67gBeHmhkkLHozZ BWT0BAkeKxelzdvwIIIDHd+yJ+HX56AXMyYLW91aNbkPwd+7CkIZ8ekPJEaVozcCs+2l sXoWrok0Dmx7dDg99DjQuCxgN3WXyOLkrmqE3jij6aXG2DUn3uGXRWcEAXWKd6LkAlgW GcZQbI6csSpM7SS9ZZn8vgWMXAp28EnMxmIHs1Ry1hMzi+HTFhx7/X5PheuQ98vqzMmd HuJCzJ6XSZAA9+4tHUiccyRsS8AMU27bKOQcL4vvA6xmF6fOwWJI+5HSv5BKmTVdFFc3 saLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:dmarc-filter :delivered-to; bh=j1NLDYkRbuWIXzNb2zmpxuFjBYQWc3xeAMCclQeuYEg=; b=tZylU8A56C70MhCsNBUXo7bGudld21YWqLY/gJr49dtfkl6pT25hDWV9wKBCO7eBsm WJalHaEDKgXV2ZbgYSndlcBIRDco6pQdY+Jtp4wq2bUETLcQedPHuMjInVLIwnLrG381 gJxBhRD8Y6aOaKfNnKD+dR2b0bLYQYAvZ8WX9XIFgGm4p22mnVHku2ad53m8VoCRu7dl TlCwOarXnp+WheCZMrJxdF+SwH3fBCJBy3abMezSmwK1RSh74u5bkn/ywWgxasf/CsXF TS+sR/oJYlXYwbCF1VaO6AaFbRi6/jJXCoX7PWNwpuEozm7ga2catK3HZjWWkOu6ZCIf xXoQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@embecosm.com header.s=google header.b=Rp9oEUes; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id b2-20020a170906150200b009476f7e3d4csi1917418ejd.234.2023.04.05.07.48.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 07:48:29 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@embecosm.com header.s=google header.b=Rp9oEUes; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 86582395A00E for ; Wed, 5 Apr 2023 14:17:35 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by sourceware.org (Postfix) with ESMTPS id 0C9933855585 for ; Wed, 5 Apr 2023 14:06:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0C9933855585 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wm1-x32c.google.com with SMTP id v6-20020a05600c470600b003f034269c96so11822145wmo.4 for ; Wed, 05 Apr 2023 07:06:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1680703571; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=j1NLDYkRbuWIXzNb2zmpxuFjBYQWc3xeAMCclQeuYEg=; b=Rp9oEUesphhzfsdNh03JZdf5CvyaoYur6a5Y31HO3Qo85j/gEnravLPbm1KGjXQs+R YtgNg50hayoF0/4W2lQMRzyKZfXz90lVE6PgUATt8AAZefEJn1BNbDvHUQ3IxYCxJBi/ x2om2oFW1icwqywaLd7DECWcFDuPbVtMv3m41kRbpz/QprXEchDQlqNL5C0k6xau4MRf kmUeHTMI33fZgeNiM3Udqrx5Xd98tCwZVJJtHKX3+XyTVS7TETbUVkfUU4gqZrtxFSIt 8kt2pFVdapaMaKKlDR3np3EzP30ScXMqmi/Ik3iLhODVKy74BP8tWWbQDzyjr6lf1nhn sQZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680703571; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=j1NLDYkRbuWIXzNb2zmpxuFjBYQWc3xeAMCclQeuYEg=; b=0InbXEeqDfuiZXzRVH102RTJXIWmLP5/8S8fHDsJ5UZJK91SQQDXg8QrqIejpy+Yfs PKBsvgxuoeZUMV2LlQr9wPuX6CjSTWjOBebGqSS4Gl4eaGA4ZeDyCjq/x/R+bYlT8imN 4GvE2P+PCSVW4yUTJ10BN+Lj61k6aQdDCP9zzGZhcwxhMe777AdaejUze9gWaHg9cxRx LnUxzRgDGfQv7lycWJ5RubEYB4dX8b6d+QEoSZKajrAz6gSL/cLabfKX/O4fBxpTawFX YCCACh9mk63zqoQIwsDtP9AsTURsUNaLiD8zBBsRVDs/DWKGoA4C3llNaLGVNfV5GkEu 9zsA== X-Gm-Message-State: AAQBX9cvdVSwEuChPLvyG7A4HPY+HXFFKnee4+dUfof1wMaL/s+gesGI xGnxz55cYarSBiR2pTB35b+ZXLB24awqqHdZ8A== X-Received: by 2002:a7b:c4c6:0:b0:3eb:3945:d3fd with SMTP id g6-20020a7bc4c6000000b003eb3945d3fdmr4838365wmk.14.1680703571406; Wed, 05 Apr 2023 07:06:11 -0700 (PDT) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id ay8-20020a05600c1e0800b003edddae1068sm2330150wmb.9.2023.04.05.07.06.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 07:06:10 -0700 (PDT) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Pierre-Emmanuel Patry Subject: [committed 62/88] gccrs: typecheck: Refactor rust-hir-trait-reference.h Date: Wed, 5 Apr 2023 16:03:46 +0200 Message-Id: <20230405140411.3016563-63-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230405140411.3016563-1-arthur.cohen@embecosm.com> References: <20230405140411.3016563-1-arthur.cohen@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: arthur.cohen@embecosm.com Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762348089002670045?= X-GMAIL-MSGID: =?utf-8?q?1762348089002670045?= From: Pierre-Emmanuel Patry Move function body to their own cc file instead of keeping them in the header file. gcc/rust/ChangeLog: * Make-lang.in: Add `rust-hir-trait-reference.o`. * typecheck/rust-hir-trait-reference.h: Remove multiple function body. * typecheck/rust-hir-trait-reference.cc: Add multiple function body. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/Make-lang.in | 1 + .../typecheck/rust-hir-trait-reference.cc | 463 ++++++++++++++++++ gcc/rust/typecheck/rust-hir-trait-reference.h | 343 ++----------- 3 files changed, 510 insertions(+), 297 deletions(-) create mode 100644 gcc/rust/typecheck/rust-hir-trait-reference.cc diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index d9bc40945c3..09bbe450bd5 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -123,6 +123,7 @@ GRS_OBJS = \ rust/rust-tyty-bounds.o \ rust/rust-hir-type-check-util.o \ rust/rust-hir-trait-resolve.o \ + rust/rust-hir-trait-reference.o \ rust/rust-hir-type-check-item.o \ rust/rust-hir-type-check-type.o \ rust/rust-hir-type-check-struct.o \ diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.cc b/gcc/rust/typecheck/rust-hir-trait-reference.cc new file mode 100644 index 00000000000..651c55abc82 --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-trait-reference.cc @@ -0,0 +1,463 @@ +// Copyright (C) 2020-2022 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#include "rust-hir-trait-reference.h" + +namespace Rust { +namespace Resolver { + +std::string +TraitItemReference::as_string () const +{ + return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")"; +} + +bool +TraitItemReference::is_error () const +{ + return type == ERROR; +} + +bool +TraitItemReference::is_optional () const +{ + return optional_flag; +}; + +std::string +TraitItemReference::get_identifier () const +{ + return identifier; +} + +TraitItemReference::TraitItemType +TraitItemReference::get_trait_item_type () const +{ + return type; +} + +HIR::TraitItem * +TraitItemReference::get_hir_trait_item () const +{ + return hir_trait_item; +} + +Location +TraitItemReference::get_locus () const +{ + return locus; +} + +const Analysis::NodeMapping +TraitItemReference::get_mappings () const +{ + return hir_trait_item->get_mappings (); +} + +TyTy::BaseType * +TraitItemReference::get_tyty () const +{ + rust_assert (hir_trait_item != nullptr); + + switch (type) + { + case CONST: + return get_type_from_constant ( + static_cast (*hir_trait_item)); + break; + + case TYPE: + return get_type_from_typealias ( + static_cast (*hir_trait_item)); + + case FN: + return get_type_from_fn ( + static_cast (*hir_trait_item)); + break; + + default: + return get_error (); + } + + gcc_unreachable (); + return get_error (); +} + +TyTy::ErrorType * +TraitItemReference::get_error () const +{ + return new TyTy::ErrorType (get_mappings ().get_hirid ()); +} + +TraitReference::TraitReference ( + const HIR::Trait *hir_trait_ref, std::vector item_refs, + std::vector super_traits, + std::vector substs) + : hir_trait_ref (hir_trait_ref), item_refs (item_refs), + super_traits (super_traits) +{ + trait_substs.clear (); + trait_substs.reserve (substs.size ()); + for (const auto &p : substs) + trait_substs.push_back (p.clone ()); +} + +TraitReference::TraitReference (TraitReference const &other) + : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs), + super_traits (other.super_traits) +{ + trait_substs.clear (); + trait_substs.reserve (other.trait_substs.size ()); + for (const auto &p : other.trait_substs) + trait_substs.push_back (p.clone ()); +} + +TraitReference & +TraitReference::operator= (TraitReference const &other) +{ + hir_trait_ref = other.hir_trait_ref; + item_refs = other.item_refs; + super_traits = other.super_traits; + + trait_substs.clear (); + trait_substs.reserve (other.trait_substs.size ()); + for (const auto &p : other.trait_substs) + trait_substs.push_back (p.clone ()); + + return *this; +} + +bool +TraitReference::is_error () const +{ + return hir_trait_ref == nullptr; +} + +Location +TraitReference::get_locus () const +{ + return hir_trait_ref->get_locus (); +} + +std::string +TraitReference::get_name () const +{ + rust_assert (!is_error ()); + return hir_trait_ref->get_name (); +} + +std::string +TraitReference::as_string () const +{ + if (is_error ()) + return ""; + + std::string item_buf; + for (auto &item : item_refs) + { + item_buf += item.as_string () + ", "; + } + return "HIR Trait: " + get_name () + "->" + + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]"; +} + +const HIR::Trait * +TraitReference::get_hir_trait_ref () const +{ + return hir_trait_ref; +} + +const Analysis::NodeMapping & +TraitReference::get_mappings () const +{ + return hir_trait_ref->get_mappings (); +} + +DefId +TraitReference::get_defid () const +{ + return get_mappings ().get_defid (); +} + +bool +TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item, + TraitItemReference **ref) +{ + return lookup_trait_item (item.trait_identifier (), ref); +} + +bool +TraitReference::lookup_trait_item (const std::string &ident, + TraitItemReference **ref) +{ + for (auto &item : item_refs) + { + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_trait_item_by_type ( + const std::string &ident, TraitItemReference::TraitItemType type, + TraitItemReference **ref) +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_trait_item_by_type ( + const std::string &ident, TraitItemReference::TraitItemType type, + const TraitItemReference **ref) const +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item, + const TraitItemReference **ref) const +{ + return lookup_trait_item (item.trait_identifier (), ref); +} + +bool +TraitReference::lookup_trait_item (const std::string &ident, + const TraitItemReference **ref) const +{ + for (auto &item : item_refs) + { + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + bool found = super_trait->lookup_trait_item (ident, ref); + if (found) + return true; + } + + return false; +} + +const TraitItemReference * +TraitReference::lookup_trait_item (const std::string &ident, + TraitItemReference::TraitItemType type) const +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + return &item; + } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + const TraitItemReference *res + = super_trait->lookup_trait_item (ident, type); + if (!res->is_error ()) + return res; + } + + return &TraitItemReference::error_node (); +} + +size_t +TraitReference::size () const +{ + return item_refs.size (); +} + +const std::vector & +TraitReference::get_trait_items () const +{ + return item_refs; +} + +void +TraitReference::get_trait_items_and_supers ( + std::vector &result) const +{ + for (const auto &item : item_refs) + result.push_back (&item); + + for (const auto &super_trait : super_traits) + super_trait->get_trait_items_and_supers (result); +} + +void +TraitReference::on_resolved () +{ + for (auto &item : item_refs) + { + item.on_resolved (); + } +} + +void +TraitReference::clear_associated_types () +{ + for (auto &item : item_refs) + { + bool is_assoc_type = item.get_trait_item_type () + == TraitItemReference::TraitItemType::TYPE; + if (is_assoc_type) + item.associated_type_reset (); + } +} + +bool +TraitReference::is_equal (const TraitReference &other) const +{ + DefId this_id = get_mappings ().get_defid (); + DefId other_id = other.get_mappings ().get_defid (); + return this_id == other_id; +} + +const std::vector +TraitReference::get_super_traits () const +{ + return super_traits; +} + +bool +TraitReference::is_object_safe (bool emit_error, Location locus) const +{ + // https: // doc.rust-lang.org/reference/items/traits.html#object-safety + std::vector non_object_super_traits; + for (auto &item : super_traits) + { + if (!item->is_object_safe (false, Location ())) + non_object_super_traits.push_back (item); + } + + std::vector non_object_safe_items; + for (auto &item : get_trait_items ()) + { + if (!item.is_object_safe ()) + non_object_safe_items.push_back (&item); + } + + bool is_safe + = non_object_super_traits.empty () && non_object_safe_items.empty (); + if (emit_error && !is_safe) + { + RichLocation r (locus); + for (auto &item : non_object_super_traits) + r.add_range (item->get_locus ()); + for (auto &item : non_object_safe_items) + r.add_range (item->get_locus ()); + + rust_error_at (r, "trait bound is not object safe"); + } + + return is_safe; +} + +bool +TraitReference::trait_has_generics () const +{ + return !trait_substs.empty (); +} + +std::vector +TraitReference::get_trait_substs () const +{ + return trait_substs; +} + +bool +TraitReference::satisfies_bound (const TraitReference &reference) const +{ + if (is_equal (reference)) + return true; + + for (const auto &super_trait : super_traits) + { + if (super_trait->satisfies_bound (reference)) + return true; + } + + return false; +} + +AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait, + HIR::ImplBlock *impl, + TyTy::BaseType *self, + Resolver::TypeCheckContext *context) + : trait (trait), impl (impl), self (self), context (context) +{} + +TraitReference * +AssociatedImplTrait::get_trait () +{ + return trait; +} + +HIR::ImplBlock * +AssociatedImplTrait::get_impl_block () +{ + return impl; +} + +TyTy::BaseType * +AssociatedImplTrait::get_self () +{ + return self; +} +const TyTy::BaseType * +AssociatedImplTrait::get_self () const +{ + return self; +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h index adb63b468d1..f3703efcced 100644 --- a/gcc/rust/typecheck/rust-hir-trait-reference.h +++ b/gcc/rust/typecheck/rust-hir-trait-reference.h @@ -20,8 +20,8 @@ #define RUST_HIR_TRAIT_REF_H #include "rust-hir-full.h" -#include "rust-tyty-visitor.h" #include "rust-hir-type-check-util.h" +#include "rust-tyty-visitor.h" namespace Rust { namespace Resolver { @@ -61,13 +61,9 @@ public: return error; } - bool is_error () const { return type == ERROR; } + bool is_error () const; - std::string as_string () const - { - return "(" + trait_item_type_as_string (type) + " " + identifier + " " - + ")"; - } + std::string as_string () const; static std::string trait_item_type_as_string (TraitItemType ty) { @@ -85,53 +81,24 @@ public: return "ERROR"; } - bool is_optional () const { return optional_flag; } - - std::string get_identifier () const { return identifier; } - - TraitItemType get_trait_item_type () const { return type; } - - HIR::TraitItem *get_hir_trait_item () const { return hir_trait_item; } + bool is_optional () const; - Location get_locus () const { return locus; } + std::string get_identifier () const; - const Analysis::NodeMapping get_mappings () const - { - return hir_trait_item->get_mappings (); - } + TraitItemType get_trait_item_type () const; - TyTy::BaseType *get_tyty () const - { - rust_assert (hir_trait_item != nullptr); + HIR::TraitItem *get_hir_trait_item () const; - switch (type) - { - case CONST: - return get_type_from_constant ( - static_cast (*hir_trait_item)); - break; + Location get_locus () const; - case TYPE: - return get_type_from_typealias ( - static_cast (*hir_trait_item)); + const Analysis::NodeMapping get_mappings () const; - case FN: - return get_type_from_fn ( - static_cast (*hir_trait_item)); - break; - - default: - return get_error (); - } - - gcc_unreachable (); - return get_error (); - } + TyTy::BaseType *get_tyty () const; Analysis::NodeMapping get_parent_trait_mappings () const; - // this is called when the trait is completed resolution and gives the items a - // chance to run their specific type resolution passes. If we call their + // this is called when the trait is completed resolution and gives the items + // a chance to run their specific type resolution passes. If we call their // resolution on construction it can lead to a case where the trait being // resolved recursively trying to resolve the trait itself infinitely since // the trait will not be stored in its own map yet @@ -144,10 +111,7 @@ public: bool is_object_safe () const; private: - TyTy::ErrorType *get_error () const - { - return new TyTy::ErrorType (get_mappings ().get_hirid ()); - } + TyTy::ErrorType *get_error () const; TyTy::BaseType *get_type_from_typealias (/*const*/ HIR::TraitItemType &type) const; @@ -182,39 +146,11 @@ public: TraitReference (const HIR::Trait *hir_trait_ref, std::vector item_refs, std::vector super_traits, - std::vector substs) - : hir_trait_ref (hir_trait_ref), item_refs (item_refs), - super_traits (super_traits) - { - trait_substs.clear (); - trait_substs.reserve (substs.size ()); - for (const auto &p : substs) - trait_substs.push_back (p.clone ()); - } - - TraitReference (TraitReference const &other) - : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs), - super_traits (other.super_traits) - { - trait_substs.clear (); - trait_substs.reserve (other.trait_substs.size ()); - for (const auto &p : other.trait_substs) - trait_substs.push_back (p.clone ()); - } - - TraitReference &operator= (TraitReference const &other) - { - hir_trait_ref = other.hir_trait_ref; - item_refs = other.item_refs; - super_traits = other.super_traits; + std::vector substs); - trait_substs.clear (); - trait_substs.reserve (other.trait_substs.size ()); - for (const auto &p : other.trait_substs) - trait_substs.push_back (p.clone ()); + TraitReference (TraitReference const &other); - return *this; - } + TraitReference &operator= (TraitReference const &other); TraitReference (TraitReference &&other) = default; TraitReference &operator= (TraitReference &&other) = default; @@ -224,7 +160,7 @@ public: return TraitReference (nullptr, {}, {}, {}); } - bool is_error () const { return hir_trait_ref == nullptr; } + bool is_error () const; static TraitReference &error_node () { @@ -232,248 +168,63 @@ public: return trait_error_node; } - Location get_locus () const { return hir_trait_ref->get_locus (); } + Location get_locus () const; - std::string get_name () const - { - rust_assert (!is_error ()); - return hir_trait_ref->get_name (); - } + std::string get_name () const; - std::string as_string () const - { - if (is_error ()) - return ""; - - std::string item_buf; - for (auto &item : item_refs) - { - item_buf += item.as_string () + ", "; - } - return "HIR Trait: " + get_name () + "->" - + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf - + "]"; - } + std::string as_string () const; - const HIR::Trait *get_hir_trait_ref () const { return hir_trait_ref; } + const HIR::Trait *get_hir_trait_ref () const; - const Analysis::NodeMapping &get_mappings () const - { - return hir_trait_ref->get_mappings (); - } + const Analysis::NodeMapping &get_mappings () const; - DefId get_defid () const { return get_mappings ().get_defid (); } + DefId get_defid () const; bool lookup_hir_trait_item (const HIR::TraitItem &item, - TraitItemReference **ref) - { - return lookup_trait_item (item.trait_identifier (), ref); - } + TraitItemReference **ref); - bool lookup_trait_item (const std::string &ident, TraitItemReference **ref) - { - for (auto &item : item_refs) - { - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + bool lookup_trait_item (const std::string &ident, TraitItemReference **ref); bool lookup_trait_item_by_type (const std::string &ident, TraitItemReference::TraitItemType type, - TraitItemReference **ref) - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; - - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + TraitItemReference **ref); bool lookup_trait_item_by_type (const std::string &ident, TraitItemReference::TraitItemType type, - const TraitItemReference **ref) const - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; - - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + const TraitItemReference **ref) const; bool lookup_hir_trait_item (const HIR::TraitItem &item, - const TraitItemReference **ref) const - { - return lookup_trait_item (item.trait_identifier (), ref); - } + const TraitItemReference **ref) const; bool lookup_trait_item (const std::string &ident, - const TraitItemReference **ref) const - { - for (auto &item : item_refs) - { - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - - // lookup super traits - for (const auto &super_trait : super_traits) - { - bool found = super_trait->lookup_trait_item (ident, ref); - if (found) - return true; - } - - return false; - } + const TraitItemReference **ref) const; const TraitItemReference * lookup_trait_item (const std::string &ident, - TraitItemReference::TraitItemType type) const - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; + TraitItemReference::TraitItemType type) const; - if (ident.compare (item.get_identifier ()) == 0) - return &item; - } + size_t size () const; - // lookup super traits - for (const auto &super_trait : super_traits) - { - const TraitItemReference *res - = super_trait->lookup_trait_item (ident, type); - if (!res->is_error ()) - return res; - } - - return &TraitItemReference::error_node (); - } - - size_t size () const { return item_refs.size (); } - - const std::vector &get_trait_items () const - { - return item_refs; - } + const std::vector &get_trait_items () const; void get_trait_items_and_supers ( - std::vector &result) const - { - for (const auto &item : item_refs) - result.push_back (&item); - - for (const auto &super_trait : super_traits) - super_trait->get_trait_items_and_supers (result); - } - - void on_resolved () - { - for (auto &item : item_refs) - { - item.on_resolved (); - } - } - - void clear_associated_types () - { - for (auto &item : item_refs) - { - bool is_assoc_type = item.get_trait_item_type () - == TraitItemReference::TraitItemType::TYPE; - if (is_assoc_type) - item.associated_type_reset (); - } - } - - bool is_equal (const TraitReference &other) const - { - DefId this_id = get_mappings ().get_defid (); - DefId other_id = other.get_mappings ().get_defid (); - return this_id == other_id; - } - - const std::vector get_super_traits () const - { - return super_traits; - } - - bool is_object_safe (bool emit_error, Location locus) const - { - // https: // doc.rust-lang.org/reference/items/traits.html#object-safety - std::vector non_object_super_traits; - for (auto &item : super_traits) - { - if (!item->is_object_safe (false, Location ())) - non_object_super_traits.push_back (item); - } + std::vector &result) const; - std::vector non_object_safe_items; - for (auto &item : get_trait_items ()) - { - if (!item.is_object_safe ()) - non_object_safe_items.push_back (&item); - } + void on_resolved (); - bool is_safe - = non_object_super_traits.empty () && non_object_safe_items.empty (); - if (emit_error && !is_safe) - { - RichLocation r (locus); - for (auto &item : non_object_super_traits) - r.add_range (item->get_locus ()); - for (auto &item : non_object_safe_items) - r.add_range (item->get_locus ()); + void clear_associated_types (); - rust_error_at (r, "trait bound is not object safe"); - } + bool is_equal (const TraitReference &other) const; - return is_safe; - } + const std::vector get_super_traits () const; - bool trait_has_generics () const { return !trait_substs.empty (); } + bool is_object_safe (bool emit_error, Location locus) const; - std::vector get_trait_substs () const - { - return trait_substs; - } - - bool satisfies_bound (const TraitReference &reference) const - { - if (is_equal (reference)) - return true; + bool trait_has_generics () const; - for (const auto &super_trait : super_traits) - { - if (super_trait->satisfies_bound (reference)) - return true; - } + std::vector get_trait_substs () const; - return false; - } + bool satisfies_bound (const TraitReference &reference) const; private: const HIR::Trait *hir_trait_ref; @@ -487,16 +238,14 @@ class AssociatedImplTrait public: AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl, TyTy::BaseType *self, - Resolver::TypeCheckContext *context) - : trait (trait), impl (impl), self (self), context (context) - {} + Resolver::TypeCheckContext *context); - TraitReference *get_trait () { return trait; } + TraitReference *get_trait (); - HIR::ImplBlock *get_impl_block () { return impl; } + HIR::ImplBlock *get_impl_block (); - TyTy::BaseType *get_self () { return self; } - const TyTy::BaseType *get_self () const { return self; } + TyTy::BaseType *get_self (); + const TyTy::BaseType *get_self () const; TyTy::BaseType * setup_associated_types (const TyTy::BaseType *self,