aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2024-12-25 11:03:44 +0000
committerCohenArthur <arthur.cohen@embecosm.com>2024-12-31 17:00:14 +0000
commit5ab3543b1b0753f48ba364f4b6ea29c5a3f80ffa (patch)
tree0ef5cc1f47628673a07bf2f1b1d9441a114cf389 /gcc
parentb33f6348b7bfd7d9060f0614d54af2fb98d8bc2a (diff)
downloadgcc-5ab3543b1b0753f48ba364f4b6ea29c5a3f80ffa.zip
gcc-5ab3543b1b0753f48ba364f4b6ea29c5a3f80ffa.tar.gz
gcc-5ab3543b1b0753f48ba364f4b6ea29c5a3f80ffa.tar.bz2
resolve: Name resolve trait bounds properly
gcc/rust/ChangeLog: * resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): Resolve additional trait bounds. * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Error out properly on unresolved type-path instead of crashing. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: Exclude additional-trait-bounds2 for different error message. * rust/compile/additional-trait-bounds1.rs: New test. * rust/compile/additional-trait-bounds2.rs: New test. * rust/compile/additional-trait-bounds2nr2.rs: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc57
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc3
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds1.rs10
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds2.rs9
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs11
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude1
6 files changed, 87 insertions, 4 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 15ae8db..56ce95f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -18,6 +18,8 @@
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-expr.h"
+#include "rust-canonical-path.h"
+#include "rust-type.h"
namespace Rust {
namespace Resolver {
@@ -495,10 +497,59 @@ ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type)
}
void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
{
- // FIXME is this actually allowed? dyn A+B
- rust_unreachable ();
+ rust_assert (!type.get_type_param_bounds ().empty ());
+
+ auto &first_bound = type.get_type_param_bounds ().front ();
+
+ // Is it allowed or even possible to have a lifetime bound as a first bound?
+ if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME)
+ rust_unreachable ();
+
+ auto &trait = static_cast<AST::TraitBound &> (*first_bound);
+
+ CanonicalPath path = CanonicalPath::create_empty ();
+ bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
+
+ // right?
+ rust_assert (ok);
+
+ auto slice_path = "<dyn " + path.get ();
+
+ for (size_t idx = 1; idx < type.get_type_param_bounds ().size (); idx++)
+ {
+ auto &additional_bound = type.get_type_param_bounds ()[idx];
+
+ std::string str;
+
+ switch (additional_bound->get_bound_type ())
+ {
+ case AST::TypeParamBound::TRAIT: {
+ auto bound_path = CanonicalPath::create_empty ();
+
+ auto &bound_type_path
+ = static_cast<AST::TraitBound &> (*additional_bound)
+ .get_type_path ();
+ bool ok
+ = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path);
+
+ if (!ok)
+ continue;
+
+ str = bound_path.get ();
+ break;
+ }
+ case AST::TypeParamBound::LIFETIME:
+ rust_unreachable ();
+ break;
+ }
+ slice_path += " + " + str;
+ }
+
+ slice_path += ">";
+
+ result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
}
void
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index f2245c9..6d450bc 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -282,7 +282,8 @@ Late::visit (AST::TypePath &type)
ctx.map_usage (Usage (type.get_node_id ()),
Definition (resolved->get_node_id ()));
else
- rust_unreachable ();
+ rust_error_at (type.get_locus (), "could not resolve type path %qs",
+ str.c_str ());
DefaultResolver::visit (type);
}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds1.rs b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
new file mode 100644
index 0000000..449a72f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
@@ -0,0 +1,10 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send {}
+impl dyn A + Send + Sync {}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
new file mode 100644
index 0000000..843228a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
@@ -0,0 +1,9 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "failed to resolve TypePath: NonExist in this scope" }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
new file mode 100644
index 0000000..6764f6e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type path .NonExist." }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index 797e59a..8bdcc8a 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -208,4 +208,5 @@ issue-2905-2.rs
issue-2907.rs
issue-2423.rs
issue-266.rs
+additional-trait-bounds2.rs
# please don't delete the trailing newline