diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-10-05 17:24:26 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-10-06 14:07:16 +0100 |
commit | e033f1705dde104c44d69cec87cb728dba596c6f (patch) | |
tree | 073a1393a65f414b83a4874fed6503f799a174cf /gcc | |
parent | fc746fd620118f91bb8bfc139c7be3fb2356e820 (diff) | |
download | gcc-e033f1705dde104c44d69cec87cb728dba596c6f.zip gcc-e033f1705dde104c44d69cec87cb728dba596c6f.tar.gz gcc-e033f1705dde104c44d69cec87cb728dba596c6f.tar.bz2 |
Ensure uniqueness on Path probe's
When we lookup names in paths such as Foo::bar, foo is a type we resolve
and then we lookup 'bar' based on what type Foo is which includes probing
relevant bounds of this type. We currently return a vector of possible
candidates and this patch changes it so that we return a set of unique
items based on DefId.
Addresses #1555
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 4 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 8 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 108 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 2 |
5 files changed, 58 insertions, 66 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 660ad09..9ff2be6 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1982,7 +1982,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref, // trait-impl-item's definition auto root = receiver->get_root (); - std::vector<Resolver::PathProbeCandidate> candidates + auto candidates = Resolver::PathProbeType::Probe (root, segment, true /* probe_impls */, false /* probe_bounds */, true /* ignore_mandatory_trait_items */); @@ -2011,7 +2011,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref, // implementation and we should just return error_mark_node rust_assert (candidates.size () == 1); - auto &candidate = candidates.at (0); + auto &candidate = *candidates.begin (); rust_assert (candidate.is_impl_candidate ()); rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF); TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty); diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 4fb3d54..f89da2b 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -251,7 +251,7 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, // item so its up to us to figure out if this path should resolve // to an trait-impl-block-item or if it can be defaulted to the // trait-impl-item's definition - std::vector<Resolver::PathProbeCandidate> candidates + auto candidates = Resolver::PathProbeImplTrait::Probe (receiver, final_segment, trait_ref); if (candidates.size () == 0) @@ -270,7 +270,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, } else { - Resolver::PathProbeCandidate &candidate = candidates.at (0); + rust_assert (candidates.size () == 1); + + auto candidate = *candidates.begin (); rust_assert (candidate.is_impl_candidate ()); HIR::ImplBlock *impl = candidate.item.impl.parent; @@ -288,8 +290,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, else return CompileInherentImplItem::Compile (impl_item, ctx, lookup, true, expr_locus); - - lookup->set_ty_ref (impl_item->get_impl_mappings ().get_hirid ()); } } } diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index b1d7f4b..c8f207c 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -80,17 +80,17 @@ struct PathProbeCandidate PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus, EnumItemCandidate enum_field) - : type (type), ty (ty), item (enum_field) + : type (type), ty (ty), locus (locus), item (enum_field) {} PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus, ImplItemCandidate impl) - : type (type), ty (ty), item (impl) + : type (type), ty (ty), locus (locus), item (impl) {} PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus, TraitItemCandidate trait) - : type (type), ty (ty), item (trait) + : type (type), ty (ty), locus (locus), item (trait) {} std::string as_string () const @@ -123,12 +123,45 @@ struct PathProbeCandidate } bool is_error () const { return type == ERROR; } + + DefId get_defid () const + { + switch (type) + { + case ENUM_VARIANT: + return item.enum_field.variant->get_defid (); + break; + + case IMPL_CONST: + case IMPL_TYPE_ALIAS: + case IMPL_FUNC: + return item.impl.impl_item->get_impl_mappings ().get_defid (); + break; + + case TRAIT_ITEM_CONST: + case TRAIT_TYPE_ALIAS: + case TRAIT_FUNC: + return item.trait.item_ref->get_mappings ().get_defid (); + break; + + case ERROR: + default: + return UNKNOWN_DEFID; + } + + return UNKNOWN_DEFID; + } + + bool operator< (const PathProbeCandidate &c) const + { + return get_defid () < c.get_defid (); + } }; class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor { public: - static std::vector<PathProbeCandidate> + static std::set<PathProbeCandidate> Probe (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name, bool probe_impls, bool probe_bounds, bool ignore_mandatory_trait_items, @@ -203,7 +236,7 @@ public: PathProbeCandidate candidate{ PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS, ty, alias.get_locus (), impl_item_candidate}; - candidates.push_back (std::move (candidate)); + candidates.insert (std::move (candidate)); } } @@ -222,7 +255,7 @@ public: PathProbeCandidate candidate{ PathProbeCandidate::CandidateType::IMPL_CONST, ty, constant.get_locus (), impl_item_candidate}; - candidates.push_back (std::move (candidate)); + candidates.insert (std::move (candidate)); } } @@ -241,7 +274,7 @@ public: PathProbeCandidate candidate{ PathProbeCandidate::CandidateType::IMPL_FUNC, ty, function.get_locus (), impl_item_candidate}; - candidates.push_back (std::move (candidate)); + candidates.insert (std::move (candidate)); } } @@ -259,7 +292,7 @@ protected: PathProbeCandidate candidate{ PathProbeCandidate::CandidateType::ENUM_VARIANT, receiver->clone (), mappings->lookup_location (adt->get_ty_ref ()), enum_item_candidate}; - candidates.push_back (std::move (candidate)); + candidates.insert (std::move (candidate)); } void process_impl_items_for_candidates () @@ -338,8 +371,9 @@ protected: impl}; PathProbeCandidate candidate{candidate_type, trait_item_tyty, - trait_ref->get_locus (), trait_item_candidate}; - candidates.push_back (std::move (candidate)); + trait_item_ref->get_locus (), + trait_item_candidate}; + candidates.insert (std::move (candidate)); } void @@ -383,7 +417,7 @@ protected: PathProbeCandidate candidate{candidate_type, trait_item_tyty, trait_item_ref->get_locus (), trait_item_candidate}; - candidates.push_back (std::move (candidate)); + candidates.insert (std::move (candidate)); } protected: @@ -428,72 +462,30 @@ protected: const TyTy::BaseType *receiver; const HIR::PathIdentSegment &search; - std::vector<PathProbeCandidate> candidates; + std::set<PathProbeCandidate> candidates; HIR::ImplBlock *current_impl; DefId specific_trait_id; }; -class ReportMultipleCandidateError : private TypeCheckBase, - private HIR::HIRImplVisitor +class ReportMultipleCandidateError : private TypeCheckBase { public: - static void Report (std::vector<PathProbeCandidate> &candidates, + static void Report (std::set<PathProbeCandidate> &candidates, const HIR::PathIdentSegment &query, Location query_locus) { RichLocation r (query_locus); - ReportMultipleCandidateError visitor (r); for (auto &c : candidates) - { - switch (c.type) - { - case PathProbeCandidate::CandidateType::ERROR: - case PathProbeCandidate::CandidateType::ENUM_VARIANT: - gcc_unreachable (); - break; - - case PathProbeCandidate::CandidateType::IMPL_CONST: - case PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS: - case PathProbeCandidate::CandidateType::IMPL_FUNC: - c.item.impl.impl_item->accept_vis (visitor); - break; - - case PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST: - case PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS: - case PathProbeCandidate::CandidateType::TRAIT_FUNC: - r.add_range (c.item.trait.item_ref->get_locus ()); - break; - } - } + r.add_range (c.locus); rust_error_at (r, "multiple applicable items in scope for: %s", query.as_string ().c_str ()); } - - void visit (HIR::TypeAlias &alias) override - { - r.add_range (alias.get_locus ()); - } - - void visit (HIR::ConstantItem &constant) override - { - r.add_range (constant.get_locus ()); - } - - void visit (HIR::Function &function) override - { - r.add_range (function.get_locus ()); - } - -private: - ReportMultipleCandidateError (RichLocation &r) : TypeCheckBase (), r (r) {} - - RichLocation &r; }; class PathProbeImplTrait : public PathProbeType { public: - static std::vector<PathProbeCandidate> + static std::set<PathProbeCandidate> Probe (const TyTy::BaseType *receiver, const HIR::PathIdentSegment &segment_name, const TraitReference *trait_reference) diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 2450576..4e765ad 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -337,7 +337,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, return; } - auto &candidate = candidates.at (0); + auto &candidate = *candidates.begin (); prev_segment = tyseg; tyseg = candidate.ty; diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index a47d40e..67e6cb0e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -462,7 +462,7 @@ TypeCheckType::resolve_segments ( return new TyTy::ErrorType (expr_id); } - auto &candidate = candidates.at (0); + auto &candidate = *candidates.begin (); prev_segment = tyseg; tyseg = candidate.ty; |