From patchwork Wed Apr 5 14:03:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 67349 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A0D07397B5E6 for ; Wed, 5 Apr 2023 14:13:32 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by sourceware.org (Postfix) with ESMTPS id 3B93F3851405 for ; Wed, 5 Apr 2023 14:05:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3B93F3851405 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-x334.google.com with SMTP id d11-20020a05600c3acb00b003ef6e6754c5so18371797wms.5 for ; Wed, 05 Apr 2023 07:05:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1680703557; 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=fMKpeeyj8e5rheVnzAGU55AINUOYg+UQsYb2D/lPNEY=; b=LUuFiOVmJJ1ptQfPMd3tAF+ZaKeYl0PGhh+zTjvYAqx5rqOEzhrE7EHBihXDY7KjrO WfYAOiiRazXQULvF7FrreHhiQkKQO1C57e/iVM2uoRFyn9EY7Jo0neH9Q8vuXc9s2ZOQ bV0cuIBkgMBfUjfS2ViJnZqbRTuVlZniFhCM+Zax3F/MiiUfBN9oW41p23POWWL9SoMD zocvzUHveRn+qtv3bNMl0j1rVK4+FIvbiY04f3BhnU17GnwBzS/uBhdQH/Z42RzVcYhh Xq1Jb214TZq2SJUKdYY50hRUh+GSl7ao0J2wXutbOsE9MpVu7V6vHTqsoSoenGKooCEY XWjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680703557; 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=fMKpeeyj8e5rheVnzAGU55AINUOYg+UQsYb2D/lPNEY=; b=P5Z5Cror4YyztmXHhqnUUZzeEawd+JlyFI6q/e3gTWXw477Rbr5TRANTMwihG+9SGi fvxoVdaevnH8fQfmZ/uZYBM7sxHZzKFgbKVNJHxIXQXH7rZOa3+pZF5/RhBK8rLBVpIR /lDDPUQiOD9jzdET0S0rcVVIqu+ZFgFtkdoerFbdw7gP6guNH3seYCBiAcyguPq7okbZ Pt2aDS4bJ7y9D8/sGFhoNQopp67Hxc7sob2Cg7RNhrM77ie4WANpo/NOo9xgIkIeGNup gkgVoJVOc4Ffz7+BG7ybr8CUabqV2RJnuD+rmVkaZdtJlhhHh1OqzjBJrCvKn3wfeGeM xI2A== X-Gm-Message-State: AAQBX9cMB5fSslUTcJQEq28eOn7EmLcnpeiWUytYfYo1oNi1HBF189Fs /bBE5h68RS2pltM4pQZT4sJ+ym8/PbdgjYhuUg== X-Google-Smtp-Source: AKy350aAdJ0gheT3Vmp/c7pfxGp7wWfruJZy7m2yTNX5qTJi/Y3xMwW5yz9VHwS5dw85CQUtw/C5sQ== X-Received: by 2002:a05:600c:2c46:b0:3ef:d386:1a3b with SMTP id r6-20020a05600c2c4600b003efd3861a3bmr5187468wmg.34.1680703557453; Wed, 05 Apr 2023 07:05:57 -0700 (PDT) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id ay8-20020a05600c1e0800b003edddae1068sm2330150wmb.9.2023.04.05.07.05.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 07:05:57 -0700 (PDT) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron Subject: [committed 41/88] gccrs: Refactor PathProbe into cc file Date: Wed, 5 Apr 2023 16:03:25 +0200 Message-Id: <20230405140411.3016563-42-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, 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Philip Herron Signed-off-by: Philip Herron gcc/rust/ChangeLog: * typecheck/rust-hir-path-probe.cc (PathProbeType::PathProbeType): refactor (PathProbeType::Probe): likewise (PathProbeType::visit): likewise (PathProbeType::process_enum_item_for_candiates): likewise (PathProbeType::process_impl_items_for_candidates): likewise (PathProbeType::is_reciever_generic): likewise (PathProbeImplTrait::PathProbeImplTrait): likewise (PathProbeImplTrait::Probe): likewise (PathProbeImplTrait::process_trait_impl_items_for_candidates): likewise * typecheck/rust-hir-path-probe.h (struct PathProbeCandidate): likewise * typecheck/rust-hir-trait-resolve.cc (PathProbeImplTrait::process_trait_impl_items_for_candidates): likewise --- gcc/rust/typecheck/rust-hir-path-probe.cc | 344 +++++++++++++++++++ gcc/rust/typecheck/rust-hir-path-probe.h | 302 +--------------- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 22 -- 3 files changed, 360 insertions(+), 308 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc index cb3270d3623..06d8920d2eb 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.cc +++ b/gcc/rust/typecheck/rust-hir-path-probe.cc @@ -18,10 +18,168 @@ #include "rust-hir-path-probe.h" #include "rust-hir-type-check-item.h" +#include "rust-hir-trait-resolve.h" namespace Rust { namespace Resolver { +// PathProbeType + +PathProbeType::PathProbeType (const TyTy::BaseType *receiver, + const HIR::PathIdentSegment &query, + DefId specific_trait_id) + : TypeCheckBase (), receiver (receiver), search (query), + current_impl (nullptr), specific_trait_id (specific_trait_id) +{} + +std::set +PathProbeType::Probe (const TyTy::BaseType *receiver, + const HIR::PathIdentSegment &segment_name, + bool probe_impls, bool probe_bounds, + bool ignore_mandatory_trait_items, + DefId specific_trait_id) +{ + PathProbeType probe (receiver, segment_name, specific_trait_id); + if (probe_impls) + { + if (receiver->get_kind () == TyTy::TypeKind::ADT) + { + const TyTy::ADTType *adt + = static_cast (receiver); + if (adt->is_enum ()) + probe.process_enum_item_for_candiates (adt); + } + + probe.process_impl_items_for_candidates (); + } + + if (!probe_bounds) + return probe.candidates; + + if (!probe.is_reciever_generic ()) + { + std::vector> probed_bounds + = TypeBoundsProbe::Probe (receiver); + for (auto &candidate : probed_bounds) + { + const TraitReference *trait_ref = candidate.first; + if (specific_trait_id != UNKNOWN_DEFID) + { + if (trait_ref->get_mappings ().get_defid () != specific_trait_id) + continue; + } + + HIR::ImplBlock *impl = candidate.second; + probe.process_associated_trait_for_candidates ( + trait_ref, impl, ignore_mandatory_trait_items); + } + } + + for (const TyTy::TypeBoundPredicate &predicate : + receiver->get_specified_bounds ()) + { + const TraitReference *trait_ref = predicate.get (); + if (specific_trait_id != UNKNOWN_DEFID) + { + if (trait_ref->get_mappings ().get_defid () != specific_trait_id) + continue; + } + + probe.process_predicate_for_candidates (predicate, + ignore_mandatory_trait_items); + } + + return probe.candidates; +} + +void +PathProbeType::visit (HIR::TypeAlias &alias) +{ + Identifier name = alias.get_new_type_name (); + if (search.as_string ().compare (name) == 0) + { + HirId tyid = alias.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + bool ok = query_type (tyid, &ty); + rust_assert (ok); + + PathProbeCandidate::ImplItemCandidate impl_item_candidate{&alias, + current_impl}; + PathProbeCandidate candidate{ + PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS, ty, + alias.get_locus (), impl_item_candidate}; + candidates.insert (std::move (candidate)); + } +} + +void +PathProbeType::visit (HIR::ConstantItem &constant) +{ + Identifier name = constant.get_identifier (); + if (search.as_string ().compare (name) == 0) + { + HirId tyid = constant.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + bool ok = query_type (tyid, &ty); + rust_assert (ok); + + PathProbeCandidate::ImplItemCandidate impl_item_candidate{&constant, + current_impl}; + PathProbeCandidate candidate{ + PathProbeCandidate::CandidateType::IMPL_CONST, ty, + constant.get_locus (), impl_item_candidate}; + candidates.insert (std::move (candidate)); + } +} + +void +PathProbeType::visit (HIR::Function &function) +{ + Identifier name = function.get_function_name (); + if (search.as_string ().compare (name) == 0) + { + HirId tyid = function.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + bool ok = query_type (tyid, &ty); + rust_assert (ok); + + PathProbeCandidate::ImplItemCandidate impl_item_candidate{&function, + current_impl}; + PathProbeCandidate candidate{PathProbeCandidate::CandidateType::IMPL_FUNC, + ty, function.get_locus (), + impl_item_candidate}; + candidates.insert (std::move (candidate)); + } +} + +void +PathProbeType::process_enum_item_for_candiates (const TyTy::ADTType *adt) +{ + if (specific_trait_id != UNKNOWN_DEFID) + return; + + TyTy::VariantDef *v; + if (!adt->lookup_variant (search.as_string (), &v)) + return; + + PathProbeCandidate::EnumItemCandidate enum_item_candidate{adt, v}; + PathProbeCandidate candidate{PathProbeCandidate::CandidateType::ENUM_VARIANT, + receiver->clone (), + mappings->lookup_location (adt->get_ty_ref ()), + enum_item_candidate}; + candidates.insert (std::move (candidate)); +} + +void +PathProbeType::process_impl_items_for_candidates () +{ + mappings->iterate_impl_items ( + [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool { + process_impl_item_candidate (id, item, impl); + return true; + }); +} + void PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) @@ -42,5 +200,191 @@ PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item, item->accept_vis (*this); } +void +PathProbeType::process_associated_trait_for_candidates ( + const TraitReference *trait_ref, HIR::ImplBlock *impl, + bool ignore_mandatory_trait_items) +{ + const TraitItemReference *trait_item_ref = nullptr; + if (!trait_ref->lookup_trait_item (search.as_string (), &trait_item_ref)) + return; + + bool trait_item_needs_implementation = !trait_item_ref->is_optional (); + if (ignore_mandatory_trait_items && trait_item_needs_implementation) + return; + + PathProbeCandidate::CandidateType candidate_type; + switch (trait_item_ref->get_trait_item_type ()) + { + case TraitItemReference::TraitItemType::FN: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC; + break; + case TraitItemReference::TraitItemType::CONST: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST; + break; + case TraitItemReference::TraitItemType::TYPE: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS; + break; + + case TraitItemReference::TraitItemType::ERROR: + default: + gcc_unreachable (); + break; + } + + TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty (); + + // we can substitute the Self with the receiver here + if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) + { + TyTy::FnType *fn = static_cast (trait_item_tyty); + TyTy::SubstitutionParamMapping *param = nullptr; + for (auto ¶m_mapping : fn->get_substs ()) + { + const HIR::TypeParam &type_param = param_mapping.get_generic_param (); + if (type_param.get_type_representation ().compare ("Self") == 0) + { + param = ¶m_mapping; + break; + } + } + rust_assert (param != nullptr); + + std::vector mappings; + mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ())); + + Location locus; // FIXME + TyTy::SubstitutionArgumentMappings args (std::move (mappings), {}, locus); + trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args); + } + + PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref, + trait_item_ref, + impl}; + + PathProbeCandidate candidate{candidate_type, trait_item_tyty, + trait_item_ref->get_locus (), + trait_item_candidate}; + candidates.insert (std::move (candidate)); +} + +void +PathProbeType::process_predicate_for_candidates ( + const TyTy::TypeBoundPredicate &predicate, bool ignore_mandatory_trait_items) +{ + const TraitReference *trait_ref = predicate.get (); + + TyTy::TypeBoundPredicateItem item + = predicate.lookup_associated_item (search.as_string ()); + if (item.is_error ()) + return; + + if (ignore_mandatory_trait_items && item.needs_implementation ()) + return; + + const TraitItemReference *trait_item_ref = item.get_raw_item (); + PathProbeCandidate::CandidateType candidate_type; + switch (trait_item_ref->get_trait_item_type ()) + { + case TraitItemReference::TraitItemType::FN: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC; + break; + case TraitItemReference::TraitItemType::CONST: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST; + break; + case TraitItemReference::TraitItemType::TYPE: + candidate_type = PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS; + break; + + case TraitItemReference::TraitItemType::ERROR: + default: + gcc_unreachable (); + break; + } + + TyTy::BaseType *trait_item_tyty = item.get_tyty_for_receiver (receiver); + PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref, + trait_item_ref, + nullptr}; + PathProbeCandidate candidate{candidate_type, trait_item_tyty, + trait_item_ref->get_locus (), + trait_item_candidate}; + candidates.insert (std::move (candidate)); +} + +std::vector> +PathProbeType::union_bounds ( + const std::vector> a, + const std::vector> b) + const +{ + std::map> mapper; + for (auto &ref : a) + { + mapper.insert ({ref.first->get_mappings ().get_defid (), ref}); + } + for (auto &ref : b) + { + mapper.insert ({ref.first->get_mappings ().get_defid (), ref}); + } + + std::vector> union_set; + for (auto it = mapper.begin (); it != mapper.end (); it++) + { + union_set.push_back ({it->second.first, it->second.second}); + } + return union_set; +} + +bool +PathProbeType::is_reciever_generic () const +{ + const TyTy::BaseType *root = receiver->get_root (); + bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM; + bool receiver_is_dyn = root->get_kind () == TyTy::TypeKind::DYNAMIC; + return receiver_is_type_param || receiver_is_dyn; +} + +// PathProbImplTrait + +PathProbeImplTrait::PathProbeImplTrait (const TyTy::BaseType *receiver, + const HIR::PathIdentSegment &query, + const TraitReference *trait_reference) + : PathProbeType (receiver, query, UNKNOWN_DEFID), + trait_reference (trait_reference) +{} + +std::set +PathProbeImplTrait::Probe (const TyTy::BaseType *receiver, + const HIR::PathIdentSegment &segment_name, + const TraitReference *trait_reference) +{ + PathProbeImplTrait probe (receiver, segment_name, trait_reference); + // iterate all impls for this trait and receiver + // then search for possible candidates using base class behaviours + probe.process_trait_impl_items_for_candidates (); + return probe.candidates; +} + +void +PathProbeImplTrait::process_trait_impl_items_for_candidates () +{ + mappings->iterate_impl_items ( + [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool { + // just need to check if this is an impl block for this trait the next + // function checks the receiver + if (!impl->has_trait_ref ()) + return true; + + TraitReference *resolved + = TraitResolver::Lookup (*(impl->get_trait_ref ().get ())); + if (!trait_reference->is_equal (*resolved)) + return true; + + process_impl_item_candidate (id, item, impl); + return true; + }); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index bb8698ce0e1..783282a0dc9 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -152,7 +152,7 @@ struct PathProbeCandidate return UNKNOWN_DEFID; } - bool operator< (const PathProbeCandidate &c) const + bool operator<(const PathProbeCandidate &c) const { return get_defid () < c.get_defid (); } @@ -165,144 +165,16 @@ public: Probe (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name, bool probe_impls, bool probe_bounds, bool ignore_mandatory_trait_items, - DefId specific_trait_id = UNKNOWN_DEFID) - { - PathProbeType probe (receiver, segment_name, specific_trait_id); - if (probe_impls) - { - if (receiver->get_kind () == TyTy::TypeKind::ADT) - { - const TyTy::ADTType *adt - = static_cast (receiver); - if (adt->is_enum ()) - probe.process_enum_item_for_candiates (adt); - } - - probe.process_impl_items_for_candidates (); - } + DefId specific_trait_id = UNKNOWN_DEFID); - if (!probe_bounds) - return probe.candidates; - - if (!probe.is_reciever_generic ()) - { - std::vector> probed_bounds - = TypeBoundsProbe::Probe (receiver); - for (auto &candidate : probed_bounds) - { - const TraitReference *trait_ref = candidate.first; - if (specific_trait_id != UNKNOWN_DEFID) - { - if (trait_ref->get_mappings ().get_defid () - != specific_trait_id) - continue; - } - - HIR::ImplBlock *impl = candidate.second; - probe.process_associated_trait_for_candidates ( - trait_ref, impl, ignore_mandatory_trait_items); - } - } - - for (const TyTy::TypeBoundPredicate &predicate : - receiver->get_specified_bounds ()) - { - const TraitReference *trait_ref = predicate.get (); - if (specific_trait_id != UNKNOWN_DEFID) - { - if (trait_ref->get_mappings ().get_defid () != specific_trait_id) - continue; - } - - probe.process_predicate_for_candidates (predicate, - ignore_mandatory_trait_items); - } - - return probe.candidates; - } - - void visit (HIR::TypeAlias &alias) override - { - Identifier name = alias.get_new_type_name (); - if (search.as_string ().compare (name) == 0) - { - HirId tyid = alias.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - bool ok = query_type (tyid, &ty); - rust_assert (ok); - - PathProbeCandidate::ImplItemCandidate impl_item_candidate{&alias, - current_impl}; - PathProbeCandidate candidate{ - PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS, ty, - alias.get_locus (), impl_item_candidate}; - candidates.insert (std::move (candidate)); - } - } - - void visit (HIR::ConstantItem &constant) override - { - Identifier name = constant.get_identifier (); - if (search.as_string ().compare (name) == 0) - { - HirId tyid = constant.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - bool ok = query_type (tyid, &ty); - rust_assert (ok); - - PathProbeCandidate::ImplItemCandidate impl_item_candidate{&constant, - current_impl}; - PathProbeCandidate candidate{ - PathProbeCandidate::CandidateType::IMPL_CONST, ty, - constant.get_locus (), impl_item_candidate}; - candidates.insert (std::move (candidate)); - } - } - - void visit (HIR::Function &function) override - { - Identifier name = function.get_function_name (); - if (search.as_string ().compare (name) == 0) - { - HirId tyid = function.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - bool ok = query_type (tyid, &ty); - rust_assert (ok); - - PathProbeCandidate::ImplItemCandidate impl_item_candidate{&function, - current_impl}; - PathProbeCandidate candidate{ - PathProbeCandidate::CandidateType::IMPL_FUNC, ty, - function.get_locus (), impl_item_candidate}; - candidates.insert (std::move (candidate)); - } - } + void visit (HIR::TypeAlias &alias) override; + void visit (HIR::ConstantItem &constant) override; + void visit (HIR::Function &function) override; protected: - void process_enum_item_for_candiates (const TyTy::ADTType *adt) - { - if (specific_trait_id != UNKNOWN_DEFID) - return; - - TyTy::VariantDef *v; - if (!adt->lookup_variant (search.as_string (), &v)) - return; - - PathProbeCandidate::EnumItemCandidate enum_item_candidate{adt, v}; - PathProbeCandidate candidate{ - PathProbeCandidate::CandidateType::ENUM_VARIANT, receiver->clone (), - mappings->lookup_location (adt->get_ty_ref ()), enum_item_candidate}; - candidates.insert (std::move (candidate)); - } + void process_enum_item_for_candiates (const TyTy::ADTType *adt); - void process_impl_items_for_candidates () - { - mappings->iterate_impl_items ([&] (HirId id, HIR::ImplItem *item, - HIR::ImplBlock *impl) mutable -> bool { - process_impl_item_candidate (id, item, impl); - return true; - }); - } + void process_impl_items_for_candidates (); void process_impl_item_candidate (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl); @@ -310,156 +182,24 @@ protected: void process_associated_trait_for_candidates (const TraitReference *trait_ref, HIR::ImplBlock *impl, - bool ignore_mandatory_trait_items) - { - const TraitItemReference *trait_item_ref = nullptr; - if (!trait_ref->lookup_trait_item (search.as_string (), &trait_item_ref)) - return; - - bool trait_item_needs_implementation = !trait_item_ref->is_optional (); - if (ignore_mandatory_trait_items && trait_item_needs_implementation) - return; - - PathProbeCandidate::CandidateType candidate_type; - switch (trait_item_ref->get_trait_item_type ()) - { - case TraitItemReference::TraitItemType::FN: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC; - break; - case TraitItemReference::TraitItemType::CONST: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST; - break; - case TraitItemReference::TraitItemType::TYPE: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS; - break; - - case TraitItemReference::TraitItemType::ERROR: - default: - gcc_unreachable (); - break; - } - - TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty (); - - // we can substitute the Self with the receiver here - if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) - { - TyTy::FnType *fn = static_cast (trait_item_tyty); - TyTy::SubstitutionParamMapping *param = nullptr; - for (auto ¶m_mapping : fn->get_substs ()) - { - const HIR::TypeParam &type_param - = param_mapping.get_generic_param (); - if (type_param.get_type_representation ().compare ("Self") == 0) - { - param = ¶m_mapping; - break; - } - } - rust_assert (param != nullptr); - - std::vector mappings; - mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ())); - - Location locus; // FIXME - TyTy::SubstitutionArgumentMappings args (std::move (mappings), {}, - locus); - trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args); - } - - PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref, - trait_item_ref, - impl}; - - PathProbeCandidate candidate{candidate_type, trait_item_tyty, - trait_item_ref->get_locus (), - trait_item_candidate}; - candidates.insert (std::move (candidate)); - } + bool ignore_mandatory_trait_items); void process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate, - bool ignore_mandatory_trait_items) - { - const TraitReference *trait_ref = predicate.get (); - - TyTy::TypeBoundPredicateItem item - = predicate.lookup_associated_item (search.as_string ()); - if (item.is_error ()) - return; - - if (ignore_mandatory_trait_items && item.needs_implementation ()) - return; - - const TraitItemReference *trait_item_ref = item.get_raw_item (); - PathProbeCandidate::CandidateType candidate_type; - switch (trait_item_ref->get_trait_item_type ()) - { - case TraitItemReference::TraitItemType::FN: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC; - break; - case TraitItemReference::TraitItemType::CONST: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST; - break; - case TraitItemReference::TraitItemType::TYPE: - candidate_type = PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS; - break; - - case TraitItemReference::TraitItemType::ERROR: - default: - gcc_unreachable (); - break; - } - - TyTy::BaseType *trait_item_tyty = item.get_tyty_for_receiver (receiver); - PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref, - trait_item_ref, - nullptr}; - PathProbeCandidate candidate{candidate_type, trait_item_tyty, - trait_item_ref->get_locus (), - trait_item_candidate}; - candidates.insert (std::move (candidate)); - } + bool ignore_mandatory_trait_items); protected: PathProbeType (const TyTy::BaseType *receiver, - const HIR::PathIdentSegment &query, DefId specific_trait_id) - : TypeCheckBase (), receiver (receiver), search (query), - current_impl (nullptr), specific_trait_id (specific_trait_id) - {} + const HIR::PathIdentSegment &query, DefId specific_trait_id); std::vector> union_bounds ( const std::vector> a, const std::vector> b) - const - { - std::map> mapper; - for (auto &ref : a) - { - mapper.insert ({ref.first->get_mappings ().get_defid (), ref}); - } - for (auto &ref : b) - { - mapper.insert ({ref.first->get_mappings ().get_defid (), ref}); - } - - std::vector> union_set; - for (auto it = mapper.begin (); it != mapper.end (); it++) - { - union_set.push_back ({it->second.first, it->second.second}); - } - return union_set; - } + const; - bool is_reciever_generic () const - { - const TyTy::BaseType *root = receiver->get_root (); - bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM; - bool receiver_is_dyn = root->get_kind () == TyTy::TypeKind::DYNAMIC; - return receiver_is_type_param || receiver_is_dyn; - } + bool is_reciever_generic () const; const TyTy::BaseType *receiver; const HIR::PathIdentSegment &search; @@ -489,24 +229,14 @@ public: static std::set Probe (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name, - const TraitReference *trait_reference) - { - PathProbeImplTrait probe (receiver, segment_name, trait_reference); - // iterate all impls for this trait and receiver - // then search for possible candidates using base class behaviours - probe.process_trait_impl_items_for_candidates (); - return probe.candidates; - } + const TraitReference *trait_reference); private: - void process_trait_impl_items_for_candidates (); - PathProbeImplTrait (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &query, - const TraitReference *trait_reference) - : PathProbeType (receiver, query, UNKNOWN_DEFID), - trait_reference (trait_reference) - {} + const TraitReference *trait_reference); + + void process_trait_impl_items_for_candidates (); const TraitReference *trait_reference; }; diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 85cad8e9c21..19f95ca4488 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -594,27 +594,5 @@ TraitItemReference::is_object_safe () const return false; } -// rust-hir-path-probe.h - -void -PathProbeImplTrait::process_trait_impl_items_for_candidates () -{ - mappings->iterate_impl_items ( - [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool { - // just need to check if this is an impl block for this trait the next - // function checks the receiver - if (!impl->has_trait_ref ()) - return true; - - TraitReference *resolved - = TraitResolver::Lookup (*(impl->get_trait_ref ().get ())); - if (!trait_reference->is_equal (*resolved)) - return true; - - process_impl_item_candidate (id, item, impl); - return true; - }); -} - } // namespace Resolver } // namespace Rust