[gcc r16-6835] gccrs: nr: Add prelude field to NRCtx, and fill it upon encountering a prelude.

Arthur Cohen cohenarthur@gcc.gnu.org
Fri Jan 16 16:29:58 GMT 2026


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

commit r16-6835-g84fb4681805247a114edc37e9a5667fea29fe0f7
Author: Arthur Cohen <arthur.cohen@embecosm.com>
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)
     {}
   };


More information about the Gcc-cvs mailing list