aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-10-30 16:24:34 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-11-01 13:12:48 +0000
commit56e4a9db1e0804150d391e5b4a5d6a03d7525c8d (patch)
tree5658f7bc0c0f8cb03e4294223a160df89e7f6c7c
parent919a5a4c5aa7c567e2f3b3a75d7de91c1425227f (diff)
downloadgcc-56e4a9db1e0804150d391e5b4a5d6a03d7525c8d.zip
gcc-56e4a9db1e0804150d391e5b4a5d6a03d7525c8d.tar.gz
gcc-56e4a9db1e0804150d391e5b4a5d6a03d7525c8d.tar.bz2
Add TypePath resolution for enum ctor
When constructing enums we end up with a path like Enum::discriminant so we must lookup the variant to figure out how to construct the enum. Addresses #79
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h46
-rw-r--r--gcc/rust/typecheck/rust-tyty.h14
2 files changed, 59 insertions, 1 deletions
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index b35f37e..d318b9c 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -32,6 +32,8 @@ struct PathProbeCandidate
{
enum CandidateType
{
+ ENUM_VARIANT,
+
IMPL_CONST,
IMPL_TYPE_ALIAS,
IMPL_FUNC,
@@ -41,6 +43,12 @@ struct PathProbeCandidate
TRAIT_FUNC,
};
+ struct EnumItemCandidate
+ {
+ const TyTy::ADTType *parent;
+ const TyTy::VariantDef *variant;
+ };
+
struct ImplItemCandidate
{
HIR::ImplItem *impl_item;
@@ -59,14 +67,21 @@ struct PathProbeCandidate
Location locus;
union Candidate
{
+ EnumItemCandidate enum_field;
ImplItemCandidate impl;
TraitItemCandidate trait;
+ Candidate (EnumItemCandidate enum_field) : enum_field (enum_field) {}
Candidate (ImplItemCandidate impl) : impl (impl) {}
Candidate (TraitItemCandidate trait) : trait (trait) {}
} item;
PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
+ EnumItemCandidate enum_field)
+ : type (type), ty (ty), item (enum_field)
+ {}
+
+ PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
ImplItemCandidate impl)
: type (type), ty (ty), item (impl)
{}
@@ -81,6 +96,8 @@ struct PathProbeCandidate
return "PathProbe candidate TODO - as_string";
}
+ bool is_enum_candidate () const { return type == ENUM_VARIANT; }
+
bool is_impl_candidate () const
{
return type == IMPL_CONST || type == IMPL_TYPE_ALIAS || type == IMPL_FUNC;
@@ -106,7 +123,17 @@ public:
{
PathProbeType probe (receiver, segment_name);
if (probe_impls)
- probe.process_impl_items_for_candidates ();
+ {
+ 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;
@@ -192,6 +219,19 @@ public:
}
protected:
+ void process_enum_item_for_candiates (const TyTy::ADTType *adt)
+ {
+ 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.push_back (std::move (candidate));
+ }
+
void process_impl_items_for_candidates ()
{
mappings->iterate_impl_items ([&] (HirId id, HIR::ImplItem *item,
@@ -403,6 +443,10 @@ public:
{
switch (c.type)
{
+ case PathProbeCandidate::CandidateType::ENUM_VARIANT:
+ gcc_unreachable ();
+ break;
+
case PathProbeCandidate::CandidateType::IMPL_CONST:
case PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS:
case PathProbeCandidate::CandidateType::IMPL_FUNC:
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 909f210..1afb0ed 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1232,6 +1232,20 @@ public:
std::vector<VariantDef *> &get_variants () { return variants; }
const std::vector<VariantDef *> &get_variants () const { return variants; }
+ bool lookup_variant (const std::string &lookup,
+ VariantDef **found_variant) const
+ {
+ for (auto &variant : variants)
+ {
+ if (variant->get_identifier ().compare (lookup) == 0)
+ {
+ *found_variant = variant;
+ return true;
+ }
+ }
+ return false;
+ }
+
ADTType *
handle_substitions (SubstitutionArgumentMappings mappings) override final;