diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-06-14 14:25:59 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-06-14 16:31:34 +0100 |
commit | 75c44883dbe84682beabc92db7c89bc6db491db8 (patch) | |
tree | 52bea53f2c0f257c8a1a85de28e354456a53dfb6 /gcc/rust/resolve/rust-ast-resolve.cc | |
parent | df36e6b9abb197ceb0ff5d1020482c75c6f1424a (diff) | |
download | gcc-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.cc | 112 |
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; + } } } |