https://gcc.gnu.org/g:accc27eef36899c116fa82c0c456fa8c15373e06
commit r17-4302-gaccc27eef36899c116fa82c0c456fa8c15373e06 Author: Philip Herron <[email protected]> Date: Fri Aug 28 17:52:32 2026 +0100 gccrs: Refactor PathProbeType into its own file and call it PathProbeExpr gcc/rust/ChangeLog: * Make-lang.in: new object * 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::process_impl_item_candidate): likewise (PathProbeType::is_receiver_generic): likewise * typecheck/rust-hir-path-probe.h (class PathProbeType): likewise * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): likewise * typecheck/rust-hir-path-probe-expr.cc: New file. * typecheck/rust-hir-path-probe-expr.h: New file. Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/Make-lang.in | 1 + gcc/rust/typecheck/rust-hir-path-probe-expr.cc | 364 +++++++++++++++++++++++++ gcc/rust/typecheck/rust-hir-path-probe-expr.h | 79 ++++++ gcc/rust/typecheck/rust-hir-path-probe.cc | 336 ----------------------- gcc/rust/typecheck/rust-hir-path-probe.h | 49 ---- gcc/rust/typecheck/rust-hir-type-check-path.cc | 6 +- 6 files changed, 447 insertions(+), 388 deletions(-) diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 91caebbee85e..e4e5704528cf 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -187,6 +187,7 @@ GRS_OBJS = \ rust/rust-polonius.o\ rust/rust-hir-dot-operator.o \ rust/rust-hir-path-probe.o \ + rust/rust-hir-path-probe-expr.o \ rust/rust-hir-path-probe-impl-trait.o \ rust/rust-hir-path-probe-type.o \ rust/rust-hir-path.o \ diff --git a/gcc/rust/typecheck/rust-hir-path-probe-expr.cc b/gcc/rust/typecheck/rust-hir-path-probe-expr.cc new file mode 100644 index 000000000000..690e3e35c876 --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-path-probe-expr.cc @@ -0,0 +1,364 @@ +// Copyright (C) 2020-2026 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-hir-path-probe-expr.h" +#include "rust-hir-item.h" +#include "rust-type-util.h" +#include "rust-hir-type-bounds.h" + +namespace Rust { +namespace Resolver { + +// PathProbeExpr + +PathProbeExpr::PathProbeExpr (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<PathProbeCandidate> +PathProbeExpr::Probe (TyTy::BaseType *receiver, + const HIR::PathIdentSegment &segment_name, + bool probe_impls, bool probe_bounds, + bool ignore_mandatory_trait_items, + DefId specific_trait_id) +{ + Analysis::Mappings &mappings = Analysis::Mappings::get (); + + PathProbeExpr probe (receiver, segment_name, specific_trait_id); + if (probe_impls) + { + if (receiver->get_kind () == TyTy::TypeKind::ADT) + { + const TyTy::ADTType *adt + = static_cast<const TyTy::ADTType *> (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_receiver_generic ()) + { + HIR::Trait *associated_trait = nullptr; + if (specific_trait_id != UNKNOWN_DEFID) + { + auto item_lookup = mappings.lookup_defid (specific_trait_id); + if (item_lookup.has_value ()) + { + HIR::Item *item = item_lookup.value (); + rust_assert (item->get_item_kind () + == HIR::Item::ItemKind::Trait); + associated_trait = static_cast<HIR::Trait *> (item); + } + } + + auto probed_bounds = TypeBoundsProbe::Probe (receiver, associated_trait); + 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 +PathProbeExpr::visit (HIR::TypeAlias &alias) +{ + Identifier name = alias.get_new_type_name (); + if (search.to_string ().compare (name.as_string ()) == 0) + { + HirId tyid = alias.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + if (!query_type (tyid, &ty)) + return; + + 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 +PathProbeExpr::visit (HIR::ConstantItem &constant) +{ + Identifier name = constant.get_identifier (); + if (search.to_string ().compare (name.as_string ()) == 0) + { + HirId tyid = constant.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + if (!query_type (tyid, &ty)) + return; + + 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 +PathProbeExpr::visit (HIR::Function &function) +{ + Identifier name = function.get_function_name (); + if (search.to_string ().compare (name.as_string ()) == 0) + { + HirId tyid = function.get_mappings ().get_hirid (); + TyTy::BaseType *ty = nullptr; + if (!query_type (tyid, &ty)) + return; + + 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 +PathProbeExpr::process_enum_item_for_candiates (const TyTy::ADTType *adt) +{ + if (specific_trait_id != UNKNOWN_DEFID) + return; + + TyTy::VariantDef *v; + if (!adt->lookup_variant (search.to_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 +PathProbeExpr::process_impl_items_for_candidates () +{ + if (auto *adt = receiver->try_as<TyTy::ADTType> ()) + { + auto adt_item = mappings.lookup_defid (adt->get_id ()); + if (adt_item.has_value ()) + { + NodeId adt_node_id = adt_item.value ()->get_mappings ().get_nodeid (); + mappings.iterate_adt_impl_items ( + adt_node_id, + [&] (HirId id, HIR::ImplItem *item, + HIR::ImplBlock *impl) mutable -> bool { + process_impl_item_candidate (id, item, impl); + return true; + }); + return; + } + } + + mappings.iterate_impl_items ( + [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool { + process_impl_item_candidate (id, item, impl); + return true; + }); +} + +void +PathProbeExpr::process_impl_item_candidate (HirId id, HIR::ImplItem *item, + HIR::ImplBlock *impl) +{ + current_impl = impl; + HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid (); + TyTy::BaseType *impl_block_ty = nullptr; + if (!query_type (impl_ty_id, &impl_block_ty)) + return; + + if (!types_compatable (TyTy::TyWithLocation (receiver), + TyTy::TyWithLocation (impl_block_ty), + impl->get_locus (), false)) + return; + + // lets visit the impl_item + item->accept_vis (*this); +} + +void +PathProbeExpr::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.to_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: + rust_unreachable (); + break; + } + + const TyTy::TypeBoundPredicate p (*trait_ref, BoundPolarity::RegularBound, + UNDEF_LOCATION); + TyTy::TypeBoundPredicateItem item (p, trait_item_ref); + + TyTy::BaseType *trait_item_tyty = item.get_raw_item ()->get_tyty (); + if (receiver->get_kind () != TyTy::DYNAMIC) + trait_item_tyty = item.get_tyty_for_receiver (receiver); + + 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 +PathProbeExpr::process_predicate_for_candidates ( + const TyTy::TypeBoundPredicate &predicate, bool ignore_mandatory_trait_items) +{ + const TraitReference *trait_ref = predicate.get (); + + tl::optional<TyTy::TypeBoundPredicateItem> item + = predicate.lookup_associated_item (search.to_string ()); + if (!item.has_value ()) + 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: + rust_unreachable (); + break; + } + + TyTy::BaseType *trait_item_tyty = item->get_raw_item ()->get_tyty (); + if (receiver->get_kind () != TyTy::DYNAMIC) + 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<std::pair<const TraitReference *, HIR::ImplBlock *>> +PathProbeExpr::union_bounds ( + const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>> a, + const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b) + const +{ + std::map<DefId, std::pair<const TraitReference *, HIR::ImplBlock *>> 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<std::pair<const TraitReference *, HIR::ImplBlock *>> union_set; + + for (auto it = mapper.begin (); it != mapper.end (); it++) + union_set.emplace_back (it->second.first, it->second.second); + + return union_set; +} + +bool +PathProbeExpr::is_receiver_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; +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-path-probe-expr.h b/gcc/rust/typecheck/rust-hir-path-probe-expr.h new file mode 100644 index 000000000000..e824da667850 --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-path-probe-expr.h @@ -0,0 +1,79 @@ +// Copyright (C) 2020-2026 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_PATH_PROBE_EXPR_H +#define RUST_HIR_PATH_PROBE_EXPR_H + +#include "rust-hir-path-probe.h" + +namespace Rust { +namespace Resolver { + +class PathProbeExpr : public TypeCheckBase, public HIR::HIRImplVisitor +{ +public: + static std::set<PathProbeCandidate> + Probe (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); + + 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); + + void process_impl_items_for_candidates (); + + void process_impl_item_candidate (HirId id, HIR::ImplItem *item, + HIR::ImplBlock *impl); + + void + process_associated_trait_for_candidates (const TraitReference *trait_ref, + HIR::ImplBlock *impl, + bool ignore_mandatory_trait_items); + + void + process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate, + bool ignore_mandatory_trait_items); + +protected: + PathProbeExpr (TyTy::BaseType *receiver, const HIR::PathIdentSegment &query, + DefId specific_trait_id); + + std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> + union_bounds ( + const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>> + a, + const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b) + const; + + bool is_receiver_generic () const; + + TyTy::BaseType *receiver; + const HIR::PathIdentSegment &search; + std::set<PathProbeCandidate> candidates; + HIR::ImplBlock *current_impl; + DefId specific_trait_id; +}; + +} // namespace Resolver +} // namespace Rust + +#endif // RUST_HIR_PATH_PROBE_EXPR_H diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc index 2a6f93797447..ca8c1468be86 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.cc +++ b/gcc/rust/typecheck/rust-hir-path-probe.cc @@ -136,341 +136,5 @@ PathProbeCandidate::operator< (const PathProbeCandidate &c) const return get_defid () < c.get_defid (); } -// PathProbeType - -PathProbeType::PathProbeType (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<PathProbeCandidate> -PathProbeType::Probe (TyTy::BaseType *receiver, - const HIR::PathIdentSegment &segment_name, - bool probe_impls, bool probe_bounds, - bool ignore_mandatory_trait_items, - DefId specific_trait_id) -{ - Analysis::Mappings &mappings = Analysis::Mappings::get (); - - PathProbeType probe (receiver, segment_name, specific_trait_id); - if (probe_impls) - { - if (receiver->get_kind () == TyTy::TypeKind::ADT) - { - const TyTy::ADTType *adt - = static_cast<const TyTy::ADTType *> (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_receiver_generic ()) - { - HIR::Trait *associated_trait = nullptr; - if (specific_trait_id != UNKNOWN_DEFID) - { - auto item_lookup = mappings.lookup_defid (specific_trait_id); - if (item_lookup.has_value ()) - { - HIR::Item *item = item_lookup.value (); - rust_assert (item->get_item_kind () - == HIR::Item::ItemKind::Trait); - associated_trait = static_cast<HIR::Trait *> (item); - } - } - - auto probed_bounds = TypeBoundsProbe::Probe (receiver, associated_trait); - 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.to_string ().compare (name.as_string ()) == 0) - { - HirId tyid = alias.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - if (!query_type (tyid, &ty)) - return; - - 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.to_string ().compare (name.as_string ()) == 0) - { - HirId tyid = constant.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - if (!query_type (tyid, &ty)) - return; - - 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.to_string ().compare (name.as_string ()) == 0) - { - HirId tyid = function.get_mappings ().get_hirid (); - TyTy::BaseType *ty = nullptr; - if (!query_type (tyid, &ty)) - return; - - 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.to_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 () -{ - if (auto *adt = receiver->try_as<TyTy::ADTType> ()) - { - auto adt_item = mappings.lookup_defid (adt->get_id ()); - if (adt_item.has_value ()) - { - NodeId adt_node_id = adt_item.value ()->get_mappings ().get_nodeid (); - mappings.iterate_adt_impl_items ( - adt_node_id, - [&] (HirId id, HIR::ImplItem *item, - HIR::ImplBlock *impl) mutable -> bool { - process_impl_item_candidate (id, item, impl); - return true; - }); - return; - } - } - - 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) -{ - current_impl = impl; - HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid (); - TyTy::BaseType *impl_block_ty = nullptr; - if (!query_type (impl_ty_id, &impl_block_ty)) - return; - - if (!types_compatable (TyTy::TyWithLocation (receiver), - TyTy::TyWithLocation (impl_block_ty), - impl->get_locus (), false)) - return; - - // lets visit the impl_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.to_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: - rust_unreachable (); - break; - } - - const TyTy::TypeBoundPredicate p (*trait_ref, BoundPolarity::RegularBound, - UNDEF_LOCATION); - TyTy::TypeBoundPredicateItem item (p, trait_item_ref); - - TyTy::BaseType *trait_item_tyty = item.get_raw_item ()->get_tyty (); - if (receiver->get_kind () != TyTy::DYNAMIC) - trait_item_tyty = item.get_tyty_for_receiver (receiver); - - 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 (); - - tl::optional<TyTy::TypeBoundPredicateItem> item - = predicate.lookup_associated_item (search.to_string ()); - if (!item.has_value ()) - 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: - rust_unreachable (); - break; - } - - TyTy::BaseType *trait_item_tyty = item->get_raw_item ()->get_tyty (); - if (receiver->get_kind () != TyTy::DYNAMIC) - 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<std::pair<const TraitReference *, HIR::ImplBlock *>> -PathProbeType::union_bounds ( - const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>> a, - const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b) - const -{ - std::map<DefId, std::pair<const TraitReference *, HIR::ImplBlock *>> 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<std::pair<const TraitReference *, HIR::ImplBlock *>> union_set; - - for (auto it = mapper.begin (); it != mapper.end (); it++) - union_set.emplace_back (it->second.first, it->second.second); - - return union_set; -} - -bool -PathProbeType::is_receiver_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; -} - } // 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 d9800e1c696f..87bf1768970c 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -104,55 +104,6 @@ struct PathProbeCandidate bool operator< (const PathProbeCandidate &c) const; }; -class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor -{ -public: - static std::set<PathProbeCandidate> - Probe (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); - - 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); - - void process_impl_items_for_candidates (); - - void process_impl_item_candidate (HirId id, HIR::ImplItem *item, - HIR::ImplBlock *impl); - - void - process_associated_trait_for_candidates (const TraitReference *trait_ref, - HIR::ImplBlock *impl, - bool ignore_mandatory_trait_items); - - void - process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate, - bool ignore_mandatory_trait_items); - -protected: - PathProbeType (TyTy::BaseType *receiver, const HIR::PathIdentSegment &query, - DefId specific_trait_id); - - std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> - union_bounds ( - const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>> - a, - const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b) - const; - - bool is_receiver_generic () const; - - TyTy::BaseType *receiver; - const HIR::PathIdentSegment &search; - std::set<PathProbeCandidate> candidates; - HIR::ImplBlock *current_impl; - DefId specific_trait_id; -}; - class ReportMultipleCandidateError : private TypeCheckBase { public: diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 9a44fcebcc13..4c7a796d77dc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -25,7 +25,7 @@ #include "rust-hir-trait-resolve.h" #include "rust-rib.h" #include "rust-substitution-mapper.h" -#include "rust-hir-path-probe.h" +#include "rust-hir-path-probe-expr.h" #include "rust-type-util.h" #include "rust-hir-type-bounds.h" #include "rust-hir-item.h" @@ -423,13 +423,13 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, // probe the path is done in two parts one where we search impls if no // candidate is found then we search extensions from traits auto candidates - = PathProbeType::Probe (prev_segment, seg.get_segment (), probe_impls, + = PathProbeExpr::Probe (prev_segment, seg.get_segment (), probe_impls, false /*probe_bounds*/, true /*ignore_mandatory_trait_items*/); if (candidates.size () == 0) { candidates - = PathProbeType::Probe (prev_segment, seg.get_segment (), false, + = PathProbeExpr::Probe (prev_segment, seg.get_segment (), false, true /*probe_bounds*/, false /*ignore_mandatory_trait_items*/);
