From: Enes Cevik <[email protected]>
This patch fixes multiple ICEs and test failures in the Name Resolution 2.0
- Map directly to definition IDs instead of intermediate import IDs.
- Remove redundant `flatten()` calls. Flattening stripped generic arguments
from aliases like `Self`, causing typecheck errors.
- Prevent ICEs on invalid `use self;` imports by adding early returns.
- Add `Namespace::Types` to pattern lookups to correctly emit E0532 instead
of crashing.
- Remove an unsafe debug loop in `Rib::get` that caused ICEs on ambiguous
names.
- Use `value_or` for safe optional unwrapping in module resolution.
gcc/rust/ChangeLog:
* checks/lints/rust-lint-marklive.cc (MarkLive::visit_path_segment):
Add Types namespace
lookup.
* checks/lints/unused/rust-unused-checker.cc (UnusedChecker::visit):
Use safe optional
unwrapping.
* checks/lints/unused/rust-unused-collector.cc
(UnusedCollector::visit): Likewise.
* checks/lints/unused/rust-unused-collector.h: Use helper for multiple
namespace lookups.
* resolve/rust-early-name-resolver-2.0.cc
(Early::finalize_simple_import): Prevent ICE on
single self imports.
(Early::finalize_rebind_import): Return early to prevent ICE.
* resolve/rust-name-resolution-context.hxx: Use value_or for safe leaf
module lookup.
* rust-session-manager.cc (Session::compile_crate): Remove obsolete
flatten() calls.
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit):
Look up enum variants
in Types namespace.
Signed-off-by: Enes Cevik <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/83aefd6ad71221c6fb492b21635e482a476a03d1
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4551
gcc/rust/checks/lints/rust-lint-marklive.cc | 7 ++-
.../lints/unused/rust-unused-checker.cc | 22 +++++----
.../lints/unused/rust-unused-collector.cc | 11 +++--
.../lints/unused/rust-unused-collector.h | 48 +++++++++++++++----
.../resolve/rust-early-name-resolver-2.0.cc | 8 ++--
.../resolve/rust-name-resolution-context.hxx | 15 ++++--
gcc/rust/rust-session-manager.cc | 6 ---
.../typecheck/rust-hir-type-check-pattern.cc | 8 ++--
8 files changed, 84 insertions(+), 41 deletions(-)
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 3998cb70f..8fc81b363 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -165,8 +165,11 @@ MarkLive::visit_path_segment (HIR::PathExprSegment seg)
// We should mark them alive all and ignoring other kind of segments.
// If the segment we dont care then just return false is fine
// TODO: Should we look that up in all namespaces?
- if (auto id = resolver.lookup (ast_node_id, Resolver2_0::Namespace::Values))
- ref_node_id = *id;
+
+ if (auto nslookup
+ = resolver.lookup (ast_node_id, Resolver2_0::Namespace::Values,
+ Resolver2_0::Namespace::Types))
+ ref_node_id = nslookup->id;
else
return false;
if (auto hid = mappings.lookup_node_to_hir (ref_node_id))
diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
index 06bbfd446..571e31e43 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -105,21 +105,25 @@ UnusedChecker::visit (HIR::IdentifierPattern &pattern)
"variable %qs should have a snake case name",
var_name.c_str ());
}
-void
+void
UnusedChecker::visit (HIR::AssignmentExpr &expr)
-
{
const auto &lhs = expr.get_lhs ();
auto var_name = lhs.to_string ();
NodeId ast_node_id = lhs.get_mappings ().get_nodeid ();
- NodeId def_id
- = nr_context.lookup (ast_node_id, Resolver2_0::Namespace::Values).value ();
- HirId id = mappings.lookup_node_to_hir (def_id).value ();
- if (unused_context.is_variable_assigned (id, lhs.get_mappings ().get_hirid
())
- && var_name[0] != '_')
- rust_warning_at (lhs.get_locus (), OPT_Wunused_variable,
- "unused assignment %qs", var_name.c_str ());
+ if (auto def_id
+ = nr_context.lookup (ast_node_id, Resolver2_0::Namespace::Values))
+ {
+ if (auto id = mappings.lookup_node_to_hir (*def_id))
+ {
+ if (unused_context.is_variable_assigned (
+ *id, lhs.get_mappings ().get_hirid ())
+ && var_name[0] != '_')
+ rust_warning_at (lhs.get_locus (), OPT_Wunused_variable,
+ "unused assignment %qs", var_name.c_str ());
+ }
+ }
}
void
diff --git a/gcc/rust/checks/lints/unused/rust-unused-collector.cc
b/gcc/rust/checks/lints/unused/rust-unused-collector.cc
index 5596dd97a..96920efb9 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-collector.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-collector.cc
@@ -62,10 +62,13 @@ UnusedCollector::visit (HIR::StructExprFieldIdentifier
&ident)
void
UnusedCollector::visit (HIR::AssignmentExpr &expr)
{
- auto def_id = get_def_id (expr.get_lhs (), Resolver2_0::Namespace::Values);
- HirId id = expr.get_lhs ().get_mappings ().get_hirid ();
- unused_context.remove_mut (def_id);
- unused_context.add_assign (def_id, id);
+ if (auto def_id
+ = get_def_id (expr.get_lhs (), Resolver2_0::Namespace::Values))
+ {
+ HirId id = expr.get_lhs ().get_mappings ().get_hirid ();
+ unused_context.remove_mut (*def_id);
+ unused_context.add_assign (*def_id, id);
+ }
visit_outer_attrs (expr);
expr.get_rhs ().accept_vis (*this);
}
diff --git a/gcc/rust/checks/lints/unused/rust-unused-collector.h
b/gcc/rust/checks/lints/unused/rust-unused-collector.h
index 5059f7689..a506bff80 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-collector.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-collector.h
@@ -57,25 +57,55 @@ private:
virtual void visit (HIR::ContinueExpr &expr) override;
template <typename T>
- HirId get_def_id (T &path_expr, Resolver2_0::Namespace ns)
+ tl::optional<HirId> get_def_id (T &path_expr, Resolver2_0::Namespace ns)
{
NodeId ast_node_id = path_expr.get_mappings ().get_nodeid ();
- NodeId id = nr_context.lookup (ast_node_id, ns).value ();
- HirId def_id = mappings.lookup_node_to_hir (id).value ();
- return def_id;
+
+ if (auto id = nr_context.lookup (ast_node_id, ns))
+ {
+ if (auto def_id = mappings.lookup_node_to_hir (*id))
+ {
+ return *def_id;
+ }
+ }
+ return tl::nullopt;
+ }
+
+ template <typename T>
+ tl::optional<HirId> get_def_id (T &path_expr, Resolver2_0::Namespace ns1,
+ Resolver2_0::Namespace ns2)
+ {
+ NodeId ast_node_id = path_expr.get_mappings ().get_nodeid ();
+
+ if (auto nslookup = nr_context.lookup (ast_node_id, ns1, ns2))
+ {
+ NodeId id = nslookup->id;
+
+ if (auto def_id = mappings.lookup_node_to_hir (id))
+ {
+ return *def_id;
+ }
+ }
+
+ return tl::nullopt;
}
template <typename T> void mark_path_used (T &path_expr)
{
- auto def_id = get_def_id (path_expr, Resolver2_0::Namespace::Values);
- unused_context.add_variable (def_id);
- unused_context.remove_assign (def_id);
+ if (auto def_id = get_def_id (path_expr, Resolver2_0::Namespace::Values,
+ Resolver2_0::Namespace::Types))
+ {
+ unused_context.add_variable (*def_id);
+ unused_context.remove_assign (*def_id);
+ }
}
template <typename T> void mark_label_used (T &path_expr)
{
- auto def_id = get_def_id (path_expr, Resolver2_0::Namespace::Labels);
- unused_context.add_label (def_id);
+ if (auto def_id = get_def_id (path_expr, Resolver2_0::Namespace::Labels))
+ {
+ unused_context.add_label (*def_id);
+ }
}
};
} // namespace Analysis
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 148385300..1d63b6392 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -467,7 +467,8 @@ Early::finalize_simple_import (const Early::ImportPair
&mapping)
Definition (definition.definition.get_node_id ()),
definition.ns);
- toplevel.insert_or_error_out (identifier, import.get_locus (), import_id,
+ toplevel.insert_or_error_out (identifier, import.get_locus (),
+ definition.definition.get_node_id (),
definition.ns);
dirty = dirty || toplevel.is_dirty ();
@@ -523,7 +524,7 @@ Early::finalize_rebind_import (const Early::ImportPair
&mapping)
{
// Erroneous `self` or `{self}` use declaration
if (segments.size () == 1)
- break;
+ return;
declared_name = segments[segments.size () - 2].as_string ();
import_id = segments[segments.size () - 2].get_node_id ();
}
@@ -548,7 +549,8 @@ Early::finalize_rebind_import (const Early::ImportPair
&mapping)
Definition (definition.definition.get_node_id ()),
definition.ns);
- toplevel.insert_or_error_out (declared_name, path.get_locus (),
import_id,
+ toplevel.insert_or_error_out (declared_name, path.get_locus (),
+ definition.definition.get_node_id (),
definition.ns);
dirty = dirty || toplevel.is_dirty ();
diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx
b/gcc/rust/resolve/rust-name-resolution-context.hxx
index c16bae874..359dd9c65 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.hxx
+++ b/gcc/rust/resolve/rust-name-resolution-context.hxx
@@ -353,13 +353,20 @@ NameResolutionContext::resolve_segments (
.lookup_glob_container (rib_lookup->get_node_id ())
.has_value ())
{
- auto leaf_module
+ NodeId leaf_module
= stack.find_leaf_definition (rib_lookup->get_node_id ())
- .value ()
+ .value_or (Definition (rib_lookup->get_node_id ()))
.id;
- child = stack.dfs_node (stack.root, leaf_module).value ();
- break;
+ if (auto new_child = stack.dfs_node (stack.root, leaf_module))
+ {
+ child = new_child.value ();
+ break;
+ }
+ else
+ {
+ return tl::nullopt;
+ }
}
else
{
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index b3bc99249..5eda91da9 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -764,15 +764,9 @@ Session::compile_crate (const char *filename)
if (last_step == CompileOptions::CompileStep::NameResolution)
return;
- // FIXME: Or run it within Late at the end?
- name_resolution_ctx.flatten ();
-
// resolution pipeline stage
Resolver2_0::Late (name_resolution_ctx).go (parsed_crate);
- // FIXME: Or run it within Late at the end?
- name_resolution_ctx.flatten ();
-
if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
dump_name_resolution (name_resolution_ctx);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 8c99790f4..7d12bc7b4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -57,11 +57,11 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
- // FIXME: Not sure if this is enough to look up enum variants
- if (auto id = nr_ctx.lookup (pattern.get_mappings ().get_nodeid (),
- Resolver2_0::Namespace::Values))
+ if (auto nslookup = nr_ctx.lookup (pattern.get_mappings ().get_nodeid (),
+ Resolver2_0::Namespace::Values,
+ Resolver2_0::Namespace::Types))
{
- ref_node_id = *id;
+ ref_node_id = nslookup->id;
maybe_item = true;
}
--
2.54.0