diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc index 34fddb021a4..ef61d573ab6 100644 --- a/gcc/rust/ast/rust-path.cc +++ b/gcc/rust/ast/rust-path.cc @@ -266,6 +266,27 @@ TypePath::as_simple_path () const locus); } +std::string +TypePath::make_debug_string () const +{ + rust_assert (!segments.empty ()); + + std::string output; + + for (const auto &segment : segments) + { + if (segment != nullptr && !segment->is_lang_item () + && !segment->is_error ()) + { + if (!output.empty () || has_opening_scope_resolution_op ()) + output.append ("::"); + output.append (segment->get_ident_segment ().as_string ()); + } + } + + return output; +} + // hopefully definition here will prevent circular dependency issue TraitBound * TypePath::to_trait_bound (bool in_parens) const diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 31575105d98..6f53188d9a3 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -1211,6 +1211,8 @@ class TypePath : public TypeNoBounds std::string as_string () const override; + std::string make_debug_string () const; + /* Converts TypePath to SimplePath if possible (i.e. no generic or function * arguments). Otherwise returns an empty SimplePath. */ SimplePath as_simple_path () const; diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc index 1ec38bae4d7..7d8029fe3bf 100644 --- a/gcc/rust/resolve/rust-default-resolver.cc +++ b/gcc/rust/resolve/rust-default-resolver.cc @@ -72,17 +72,54 @@ DefaultResolver::visit (AST::Trait &trait) void DefaultResolver::visit (AST::InherentImpl &impl) { - auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); }; + visit_outer_attrs (impl); + visit (impl.get_visibility ()); + visit_inner_attrs (impl); - ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); + auto inner_fn_inner = [this, &impl] () { + for (auto &item : impl.get_impl_items ()) + visit (item); + }; + + auto inner_fn_outer = [this, &impl, &inner_fn_inner] () { + maybe_insert_big_self (impl); + for (auto &generic : impl.get_generic_params ()) + visit (generic); + if (impl.has_where_clause ()) + visit (impl.get_where_clause ()); + visit (impl.get_type ()); + + ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_inner); + }; + + ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_outer); } void DefaultResolver::visit (AST::TraitImpl &impl) { - auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); }; + visit_outer_attrs (impl); + visit (impl.get_visibility ()); + visit_inner_attrs (impl); + + auto inner_fn_inner = [this, &impl] () { + for (auto &item : impl.get_impl_items ()) + visit (item); + }; + + auto inner_fn_outer = [this, &impl, &inner_fn_inner] () { + maybe_insert_big_self (impl); + for (auto &generic : impl.get_generic_params ()) + visit (generic); + if (impl.has_where_clause ()) + visit (impl.get_where_clause ()); + visit (impl.get_type ()); + visit (impl.get_trait_path ()); + + ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_inner); + }; - ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); + ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_outer); } void diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h index 9b1580165fb..14ada236b7a 100644 --- a/gcc/rust/resolve/rust-default-resolver.h +++ b/gcc/rust/resolve/rust-default-resolver.h @@ -47,6 +47,8 @@ class DefaultResolver : public AST::DefaultASTVisitor void visit (AST::Function &) override; void visit (AST::ForLoopExpr &expr) override; void visit (AST::Trait &) override; + // used to handle Self insertion in TopLevel + virtual void maybe_insert_big_self (AST::Impl &) {} void visit (AST::InherentImpl &) override; void visit (AST::TraitImpl &) override; 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 f46f9e7dd3e..4ed5528c911 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -495,15 +495,16 @@ Late::visit (AST::TypePath &type) if (!resolved.has_value ()) { if (!ctx.lookup (type.get_segments ().front ()->get_node_id ())) - rust_error_at (type.get_locus (), "could not resolve type path %qs", - type.as_string ().c_str ()); + rust_error_at (type.get_locus (), ErrorCode::E0412, + "could not resolve type path %qs", + type.make_debug_string ().c_str ()); return; } if (resolved->is_ambiguous ()) { rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous", - type.as_string ().c_str ()); + type.make_debug_string ().c_str ()); return; } diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h index 3184dea88aa..be7c2172f39 100644 --- a/gcc/rust/resolve/rust-rib.h +++ b/gcc/rust/resolve/rust-rib.h @@ -188,6 +188,8 @@ class Rib * restriction that you cannot `use` items from the Prelude */ Prelude, + /* Generic rib, used to store generics */ + Generics, } kind; static std::string kind_to_string (Rib::Kind kind) diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc index d3ae797655d..ce7ba07e435 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc @@ -141,33 +141,10 @@ TopLevel::visit (AST::Trait &trait) } void -TopLevel::visit (AST::InherentImpl &impl) +TopLevel::maybe_insert_big_self (AST::Impl &impl) { - auto inner_fn = [this, &impl] () { - insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()), - impl.get_type (), Namespace::Types); - - // We do want to visit with the default visitor instead of default resolver - // because we don't want to insert the scope twice. - AST::DefaultASTVisitor::visit (impl); - }; - - ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); -} - -void -TopLevel::visit (AST::TraitImpl &impl) -{ - auto inner_fn = [this, &impl] () { - insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()), - impl.get_type (), Namespace::Types); - - // We do want to visit using the default visitor instead of default resolver - // because we don't want to insert the scope twice. - AST::DefaultASTVisitor::visit (impl); - }; - - ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); + insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()), + impl.get_type (), Namespace::Types); } void diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h index 16e9984876f..657e6b9330b 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h @@ -160,8 +160,7 @@ class TopLevel : public DefaultResolver void visit (AST::Module &module) override; void visit (AST::Trait &trait) override; - void visit (AST::InherentImpl &impl) override; - void visit (AST::TraitImpl &impl) override; + void maybe_insert_big_self (AST::Impl &impl) override; void visit (AST::TraitItemType &trait_item) override; void visit (AST::MacroRulesDefinition ¯o) override; void visit (AST::Function &function) override; diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index d3bdb1cce0d..d7fc1152996 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -10,10 +10,8 @@ derive-default1.rs derive-eq-invalid.rs torture/alt_patterns1.rs torture/name_resolve1.rs -issue-3663.rs issue-3671.rs issue-3652.rs -issue-3649.rs issue-1487.rs issue-2015.rs issue-3454.rs