diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-10-30 16:24:34 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-11-01 13:12:48 +0000 |
commit | 56e4a9db1e0804150d391e5b4a5d6a03d7525c8d (patch) | |
tree | 5658f7bc0c0f8cb03e4294223a160df89e7f6c7c | |
parent | 919a5a4c5aa7c567e2f3b3a75d7de91c1425227f (diff) | |
download | gcc-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.h | 46 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 14 |
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; |