aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2025-01-04 14:59:54 -0500
committerCohenArthur <arthur.cohen@embecosm.com>2025-02-03 11:44:49 +0000
commit668c3bf7b7b45f8cea7a09515b6420cece877881 (patch)
tree2d7394f4c305d28719615b6d84293337b388fbb9 /gcc
parenta4a3183322dc195b3f235618d28ddca3e320a5fa (diff)
downloadgcc-668c3bf7b7b45f8cea7a09515b6420cece877881.zip
gcc-668c3bf7b7b45f8cea7a09515b6420cece877881.tar.gz
gcc-668c3bf7b7b45f8cea7a09515b6420cece877881.tar.bz2
Fix bug in type resolution of paths
gcc/rust/ChangeLog: * resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import): Use NameResolutionContext::resolve_path instead of ForeverStack::resolve_path. (Early::visit): Likewise. (Early::visit_attributes): Likewise. * resolve/rust-early-name-resolver-2.0.h (Early::resolve_path_in_all_ns): Likewise. * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise, insert segment resolutions not handled by NameResolutionContext::resolve_path, and avoid throwing an error when path resolution could be finished by the typechecker. * resolve/rust-name-resolution-context.h (NameResolutionContext::resolve_path): Add. * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): Use segment node ids instead of the path node id to look up segment resolutions when using the 2.0 resolver, as is done with the 1.0 resolver. * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): Likewise. * resolve/rust-forever-stack.h (ForeverStack::resolve_path): Add callback parameter for inserting segment resolutions. (ForeverStack::find_starting_point): Likewise. (ForeverStack::resolve_segments): Likewise. * resolve/rust-forever-stack.hxx (ForeverStack::find_starting_point): Likewise. (ForeverStack::resolve_segments): Likewise. (ForeverStack::resolve_path): Likewise and avoid resolving inside TraitOrImpl ribs. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: Remove entries. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc13
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h9
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h18
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx48
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc36
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h40
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc5
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc2
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude29
9 files changed, 128 insertions, 72 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 ae02a17..cdd8d16 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -74,7 +74,8 @@ Early::go (AST::Crate &crate)
bool
Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
{
- auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
+ auto resolved
+ = ctx.resolve_path (glob.to_resolve.get_segments (), Namespace::Types);
if (!resolved.has_value ())
return false;
@@ -259,7 +260,7 @@ Early::visit (AST::MacroInvocation &invoc)
// we won't have changed `definition` from `nullopt` if there are more
// than one segments in our path
if (!definition.has_value ())
- definition = ctx.macros.resolve_path (path.get_segments ());
+ definition = ctx.resolve_path (path.get_segments (), Namespace::Macros);
// if the definition still does not have a value, then it's an error
if (!definition.has_value ())
@@ -300,8 +301,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto traits = attr.get_traits_to_derive ();
for (auto &trait : traits)
{
- auto definition
- = ctx.macros.resolve_path (trait.get ().get_segments ());
+ auto definition = ctx.resolve_path (trait.get ().get_segments (),
+ Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
@@ -324,8 +325,8 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
->lookup_builtin (name)
.is_error ()) // Do not resolve builtins
{
- auto definition
- = ctx.macros.resolve_path (attr.get_path ().get_segments ());
+ auto definition = ctx.resolve_path (attr.get_path ().get_segments (),
+ Namespace::Macros);
if (!definition.has_value ())
{
// FIXME: Change to proper error message
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 dd199cc..de14d3c 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -227,9 +227,12 @@ private:
};
};
- ctx.values.resolve_path (segments).map (pair_with_ns (Namespace::Values));
- ctx.types.resolve_path (segments).map (pair_with_ns (Namespace::Types));
- ctx.macros.resolve_path (segments).map (pair_with_ns (Namespace::Macros));
+ ctx.resolve_path (segments, Namespace::Values)
+ .map (pair_with_ns (Namespace::Values));
+ ctx.resolve_path (segments, Namespace::Types)
+ .map (pair_with_ns (Namespace::Types));
+ ctx.resolve_path (segments, Namespace::Macros)
+ .map (pair_with_ns (Namespace::Macros));
return resolved;
}
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 278c1a8..7bfe651 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -661,7 +661,9 @@ public:
* current map, an empty one otherwise.
*/
template <typename S>
- tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments);
+ tl::optional<Rib::Definition> resolve_path (
+ const std::vector<S> &segments,
+ std::function<void (const S &, NodeId)> insert_segment_resolution);
// FIXME: Documentation
tl::optional<Resolver::CanonicalPath> to_canonical_path (NodeId id) const;
@@ -764,14 +766,16 @@ private:
Node &find_closest_module (Node &starting_point);
template <typename S>
- tl::optional<SegIterator<S>>
- find_starting_point (const std::vector<S> &segments,
- std::reference_wrapper<Node> &starting_point);
+ tl::optional<SegIterator<S>> find_starting_point (
+ const std::vector<S> &segments,
+ std::reference_wrapper<Node> &starting_point,
+ std::function<void (const S &, NodeId)> insert_segment_resolution);
template <typename S>
- tl::optional<Node &> resolve_segments (Node &starting_point,
- const std::vector<S> &segments,
- SegIterator<S> iterator);
+ tl::optional<Node &> resolve_segments (
+ Node &starting_point, const std::vector<S> &segments,
+ SegIterator<S> iterator,
+ std::function<void (const S &, NodeId)> insert_segment_resolution);
/* Helper functions for forward resolution (to_canonical_path, to_rib...) */
struct DfsResult
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index be05f52..57bd0bb 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -375,7 +375,8 @@ template <Namespace N>
template <typename S>
tl::optional<typename std::vector<S>::const_iterator>
ForeverStack<N>::find_starting_point (
- const std::vector<S> &segments, std::reference_wrapper<Node> &starting_point)
+ const std::vector<S> &segments, std::reference_wrapper<Node> &starting_point,
+ std::function<void (const S &, NodeId)> insert_segment_resolution)
{
auto iterator = segments.begin ();
@@ -401,12 +402,19 @@ ForeverStack<N>::find_starting_point (
if (seg.is_crate_path_seg ())
{
starting_point = root;
+ // TODO: is this how we should be getting the crate node id?
+ auto &mappings = Analysis::Mappings::get ();
+ NodeId current_crate
+ = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
+
+ insert_segment_resolution (seg, current_crate);
iterator++;
break;
}
if (seg.is_lower_self_seg ())
{
- // do nothing and exit
+ // insert segment resolution and exit
+ insert_segment_resolution (seg, starting_point.get ().id);
iterator++;
break;
}
@@ -421,6 +429,8 @@ ForeverStack<N>::find_starting_point (
starting_point
= find_closest_module (starting_point.get ().parent.value ());
+
+ insert_segment_resolution (seg, starting_point.get ().id);
continue;
}
@@ -438,7 +448,8 @@ template <typename S>
tl::optional<typename ForeverStack<N>::Node &>
ForeverStack<N>::resolve_segments (
Node &starting_point, const std::vector<S> &segments,
- typename std::vector<S>::const_iterator iterator)
+ typename std::vector<S>::const_iterator iterator,
+ std::function<void (const S &, NodeId)> insert_segment_resolution)
{
auto *current_node = &starting_point;
for (; !is_last (iterator, segments); iterator++)
@@ -479,6 +490,7 @@ ForeverStack<N>::resolve_segments (
}
current_node = &child.value ();
+ insert_segment_resolution (seg, current_node->id);
}
return *current_node;
@@ -487,23 +499,39 @@ ForeverStack<N>::resolve_segments (
template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
-ForeverStack<N>::resolve_path (const std::vector<S> &segments)
+ForeverStack<N>::resolve_path (
+ const std::vector<S> &segments,
+ std::function<void (const S &, NodeId)> insert_segment_resolution)
{
// TODO: What to do if segments.empty() ?
// if there's only one segment, we just use `get`
if (segments.size () == 1)
- return get (segments.back ().as_string ());
+ {
+ auto res = get (segments.back ().as_string ());
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+ return res;
+ }
std::reference_wrapper<Node> starting_point = cursor ();
- return find_starting_point (segments, starting_point)
- .and_then ([this, &segments, &starting_point] (
+ return find_starting_point (segments, starting_point,
+ insert_segment_resolution)
+ .and_then ([this, &segments, &starting_point, &insert_segment_resolution] (
typename std::vector<S>::const_iterator iterator) {
- return resolve_segments (starting_point.get (), segments, iterator);
+ return resolve_segments (starting_point.get (), segments, iterator,
+ insert_segment_resolution);
})
- .and_then ([&segments] (Node final_node) {
- return final_node.rib.get (segments.back ().as_string ());
+ .and_then ([&segments, &insert_segment_resolution] (
+ Node final_node) -> tl::optional<Rib::Definition> {
+ // leave resolution within impl blocks to type checker
+ if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
+ return tl::nullopt;
+ auto res = final_node.rib.get (segments.back ().as_string ());
+ if (res && !res->is_ambiguous ())
+ insert_segment_resolution (segments.back (), res->get_node_id ());
+ return res;
});
}
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index a0c3a05..8ed3053 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -263,16 +263,15 @@ Late::visit (AST::PathInExpression &expr)
return;
}
- auto resolved
- = ctx.values.resolve_path (expr.get_segments ()).or_else ([&] () {
- return ctx.types.resolve_path (expr.get_segments ());
- });
+ auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values,
+ Namespace::Types);
if (!resolved)
{
- rust_error_at (expr.get_locus (),
- "could not resolve path expression: %qs",
- expr.as_simple_path ().as_string ().c_str ());
+ if (!ctx.lookup (expr.get_segments ().front ().get_node_id ()))
+ rust_error_at (expr.get_locus (),
+ "could not resolve path expression: %qs",
+ expr.as_simple_path ().as_string ().c_str ());
return;
}
@@ -307,11 +306,17 @@ Late::visit (AST::TypePath &type)
auto values = ctx.types.peek ().get_values ();
if (auto resolved = ctx.types.get (str))
- ctx.map_usage (Usage (type.get_node_id ()),
- Definition (resolved->get_node_id ()));
+ {
+ ctx.map_usage (Usage (type.get_node_id ()),
+ Definition (resolved->get_node_id ()));
+ ctx.map_usage (Usage (type.get_segments ().back ()->get_node_id ()),
+ Definition (resolved->get_node_id ()));
+ }
else
- rust_error_at (type.get_locus (), "could not resolve type path %qs",
- str.c_str ());
+ {
+ rust_error_at (type.get_locus (), "could not resolve type path %qs",
+ str.c_str ());
+ }
DefaultResolver::visit (type);
}
@@ -339,7 +344,8 @@ Late::visit (AST::StructStruct &s)
void
Late::visit (AST::StructExprStruct &s)
{
- auto resolved = ctx.types.resolve_path (s.get_struct_name ().get_segments ());
+ auto resolved
+ = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
@@ -348,7 +354,8 @@ Late::visit (AST::StructExprStruct &s)
void
Late::visit (AST::StructExprStructBase &s)
{
- auto resolved = ctx.types.resolve_path (s.get_struct_name ().get_segments ());
+ auto resolved
+ = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
@@ -358,7 +365,8 @@ Late::visit (AST::StructExprStructBase &s)
void
Late::visit (AST::StructExprStructFields &s)
{
- auto resolved = ctx.types.resolve_path (s.get_struct_name ().get_segments ());
+ auto resolved
+ = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
Definition (resolved->get_node_id ()));
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index 44d7da7..bd03ff9 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -216,6 +216,46 @@ public:
tl::optional<NodeId> lookup (NodeId usage) const;
+ template <typename S>
+ tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ Namespace ns)
+ {
+ std::function<void (const S &, NodeId)> insert_segment_resolution
+ = [this] (const S &seg, NodeId id) {
+ if (resolved_nodes.find (Usage (seg.get_node_id ()))
+ == resolved_nodes.end ())
+ map_usage (Usage (seg.get_node_id ()), Definition (id));
+ };
+ switch (ns)
+ {
+ case Namespace::Values:
+ return values.resolve_path (segments, insert_segment_resolution);
+ case Namespace::Types:
+ return types.resolve_path (segments, insert_segment_resolution);
+ case Namespace::Macros:
+ return macros.resolve_path (segments, insert_segment_resolution);
+ case Namespace::Labels:
+ return labels.resolve_path (segments, insert_segment_resolution);
+ default:
+ rust_unreachable ();
+ }
+ }
+
+ template <typename S, typename... Args>
+ tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
+ Args... ns_args)
+ {
+ std::initializer_list<Namespace> namespaces = {ns_args...};
+
+ for (auto ns : namespaces)
+ {
+ if (auto ret = resolve_path (segments, ns))
+ return ret;
+ }
+
+ return tl::nullopt;
+ }
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index a489490..a4f294b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -274,8 +274,9 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
// assign the ref_node_id if we've found something
- nr_ctx.lookup (expr.get_mappings ().get_nodeid ())
- .map ([&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
+ ref_node_id = resolved;
+ });
}
else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 55c5934..6dc62d6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -403,7 +403,7 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
.resolver ();
// assign the ref_node_id if we've found something
- nr_ctx.lookup (path.get_mappings ().get_nodeid ())
+ nr_ctx.lookup (ast_node_id)
.map (
[&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index acb4334..29d6e21 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -14,14 +14,11 @@ feature_rust_attri0.rs
format_args_basic_expansion.rs
generic-default1.rs
generics1.rs
-generics10.rs
-generics11.rs
generics3.rs
generics4.rs
generics5.rs
generics6.rs
generics9.rs
-if_let_expr.rs
issue-1130.rs
issue-1173.rs
issue-1272.rs
@@ -45,26 +42,16 @@ issue-2775.rs
issue-2782.rs
issue-2812.rs
issue-850.rs
-issue-852.rs
issue-855.rs
iterators1.rs
lookup_err1.rs
macros/mbe/macro20.rs
-macros/mbe/macro23.rs
macros/mbe/macro40.rs
macros/mbe/macro43.rs
macros/mbe/macro44.rs
macros/mbe/macro54.rs
macros/mbe/macro6.rs
macros/mbe/macro_use1.rs
-match-never-ltype.rs
-match-never-rtype.rs
-match1.rs
-match2.rs
-match3.rs
-match4.rs
-match5.rs
-match9.rs
method2.rs
multiple_bindings1.rs
multiple_bindings2.rs
@@ -72,11 +59,7 @@ nested_macro_use1.rs
nested_macro_use2.rs
nested_macro_use3.rs
not_find_value_in_scope.rs
-parse_associated_type_as_generic_arg.rs
-parse_associated_type_as_generic_arg2.rs
-parse_associated_type_as_generic_arg3.rs
parse_complex_generic_application.rs
-parse_complex_generic_application2.rs
path_as_generic_arg.rs
pattern-struct.rs
privacy4.rs
@@ -89,7 +72,6 @@ pub_restricted_1.rs
pub_restricted_2.rs
pub_restricted_3.rs
redef_error2.rs
-redef_error4.rs
redef_error5.rs
self-path1.rs
self-path2.rs
@@ -99,23 +81,15 @@ traits3.rs
traits6.rs
traits7.rs
type-bindings1.rs
-unconstrained_type_param.rs
undeclared_label.rs
use_1.rs
v0-mangle1.rs
v0-mangle2.rs
while_break_expr.rs
-exhaustiveness1.rs
exhaustiveness2.rs
-exhaustiveness3.rs
-issue-2324-1.rs
-issue-2324-2.rs
-issue-3046.rs
issue-3139-2.rs
issue-3032-1.rs
issue-3032-2.rs
-# https://github.com/Rust-GCC/gccrs/issues/3189
-if_let_expr_simple.rs
iflet.rs
issue-3033.rs
issue-3009.rs
@@ -126,8 +100,6 @@ issue-2907.rs
issue-2423.rs
issue-266.rs
additional-trait-bounds2.rs
-issue-3140.rs
-cmp1.rs
derive_clone_enum1.rs
derive_clone_enum2.rs
derive_clone_enum3.rs
@@ -150,6 +122,5 @@ issue-2953-1.rs
issue-3030.rs
traits12.rs
try-trait.rs
-issue-3174.rs
derive-debug1.rs
# please don't delete the trailing newline