From: Pierre-Emmanuel Patry <[email protected]>
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]>
---
.../resolve/rust-early-name-resolver-2.0.cc | 31 +++++++++++++++++--
.../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(-)
create mode 100644 gcc/testsuite/rust/compile/use_self_alone_in_list.rs
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 6036f474afc..0dff8315331 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 960de0e4c79..39403866b83 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 00000000000..2e8722721b2
--- /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 }
--
2.50.1