Skip to content

Commit

Permalink
Resolve path starting with Self with nr2
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* ast/rust-path.h:
	* resolve/rust-forever-stack.h:
	* resolve/rust-forever-stack.hxx:
	* resolve/rust-late-name-resolver-2.0.cc (Late::visit):
	* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
  • Loading branch information
P-E-P committed Jan 29, 2025
1 parent 84bca6f commit c167dc7
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 3 deletions.
5 changes: 5 additions & 0 deletions gcc/rust/ast/rust-path.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ class PathExprSegment
PathIdentSegment &get_ident_segment () { return segment_name; }
const PathIdentSegment &get_ident_segment () const { return segment_name; }

const std::string get_segment_name () const
{
return segment_name.as_string ();
}

NodeId get_node_id () const { return node_id; }

bool is_super_path_seg () const
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/resolve/rust-forever-stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@ template <Namespace N> class ForeverStack
using SegIterator = typename std::vector<S>::const_iterator;

Node &find_closest_module (Node &starting_point);
Node &find_closest_inherent_impl (Node &starting_point);

template <typename S>
tl::optional<SegIterator<S>>
Expand Down
30 changes: 28 additions & 2 deletions gcc/rust/resolve/rust-forever-stack.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,24 @@ ForeverStack<N>::find_closest_module (Node &starting_point)
return *closest_module;
}

template <Namespace N>
typename ForeverStack<N>::Node &
ForeverStack<N>::find_closest_inherent_impl (Node &starting_point)
{
auto *closest_impl = &starting_point;

reverse_iter (starting_point, [&closest_impl] (Node &current) {
if (current.rib.kind == Rib::Kind::TraitOrImpl)
{
closest_impl = &current;
return KeepGoing::No;
}

return KeepGoing::Yes;
});

return *closest_impl;
}
/* If a the given condition is met, emit an error about misused leading path
* segments */
template <typename S>
Expand Down Expand Up @@ -383,7 +401,15 @@ ForeverStack<N>::find_starting_point (
// at the closest module. In order to resolve something like `foo::bar!()`, we
// need to get back to the surrounding module, and look for a child module
// named `foo`.
if (segments.size () > 1)
//
// But if path start with a "Self" we skip it and find the closest inherent
// implementation.
if (segments.size () > 0 && segments[0].as_string () == "Self")
{
starting_point = find_closest_inherent_impl (starting_point);
iterator++;
}
else if (segments.size () > 1)
starting_point = find_closest_module (starting_point);

for (; !is_last (iterator, segments); iterator++)
Expand Down Expand Up @@ -503,7 +529,7 @@ ForeverStack<N>::resolve_path (const std::vector<S> &segments)
return resolve_segments (starting_point.get (), segments, iterator);
})
.and_then ([&segments] (Node final_node) {
return final_node.rib.get (segments.back ().as_string ());
return final_node.rib.get (segments.back ().get_segment_name ());
});
}

Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/resolve/rust-late-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Late::visit (AST::PathInExpression &expr)
{
rust_error_at (expr.get_locus (),
"could not resolve path expression: %qs",
expr.as_simple_path ().as_string ().c_str ());
expr.as_string ().c_str ());
return;
}

Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,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 default visitor instead of default resolver because we don't
// want to insert the scope twice.
AST::DefaultASTVisitor::visit (impl);
};

Expand All @@ -123,6 +125,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 default visitor instead of default resolver because we don't
// want to insert the scope twice.
AST::DefaultASTVisitor::visit (impl);
};

Expand Down

0 comments on commit c167dc7

Please sign in to comment.