aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc')
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc86
1 files changed, 69 insertions, 17 deletions
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 4c6664f..2f036fe 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -32,21 +32,18 @@ TopLevel::TopLevel (NameResolutionContext &resolver)
template <typename T>
void
-TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
- Namespace ns)
+TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
+ const T &node)
{
- insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
+ insert_enum_variant_or_error_out (identifier, node.get_locus (),
+ node.get_node_id ());
}
void
-TopLevel::insert_or_error_out (const Identifier &identifier,
- const location_t &locus, const NodeId &node_id,
- Namespace ns)
+TopLevel::check_multiple_insertion_error (
+ tl::expected<NodeId, DuplicateNameError> result, const Identifier &identifier,
+ const location_t &locus, const NodeId node_id)
{
- // keep track of each node's location to provide useful errors
- node_locations.emplace (node_id, locus);
-
- auto result = ctx.insert (identifier, node_id, ns);
if (result)
dirty = true;
else if (result.error ().existing != node_id)
@@ -58,6 +55,37 @@ TopLevel::insert_or_error_out (const Identifier &identifier,
identifier.as_string ().c_str ());
}
}
+void
+TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
+ const location_t &locus,
+ const NodeId node_id)
+{
+ // keep track of each node's location to provide useful errors
+ node_locations.emplace (node_id, locus);
+
+ auto result = ctx.insert_variant (identifier, node_id);
+ check_multiple_insertion_error (result, identifier, locus, node_id);
+}
+
+template <typename T>
+void
+TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
+ Namespace ns)
+{
+ insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
+}
+
+void
+TopLevel::insert_or_error_out (const Identifier &identifier,
+ const location_t &locus, const NodeId &node_id,
+ Namespace ns)
+{
+ // keep track of each node's location to provide useful errors
+ node_locations.emplace (node_id, locus);
+
+ auto result = ctx.insert (identifier, node_id, ns);
+ check_multiple_insertion_error (result, identifier, locus, node_id);
+}
void
TopLevel::go (AST::Crate &crate)
@@ -85,7 +113,17 @@ TopLevel::visit (AST::Module &module)
// This was copied from the old early resolver method
// 'accumulate_escaped_macros'
if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
+ {
+ module.load_items ();
+
+ // If the module was previously unloaded, then we don't want to visit it
+ // this time around as the CfgStrip hasn't run on its inner items yet.
+ // Skip it for now, mark the visitor as dirty and try again
+
+ dirty = true;
+
+ return;
+ }
DefaultResolver::visit (module);
@@ -97,8 +135,7 @@ TopLevel::visit (AST::Module &module)
void
TopLevel::visit (AST::Trait &trait)
{
- insert_or_error_out (trait.get_identifier ().as_string (), trait,
- Namespace::Types);
+ insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
DefaultResolver::visit (trait);
}
@@ -110,6 +147,8 @@ TopLevel::visit (AST::InherentImpl &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);
};
@@ -123,6 +162,8 @@ TopLevel::visit (AST::TraitImpl &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);
};
@@ -159,7 +200,16 @@ void
TopLevel::visit (AST::ExternCrate &crate)
{
auto &mappings = Analysis::Mappings::get ();
- CrateNum num = *mappings.lookup_crate_name (crate.get_referenced_crate ());
+ auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
+
+ if (!num_opt)
+ {
+ rust_error_at (crate.get_locus (), "unknown crate %qs",
+ crate.get_referenced_crate ().c_str ());
+ return;
+ }
+
+ CrateNum num = *num_opt;
auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
@@ -323,19 +373,19 @@ TopLevel::visit (AST::TupleStruct &tuple_struct)
void
TopLevel::visit (AST::EnumItem &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
TopLevel::visit (AST::EnumItemTuple &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
TopLevel::visit (AST::EnumItemStruct &variant)
{
- insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+ insert_enum_variant_or_error_out (variant.get_identifier (), variant);
}
void
@@ -497,6 +547,8 @@ flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
{
if (glob.has_path ())
paths.emplace_back (glob.get_path ());
+ else
+ paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
}
void