aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-16 17:16:27 +0000
committerGitHub <noreply@github.com>2021-06-16 17:16:27 +0000
commiteeee6c73f048177dfdd94c50fe387391d225f4f5 (patch)
treeb11d635e4502c778fe7db8bfae2f1098cc083471
parent350b0e595144cf7c6cf70807b429d87077173415 (diff)
parent9474a0f4a55caf1e2e5945d7407164cf3b58f056 (diff)
downloadgcc-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.h12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h11
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h8
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: