aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-early-name-resolver-2.0.cc')
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc47
1 files changed, 44 insertions, 3 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 4fd1dd2..0dff831 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
@@ -447,8 +449,8 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
break;
}
case AST::UseTreeRebind::NewBindType::WILDCARD:
- rust_unreachable ();
- break;
+ // We don't want to insert it into the trie
+ return;
}
for (auto &&definition : data.definitions ())
@@ -459,6 +461,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
void
Early::visit (AST::UseDeclaration &decl)
{
+ // We do not want to visit the use trees, we're only looking for top level
+ // rebind. eg. `use something;` or `use something::other;`
+ if (decl.get_tree ()->get_kind () == AST::UseTree::Kind::Rebind)
+ {
+ auto &rebind = static_cast<AST::UseTreeRebind &> (*decl.get_tree ());
+ if (rebind.get_path ().get_final_segment ().is_lower_self_seg ())
+ {
+ collect_error (
+ Error (decl.get_locus (), ErrorCode::E0429,
+ "%<self%> imports are only allowed within a { } list"));
+ }
+ }
+
auto &imports = toplevel.get_imports_to_resolve ();
auto current_import = imports.find (decl.get_node_id ());
if (current_import != imports.end ())
@@ -484,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