diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 42a63f6fd704..24d5f168c6a0 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -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::type>::type>::unwrap (x)) + +template class unwrap_type_segment_inner; + +/* base case */ +template <> class unwrap_type_segment_inner +{ +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 unwrap_type_segment_inner> +{ +public: + using ret = typename unwrap_type_segment_inner::ret; + + static ret &unwrap (std::unique_ptr &x) + { + return unwrap_type_segment (*x); + } + static const ret &unwrap (const std::unique_ptr &x) + { + return unwrap_type_segment (*x); + } +}; + +/* case which handles objects with a get_ident_segment member function */ +template 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 @@ -387,7 +447,7 @@ ForeverStack::find_starting_point (const std::vector &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 (); @@ -441,7 +501,7 @@ ForeverStack::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 ()); @@ -491,7 +551,7 @@ ForeverStack::resolve_path (const std::vector &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 (); @@ -501,7 +561,8 @@ ForeverStack::resolve_path (const std::vector &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 ()); }); } 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 4dbd86aa5d0d..6b7c4d6ee09c 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -255,10 +255,15 @@ Late::visit (AST::TypePath &type) // maybe we can overload `resolve_path` 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 diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index 4ba27d31f88b..5d728b42391f 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -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