diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-12-25 11:03:44 +0000 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-21 12:55:43 +0100 |
commit | c0640954e1a340764368a10f3b7774696e32a8ae (patch) | |
tree | 381ce7ebf2db113cbadf9c5854abb3ab8c71c91a /gcc/rust/resolve | |
parent | f30ba73582e4c53d4936e9c091d60b187a276373 (diff) | |
download | gcc-c0640954e1a340764368a10f3b7774696e32a8ae.zip gcc-c0640954e1a340764368a10f3b7774696e32a8ae.tar.gz gcc-c0640954e1a340764368a10f3b7774696e32a8ae.tar.bz2 |
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.
Diffstat (limited to 'gcc/rust/resolve')
-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 |
2 files changed, 56 insertions, 4 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index ec5e8a7..cb5a18d 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 ac5f1c5..40f0673 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); } |