From: Owen Avery <powerboat9.ga...@gmail.com>

gcc/rust/ChangeLog:

        * resolve/rust-forever-stack.hxx
        (ForeverStack::find_starting_point): Stop when hitting a lang
        item segment.
        (ForeverStack::resolve_segments): Resolve lang item segments.
        (ForeverStacl::resolve_path): Handle single segment lang item
        paths and add comment.
        * util/rust-unwrap-segment.cc
        (unwrap_segment_get_lang_item): Add.
        * util/rust-unwrap-segment.h
        (unwrap_segment_get_lang_item): Add.

gcc/testsuite/ChangeLog:

        * rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery <powerboat9.ga...@gmail.com>
---
 gcc/rust/resolve/rust-forever-stack.hxx | 27 +++++++++++++++++++++++++
 gcc/rust/util/rust-unwrap-segment.cc    | 20 ++++++++++++++++++
 gcc/rust/util/rust-unwrap-segment.h     | 19 +++++++++++++++++
 gcc/testsuite/rust/compile/nr2/exclude  |  5 -----
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 8abe8a61acb..9ca8db2c09d 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -384,6 +384,10 @@ ForeverStack<N>::find_starting_point (
   for (; !is_last (iterator, segments); iterator++)
     {
       auto &outer_seg = *iterator;
+
+      if (unwrap_segment_get_lang_item (outer_seg).has_value ())
+       break;
+
       auto &seg = unwrap_type_segment (outer_seg);
       auto is_self_or_crate
        = seg.is_crate_path_seg () || seg.is_lower_self_seg ();
@@ -452,6 +456,17 @@ ForeverStack<N>::resolve_segments (
   for (; !is_last (iterator, segments); iterator++)
     {
       auto &outer_seg = *iterator;
+
+      if (auto lang_item = unwrap_segment_get_lang_item (outer_seg))
+       {
+         NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+           lang_item.value ());
+         current_node = &dfs_node (root, seg_id).value ();
+
+         insert_segment_resolution (outer_seg, seg_id);
+         continue;
+       }
+
       auto &seg = unwrap_type_segment (outer_seg);
       auto str = seg.as_string ();
       rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());
@@ -538,6 +553,17 @@ ForeverStack<N>::resolve_path (
   // if there's only one segment, we just use `get`
   if (segments.size () == 1)
     {
+      auto &seg = segments.front ();
+      if (auto lang_item = unwrap_segment_get_lang_item (seg))
+       {
+         NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+           lang_item.value ());
+
+         insert_segment_resolution (seg, seg_id);
+         // TODO: does NonShadowable matter?
+         return Rib::Definition::NonShadowable (seg_id);
+       }
+
       auto res = get (unwrap_type_segment (segments.back ()).as_string ());
       if (res && !res->is_ambiguous ())
        insert_segment_resolution (segments.back (), res->get_node_id ());
@@ -558,6 +584,7 @@ ForeverStack<N>::resolve_path (
       // leave resolution within impl blocks to type checker
       if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
        return tl::nullopt;
+      // assuming this can't be a lang item segment
       auto res = final_node.rib.get (
        unwrap_type_segment (segments.back ()).as_string ());
       if (res && !res->is_ambiguous ())
diff --git a/gcc/rust/util/rust-unwrap-segment.cc 
b/gcc/rust/util/rust-unwrap-segment.cc
index 38ff273fc06..083a0e54c91 100644
--- a/gcc/rust/util/rust-unwrap-segment.cc
+++ b/gcc/rust/util/rust-unwrap-segment.cc
@@ -38,4 +38,24 @@ unwrap_segment_node_id (const AST::PathExprSegment &seg)
   return seg.get_node_id ();
 }
 
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg)
+{
+  if (seg.is_lang_item ())
+    return seg.get_lang_item ();
+  return tl::nullopt;
+}
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg)
+{
+  return tl::nullopt;
+}
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg)
+{
+  return tl::nullopt;
+}
+
 } // namespace Rust
diff --git a/gcc/rust/util/rust-unwrap-segment.h 
b/gcc/rust/util/rust-unwrap-segment.h
index 4a3838a407a..bebdc3aadd4 100644
--- a/gcc/rust/util/rust-unwrap-segment.h
+++ b/gcc/rust/util/rust-unwrap-segment.h
@@ -99,4 +99,23 @@ unwrap_segment_node_id (const std::unique_ptr<T> &ptr)
   return unwrap_segment_node_id (*ptr);
 }
 
+/**
+ * Used to check if a path segment is associated with a lang item
+ */
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg);
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg);
+
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg);
+
+template <class T>
+tl::optional<LangItem::Kind>
+unwrap_segment_get_lang_item (const std::unique_ptr<T> &ptr)
+{
+  return unwrap_segment_get_lang_item (*ptr);
+}
+
 } // namespace Rust
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index f74c2ac6c66..6dba0f71705 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -4,7 +4,6 @@ cfg1.rs
 complex-path1.rs
 const_generics_3.rs
 const_generics_4.rs
-derive_macro1.rs
 feature_rust_attri0.rs
 generics9.rs
 issue-1483.rs
@@ -55,9 +54,6 @@ issue-266.rs
 derive_clone_enum1.rs
 derive_clone_enum2.rs
 derive_clone_enum3.rs
-derive_macro4.rs
-derive_macro6.rs
-issue-2987.rs
 issue-3139-1.rs
 issue-3139-3.rs
 derive-debug1.rs
@@ -67,6 +63,5 @@ for-loop1.rs
 for-loop2.rs
 issue-3403.rs
 derive-eq-invalid.rs
-derive-partialeq1.rs
 derive-hash1.rs
 # please don't delete the trailing newline
-- 
2.45.2

Reply via email to