diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-12-25 11:03:44 +0000 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2024-12-31 17:00:14 +0000 |
commit | 5ab3543b1b0753f48ba364f4b6ea29c5a3f80ffa (patch) | |
tree | 0ef5cc1f47628673a07bf2f1b1d9441a114cf389 /gcc | |
parent | b33f6348b7bfd7d9060f0614d54af2fb98d8bc2a (diff) | |
download | gcc-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.cc | 57 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/additional-trait-bounds1.rs | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/additional-trait-bounds2.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs | 11 | ||||
-rw-r--r-- | 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 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 |