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
}
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,
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));
}
}
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::IMPL_CONST, ty,
constant.get_locus (), impl_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
}
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::IMPL_FUNC, ty,
function.get_locus (), impl_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
}
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 ()
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
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:
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)