Skip to content

Commit

Permalink
Resolve instances of TypePath more accurately
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* resolve/rust-forever-stack.hxx
	(unwrap_type_segment): Add.
	(unwrap_type_segment_inner): Add.
	(ForeverStack::find_starting_point): Use unwrap_type_segment.
	(ForeverStack::resolve_segments): Likewise.
	(ForeverStack::resolve_path): Likewise.
	* resolve/rust-late-name-resolver-2.0.cc
	(Late::visit): Resolve TypePath using ForeverStack::resolve_path.

gcc/testsuite/ChangeLog:

	* rust/compile/nr2/exclude: Remove complex-path1.rs.

Signed-off-by: Owen Avery <[email protected]>
  • Loading branch information
powerboat9 committed Oct 28, 2024
1 parent 4564a4f commit 2bcb4fc
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
69 changes: 65 additions & 4 deletions gcc/rust/resolve/rust-forever-stack.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,66 @@ check_leading_kw_at_start (const S &segment, bool condition)
return condition;
}

/*
* Used to convert different path segment object references
* into SimplePathSegment/PathIdentSegment references
*
* unwrap_type_segment:
* expands to a call to unwrap_type_segment_inner::unwrap,
* used for type inference
*/
#define unwrap_type_segment(x) \
(unwrap_type_segment_inner<typename std::remove_const< \
typename std::remove_reference<decltype (x)>::type>::type>::unwrap (x))

template <class T> class unwrap_type_segment_inner;

/* base case */
template <> class unwrap_type_segment_inner<AST::SimplePathSegment>
{
public:
/* The return type of unwrap */
using ret = AST::SimplePathSegment;

/* non-const qualified unwrap */
static AST::SimplePathSegment &unwrap (AST::SimplePathSegment &x)
{
return x;
}

/* const qualified unwrap */
static const AST::SimplePathSegment &unwrap (const AST::SimplePathSegment &x)
{
return x;
}
};

/* case which dereferences unique_ptr */
template <class T> class unwrap_type_segment_inner<std::unique_ptr<T>>
{
public:
using ret = typename unwrap_type_segment_inner<T>::ret;

static ret &unwrap (std::unique_ptr<T> &x)
{
return unwrap_type_segment (*x);
}
static const ret &unwrap (const std::unique_ptr<T> &x)
{
return unwrap_type_segment (*x);
}
};

/* case which handles objects with a get_ident_segment member function */
template <class T> class unwrap_type_segment_inner
{
public:
using ret = AST::PathIdentSegment;

static ret &unwrap (T &x) { return x.get_ident_segment (); }
static const ret &unwrap (const T &x) { return x.get_ident_segment (); }
};

// we first need to handle the "starting" segments - `super`, `self` or
// `crate`. we don't need to do anything for `self` and can just skip it. for
// `crate`, we need to go back to the root of the current stack. for each
Expand All @@ -387,7 +447,7 @@ ForeverStack<N>::find_starting_point (const std::vector<S> &segments,

for (; !is_last (iterator, segments); iterator++)
{
auto &seg = *iterator;
auto &seg = unwrap_type_segment (*iterator);
auto is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();

Expand Down Expand Up @@ -441,7 +501,7 @@ ForeverStack<N>::resolve_segments (
auto *current_node = &starting_point;
for (; !is_last (iterator, segments); iterator++)
{
auto &seg = *iterator;
auto &seg = unwrap_type_segment (*iterator);
auto str = seg.as_string ();
rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());

Expand Down Expand Up @@ -491,7 +551,7 @@ ForeverStack<N>::resolve_path (const std::vector<S> &segments)

// if there's only one segment, we just use `get`
if (segments.size () == 1)
return get (segments.back ().as_string ());
return get (unwrap_type_segment (segments.back ()).as_string ());

auto starting_point = cursor ();

Expand All @@ -501,7 +561,8 @@ ForeverStack<N>::resolve_path (const std::vector<S> &segments)
return resolve_segments (starting_point, segments, iterator);
})
.and_then ([&segments] (Node final_node) {
return final_node.rib.get (segments.back ().as_string ());
return final_node.rib.get (
unwrap_type_segment (segments.back ()).as_string ());
});
}

Expand Down
11 changes: 8 additions & 3 deletions gcc/rust/resolve/rust-late-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,15 @@ Late::visit (AST::TypePath &type)
// maybe we can overload `resolve_path<Namespace::Types>` to only do
// typepath-like path resolution? that sounds good

auto str = type.get_segments ().back ()->get_ident_segment ().as_string ();
auto values = ctx.types.peek ().get_values ();
// take care of only simple cases
// TODO: remove this?
rust_assert (!type.has_opening_scope_resolution_op ());

if (auto resolved = ctx.types.get (str))
// this *should* mostly work
// TODO: make sure typepath-like path resolution (?) is working
auto resolved = ctx.types.resolve_path (type.get_segments ());

if (resolved.has_value ())
ctx.map_usage (Usage (type.get_node_id ()),
Definition (resolved->get_node_id ()));
else
Expand Down
1 change: 0 additions & 1 deletion gcc/testsuite/rust/compile/nr2/exclude
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ cfg3.rs
cfg4.rs
cfg5.rs
closure_no_type_anno.rs
complex-path1.rs
complex_qualified_path_in_expr.rs
const-issue1440.rs
const_generics_3.rs
Expand Down

0 comments on commit 2bcb4fc

Please sign in to comment.