diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-06-03 15:12:00 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-06-10 17:09:34 +0100 |
commit | 7ca7362602d4e827ecbc39d5cfdf56df9044633b (patch) | |
tree | 7e149ddc7c9ffb0f72bcd4be2459abc7d1ee688a /gcc/rust/resolve/rust-ast-resolve.cc | |
parent | fc3ef6c4b1fad0d88a65043df8102437416b1df3 (diff) | |
download | gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.zip gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.gz gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.bz2 |
This patch implements complex Path resolution
This patch completely reimplements our name resolution process for Paths in
general. This patch gets rid of the old Resolver::Definition structures
which were used so that we can map patterns back to LetStmts and establish
an hierarchy of nodes. This was not nessecary and complicated name/type
resolution.
TypePaths and PathInExpression are similar but have a slightl tweak in the
order they lookup the relevant scopes for types. But overall work the same.
There are several cases of paths you must consider in type resolution:
- i32 (simple type path)
- Self::A (associated type reference)
- mod::foo::impl_item() (reference to impl item)
- super::foo (reference to impl item)
- crate::foo
- T::bound()
In name resolution we cannot always fully resolve a path but have to rely
on the type-resolution to fully resolve a path as it may require careful
thought. For example a path like:
mod::foo::item()
might be for a generic foo<T>(), which might have two specialized impl
blocks so the best the name resolution can do is resolve mod::foo then
leave it up to the type resolution to figure out which item this is. We
might have i32 which is just a simple lookup.
Apart from that this patch introduces a module parent child hierachy so
that on paths such as super::foo we resolve super to be our parent module
scope then foo can be resolved with the lookup in the items for that
module.
More over this patch gets rid of some but not all of the awkward name
canonicalization to try and patch paths directly. More cleanup is still
needed here to make the name resolution step easier to read. This was
notable in the Qualified path handling where we can now rely on the type
resolver to setup the associated types properly rather than the name
resolver requiring us to resolve this directly.
Fixes #1251 #1230
Addresses #1227 #1153
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve.cc')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index 8465162..169237a 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -81,6 +81,11 @@ NameResolution::go (AST::Crate &crate) = CanonicalPath::new_seg (scope_node_id, crate_name); crate_prefix.set_crate_num (cnum); + // setup a dummy crate node + resolver->get_name_scope ().insert ( + CanonicalPath::new_seg (crate.get_node_id (), "__$$crate__"), + crate.get_node_id (), Location ()); + // setup the root scope resolver->push_new_module_scope (scope_node_id); @@ -167,19 +172,21 @@ ResolveRelativeTypePath::resolve_qual_seg (AST::QualifiedPathType &seg, seg.as_string ().c_str ()); return false; } - bool include_generic_args_in_path = false; - NodeId type_resolved_node - = ResolveType::go (seg.get_type ().get (), seg.get_node_id ()); + auto type = seg.get_type ().get (); + NodeId type_resolved_node = ResolveType::go (type, seg.get_node_id ()); if (type_resolved_node == UNKNOWN_NODEID) return false; - CanonicalPath impl_type_seg - = ResolveTypeToCanonicalPath::resolve (*seg.get_type ().get (), - include_generic_args_in_path); + const CanonicalPath *impl_type_seg = nullptr; + bool ok + = mappings->lookup_canonical_path (mappings->get_current_crate (), + type_resolved_node, &impl_type_seg); + rust_assert (ok); + if (!seg.has_as_clause ()) { - result = result.append (impl_type_seg); + result = result.append (*impl_type_seg); return true; } @@ -188,12 +195,15 @@ ResolveRelativeTypePath::resolve_qual_seg (AST::QualifiedPathType &seg, if (trait_resolved_node == UNKNOWN_NODEID) return false; - CanonicalPath trait_type_seg - = ResolveTypeToCanonicalPath::resolve (seg.get_as_type_path (), - include_generic_args_in_path); + const CanonicalPath *trait_type_seg = nullptr; + ok = mappings->lookup_canonical_path (mappings->get_current_crate (), + trait_resolved_node, &trait_type_seg); + rust_assert (ok); + CanonicalPath projection - = TraitImplProjection::resolve (seg.get_node_id (), trait_type_seg, - impl_type_seg); + = TraitImplProjection::resolve (seg.get_node_id (), *trait_type_seg, + *impl_type_seg); + result = result.append (projection); return true; } |