https://gcc.gnu.org/g:84fb4681805247a114edc37e9a5667fea29fe0f7

commit r16-6835-g84fb4681805247a114edc37e9a5667fea29fe0f7
Author: Arthur Cohen <[email protected]>
Date:   Wed Sep 10 09:07:55 2025 +0200

    gccrs: nr: Add prelude field to NRCtx, and fill it upon encountering a 
prelude.
    
    gcc/rust/ChangeLog:
    
            * resolve/rust-early-name-resolver-2.0.cc 
(Early::finalize_glob_import): Save prelude
            if we find one.
            * resolve/rust-name-resolution-context.h: Add field.
            * resolve/rust-toplevel-name-resolver-2.0.cc (has_prelude_import): 
New function.
            (TopLevel::visit): Create a prelude glob import if necessary.
            * resolve/rust-toplevel-name-resolver-2.0.h: Allow glob imports to 
be prelude imports.

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc   |  8 +++
 gcc/rust/resolve/rust-name-resolution-context.h    | 59 +++++++++++++++++++---
 .../resolve/rust-toplevel-name-resolver-2.0.cc     | 13 ++++-
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h | 18 ++++---
 4 files changed, 83 insertions(+), 15 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 49ac9c821d88..9e0e6a258789 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -411,6 +411,14 @@ Early::finalize_glob_import (NameResolutionContext &ctx,
 
   rust_assert (container);
 
+  if (mapping.import_kind.is_prelude)
+    {
+      rust_assert (container.value ()->get_item_kind ()
+                  == AST::Item::Kind::Module);
+
+      ctx.prelude = container.value ()->get_node_id ();
+    }
+
   GlobbingVisitor (ctx).go (container.value ());
 }
 
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 9263e19d6d85..2d1ce3117b57 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -560,23 +560,63 @@ public:
          if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ())
            map_usage (Usage (seg_id), Definition (id));
        };
+
+    tl::optional<Rib::Definition> resolved = tl::nullopt;
+
     switch (ns)
       {
       case Namespace::Values:
-       return values.resolve_path (segments, mode, insert_segment_resolution,
-                                   collect_errors);
+       resolved
+         = values.resolve_path (segments, mode, insert_segment_resolution,
+                                collect_errors);
+       break;
       case Namespace::Types:
-       return types.resolve_path (segments, mode, insert_segment_resolution,
-                                  collect_errors);
+       resolved
+         = types.resolve_path (segments, mode, insert_segment_resolution,
+                               collect_errors);
+       break;
       case Namespace::Macros:
-       return macros.resolve_path (segments, mode, insert_segment_resolution,
-                                   collect_errors);
+       resolved
+         = macros.resolve_path (segments, mode, insert_segment_resolution,
+                                collect_errors);
+       break;
       case Namespace::Labels:
-       return labels.resolve_path (segments, mode, insert_segment_resolution,
-                                   collect_errors);
+       resolved
+         = labels.resolve_path (segments, mode, insert_segment_resolution,
+                                collect_errors);
+       break;
       default:
        rust_unreachable ();
       }
+
+    // If it fails, switch to std prelude resolution if it exists
+    if (prelude && !resolved)
+      {
+       // TODO: Factor this with the above
+       switch (ns)
+         {
+         case Namespace::Values:
+           return values.resolve_path (segments, mode,
+                                       insert_segment_resolution,
+                                       collect_errors, *prelude);
+         case Namespace::Types:
+           return types.resolve_path (segments, mode,
+                                      insert_segment_resolution,
+                                      collect_errors, *prelude);
+         case Namespace::Macros:
+           return macros.resolve_path (segments, mode,
+                                       insert_segment_resolution,
+                                       collect_errors, *prelude);
+         case Namespace::Labels:
+           return labels.resolve_path (segments, mode,
+                                       insert_segment_resolution,
+                                       collect_errors, *prelude);
+         default:
+           rust_unreachable ();
+         }
+      }
+
+    return resolved;
   }
 
   template <typename S, typename... Args>
@@ -676,6 +716,9 @@ public:
                         std::forward<Args> (args)...);
   }
 
+  /* If declared with #[prelude_import], the current standard library module */
+  tl::optional<NodeId> prelude;
+
 private:
   /* Map of "usage" nodes which have been resolved to a "definition" node */
   std::map<Usage, Definition> resolved_nodes;
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index b3dafc4800c5..ed93911fbab1 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -496,6 +496,16 @@ flatten_glob (const AST::UseTreeGlob &glob, 
std::vector<AST::SimplePath> &paths,
     paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
 }
 
+static bool
+has_prelude_import (const std::vector<AST::Attribute> &attributes)
+{
+  for (const auto &attr : attributes)
+    if (attr.get_path ().as_string () == "prelude_import")
+      return true;
+
+  return false;
+}
+
 void
 TopLevel::visit (AST::UseDeclaration &use)
 {
@@ -523,7 +533,8 @@ TopLevel::visit (AST::UseDeclaration &use)
 
   for (auto &&glob : glob_path)
     imports.emplace_back (
-      ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
+      ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
+                       has_prelude_import (use.get_outer_attrs ())));
 
   for (auto &&rebind : rebind_path)
     imports.emplace_back (
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index cc280ec67ff2..b5b0c8b19820 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -67,10 +67,10 @@ public:
     } kind;
 
     static ImportKind Glob (AST::SimplePath &&to_resolve, Rib &values_rib,
-                           Rib &types_rib, Rib &macros_rib)
+                           Rib &types_rib, Rib &macros_rib, bool is_prelude)
     {
       return ImportKind (Kind::Glob, std::move (to_resolve), values_rib,
-                        types_rib, macros_rib);
+                        types_rib, macros_rib, is_prelude);
     }
 
     static ImportKind Simple (AST::SimplePath &&to_resolve, Rib &values_rib,
@@ -84,8 +84,10 @@ public:
                              AST::UseTreeRebind &&rebind, Rib &values_rib,
                              Rib &types_rib, Rib &macros_rib)
     {
-      return ImportKind (Kind::Rebind, std::move (to_resolve), values_rib,
-                        types_rib, macros_rib, std::move (rebind));
+      return ImportKind (
+       Kind::Rebind, std::move (to_resolve), values_rib, types_rib, macros_rib,
+       false /* is_prelude: rebind imports can never be preludes */,
+       std::move (rebind));
     }
 
     // The path for `Early` to resolve.
@@ -98,13 +100,17 @@ public:
     Rib &types_rib;
     Rib &macros_rib;
 
+    // Can only be true if we are dealing with a glob import with the
+    // #[prelude_import] attribute
+    bool is_prelude = false;
+
   private:
     ImportKind (Kind kind, AST::SimplePath &&to_resolve, Rib &values_rib,
-               Rib &types_rib, Rib &macros_rib,
+               Rib &types_rib, Rib &macros_rib, bool is_prelude = false,
                tl::optional<AST::UseTreeRebind> &&rebind = tl::nullopt)
       : kind (kind), to_resolve (std::move (to_resolve)),
        rebind (std::move (rebind)), values_rib (values_rib),
-       types_rib (types_rib), macros_rib (macros_rib)
+       types_rib (types_rib), macros_rib (macros_rib), is_prelude (is_prelude)
     {}
   };

Reply via email to