https://gcc.gnu.org/g:229ab5da69292f14f052e7da7b2d83003369197c
commit r16-4827-g229ab5da69292f14f052e7da7b2d83003369197c Author: Pierre-Emmanuel Patry <[email protected]> Date: Tue Aug 26 20:07:05 2025 +0200 gccrs: Error out on unsuffixed self list use declaration gcc/rust/ChangeLog: * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import): Replace assert with early break and remove early return. (Early::visit): Check for unsuffixed lower self list. * resolve/rust-early-name-resolver-2.0.h: Add visit function prototype. gcc/testsuite/ChangeLog: * rust/compile/use_self_alone_in_list.rs: New test. Signed-off-by: Pierre-Emmanuel Patry <[email protected]> Diff: --- gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 31 ++++++++++++++++++++-- gcc/rust/resolve/rust-early-name-resolver-2.0.h | 1 + .../rust/compile/use_self_alone_in_list.rs | 7 +++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc index 6036f474afc6..0dff83153311 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -438,7 +438,9 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping) // We don't want to insert `self` with `use module::self` if (path.get_final_segment ().is_lower_self_seg ()) { - rust_assert (segments.size () > 1); + // Erroneous `self` or `{self}` use declaration + if (segments.size () == 1) + break; declared_name = segments[segments.size () - 2].as_string (); } else @@ -469,7 +471,6 @@ Early::visit (AST::UseDeclaration &decl) collect_error ( Error (decl.get_locus (), ErrorCode::E0429, "%<self%> imports are only allowed within a { } list")); - return; } } @@ -498,5 +499,31 @@ Early::visit (AST::UseDeclaration &decl) DefaultResolver::visit (decl); } +void +Early::visit (AST::UseTreeList &use_list) +{ + if (!use_list.has_path ()) + { + for (auto &&tree : use_list.get_trees ()) + { + if (tree->get_kind () == AST::UseTree::Kind::Rebind) + { + auto &rebind = static_cast<AST::UseTreeRebind &> (*tree); + auto path_size = rebind.get_path ().get_segments ().size (); + if (path_size == 1 + && rebind.get_path () + .get_final_segment () + .is_lower_self_seg ()) + { + collect_error (Error (rebind.get_locus (), ErrorCode::E0431, + "%<self%> import can only appear in an " + "import list with a non-empty prefix")); + } + } + } + } + DefaultResolver::visit (use_list); +} + } // namespace Resolver2_0 } // namespace Rust diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h b/gcc/rust/resolve/rust-early-name-resolver-2.0.h index 960de0e4c791..39403866b832 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h @@ -61,6 +61,7 @@ public: void visit (AST::Function &) override; void visit (AST::StructStruct &) override; void visit (AST::UseDeclaration &) override; + void visit (AST::UseTreeList &) override; struct ImportData { diff --git a/gcc/testsuite/rust/compile/use_self_alone_in_list.rs b/gcc/testsuite/rust/compile/use_self_alone_in_list.rs new file mode 100644 index 000000000000..2e8722721b2f --- /dev/null +++ b/gcc/testsuite/rust/compile/use_self_alone_in_list.rs @@ -0,0 +1,7 @@ +struct B; + +use {B as B2, self}; +// { dg-error ".self. import can only appear in an import list with a non-empty prefix" "" { target *-*-* } .-1 } + +use {self}; +// { dg-error ".self. import can only appear in an import list with a non-empty prefix" "" { target *-*-* } .-1 }
