https://gcc.gnu.org/g:c0640954e1a340764368a10f3b7774696e32a8ae

commit r15-8578-gc0640954e1a340764368a10f3b7774696e32a8ae
Author: Arthur Cohen <arthur.co...@embecosm.com>
Date:   Wed Dec 25 11:03:44 2024 +0000

    gccrs: 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.

Diff:
---
 gcc/rust/resolve/rust-ast-resolve-type.cc          | 57 ++++++++++++++++++++--
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc    |  3 +-
 .../rust/compile/additional-trait-bounds1.rs       | 10 ++++
 .../rust/compile/additional-trait-bounds2.rs       |  9 ++++
 .../rust/compile/additional-trait-bounds2nr2.rs    | 11 +++++
 gcc/testsuite/rust/compile/nr2/exclude             |  1 +
 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 ec5e8a762a70..cb5a18d5d477 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 ac5f1c575461..40f067319b57 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 000000000000..449a72fe4612
--- /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 000000000000..843228ae9a64
--- /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 000000000000..6764f6e80120
--- /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 797e59a5c580..8bdcc8ac3388 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

Reply via email to