diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-16 17:16:27 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-16 17:16:27 +0000 |
commit | eeee6c73f048177dfdd94c50fe387391d225f4f5 (patch) | |
tree | b11d635e4502c778fe7db8bfae2f1098cc083471 | |
parent | 350b0e595144cf7c6cf70807b429d87077173415 (diff) | |
parent | 9474a0f4a55caf1e2e5945d7407164cf3b58f056 (diff) | |
download | gcc-eeee6c73f048177dfdd94c50fe387391d225f4f5.zip gcc-eeee6c73f048177dfdd94c50fe387391d225f4f5.tar.gz gcc-eeee6c73f048177dfdd94c50fe387391d225f4f5.tar.bz2 |
Merge #496
496: TraitImpl blocks have a different CanonicalPath to normal impl blocks r=philberty a=philberty
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
}
```
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
-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: |