diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-06-16 17:39:14 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-06-16 17:45:05 +0100 |
commit | 9474a0f4a55caf1e2e5945d7407164cf3b58f056 (patch) | |
tree | 7e3b238813583e89aab5473fb99ac9df27869964 | |
parent | 59f09fd5a48046ceba064bde2f230386fbc3700f (diff) | |
download | gcc-9474a0f4a55caf1e2e5945d7407164cf3b58f056.zip gcc-9474a0f4a55caf1e2e5945d7407164cf3b58f056.tar.gz gcc-9474a0f4a55caf1e2e5945d7407164cf3b58f056.tar.bz2 |
TraitImpl blocks have a different CanonicalPath to normal impl blocks
TraitImpls have a canonical path which is a trait projection such as
```rust
pub trait Trait { // ::a::Trait
fn f(&self); // ::a::Trait::f
}
impl Trait for Struct {
fn f(&self) {} // <::a::Struct as ::a::Trait>::f
}
```
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 12 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 11 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 8 |
3 files changed, 29 insertions, 2 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 0893224..3dd81d8 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -149,11 +149,19 @@ public: { bool canonicalize_type_args = !impl_block.has_generics (); bool type_resolve_generic_args = false; - CanonicalPath impl_type + + CanonicalPath impl_type_seg = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (), canonicalize_type_args, type_resolve_generic_args); - CanonicalPath impl_prefix = prefix.append (impl_type); + CanonicalPath trait_type_seg + = ResolveTypeToCanonicalPath::resolve (impl_block.get_trait_path (), + canonicalize_type_args, + type_resolve_generic_args); + + CanonicalPath projection + = TraitImplProjection::resolve (trait_type_seg, impl_type_seg); + CanonicalPath impl_prefix = prefix.append (projection); for (auto &impl_item : impl_block.get_impl_items ()) ResolveToplevelImplItem::go (impl_item.get (), impl_prefix); diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 05b347c3..6d40517 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -162,6 +162,17 @@ public: } }; +class TraitImplProjection +{ +public: + static CanonicalPath resolve (const CanonicalPath &trait_seg, + const CanonicalPath &impl_type_seg) + { + return CanonicalPath ("<" + impl_type_seg.get () + " as " + trait_seg.get () + + ">"); + } +}; + // FIXME: as part of imports and visibility we need to be able to keep a context // for handling PathInExpressions segments as they can be local to a particular // lexical scope requiring a context to be maintained for resolution diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index e45847e..b1f745e 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -36,6 +36,14 @@ namespace Resolver { // impl X<T> { fn test - path X::test} // impl X<i32> { fn test - path X<i32>::test } // impl X<f32> { fn test - path X<f32>::test } +// +// pub trait Trait { // ::a::Trait +// fn f(&self); // ::a::Trait::f +// } +// +// impl Trait for Struct { +// fn f(&self) {} // <::a::Struct as ::a::Trait>::f +// } class CanonicalPath { public: |