aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-ast-resolve.cc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-06-14 14:25:59 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-06-14 16:31:34 +0100
commit75c44883dbe84682beabc92db7c89bc6db491db8 (patch)
tree52bea53f2c0f257c8a1a85de28e354456a53dfb6 /gcc/rust/resolve/rust-ast-resolve.cc
parentdf36e6b9abb197ceb0ff5d1020482c75c6f1424a (diff)
downloadgcc-75c44883dbe84682beabc92db7c89bc6db491db8.zip
gcc-75c44883dbe84682beabc92db7c89bc6db491db8.tar.gz
gcc-75c44883dbe84682beabc92db7c89bc6db491db8.tar.bz2
Name resolver should try to resolve each segment in turn
Name resolution tried to greedily resolve the entire CanonicalPath in one lookup which was ok for simple paths like A::B. This changes the name resolver to resolve each segment which allows the type resolution to determine the root path to be up until the segment is unresolved which will then require a PathProbe or its a failure. This will be required to support modules which extend the resolution to be much more generic than is assumed here. Addresses: #432
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve.cc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc112
1 files changed, 58 insertions, 54 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index f97c97b..74ad4b8 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -537,61 +537,65 @@ ResolvePath::resolve_path (AST::PathInExpression *expr)
AST::PathExprSegment &seg = expr->get_segments ().at (i);
auto s = ResolvePathSegmentToCanonicalPath::resolve (seg);
path = path.append (s);
- }
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
- {
- resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (path, &resolved_node))
- {
- resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- else
- {
- // attempt to fully resolve the path which is allowed to fail given the
- // following scenario
- //
- // https://github.com/Rust-GCC/gccrs/issues/355 Paths are
- // resolved fully here, there are limitations though imagine:
- //
- // struct Foo<A> (A);
- //
- // impl Foo<isize> {
- // fn test() -> ...
- //
- // impl Foo<f32> {
- // fn test() -> ...
- //
- // fn main() {
- // let a:i32 = Foo::test();
- //
- // there are multiple paths that test can resolve to Foo::<?>::test here
- // so we cannot resolve this case
- //
- // canonical names:
- //
- // struct Foo<A> -> Foo
- // impl Foo<isize>::fn test -> Foo::isize::test
- // impl Foo<f32>::fn test -> Foo::f32::test
- //
- // Since there is the case we have the following paths for test:
- //
- // Foo::isize::test
- // Foo::f32::test
- // vs
- // Foo::test
- //
- // but the lookup was simply Foo::test we must rely on type resolution to
- // figure this type out in a similar fashion to method resolution with a
- // probe phase
+ if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_name (seg.get_node_id (), resolved_node);
+ resolver->insert_new_definition (seg.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_type (seg.get_node_id (), resolved_node);
+ resolver->insert_new_definition (seg.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ else
+ {
+ // attempt to fully resolve the path which is allowed to fail given
+ // the following scenario
+ //
+ // https://github.com/Rust-GCC/gccrs/issues/355 Paths are
+ // resolved fully here, there are limitations though imagine:
+ //
+ // struct Foo<A> (A);
+ //
+ // impl Foo<isize> {
+ // fn test() -> ...
+ //
+ // impl Foo<f32> {
+ // fn test() -> ...
+ //
+ // fn main() {
+ // let a:i32 = Foo::test();
+ //
+ // there are multiple paths that test can resolve to Foo::<?>::test
+ // here so we cannot resolve this case
+ //
+ // canonical names:
+ //
+ // struct Foo<A> -> Foo
+ // impl Foo<isize>::fn test -> Foo::isize::test
+ // impl Foo<f32>::fn test -> Foo::f32::test
+ //
+ // Since there is the case we have the following paths for test:
+ //
+ // Foo::isize::test
+ // Foo::f32::test
+ // vs
+ // Foo::test
+ //
+ // but the lookup was simply Foo::test we must rely on type resolution
+ // to figure this type out in a similar fashion to method resolution
+ // with a probe phase
+
+ // nothing more we can do we need the type resolver to try and resolve
+ // this
+ return;
+ }
}
}