]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Allow early resolution to use the language prelude
authorOwen Avery <powerboat9.gamer@gmail.com>
Sun, 10 Aug 2025 20:03:35 +0000 (16:03 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:50 +0000 (20:58 +0100)
gcc/rust/ChangeLog:

* Make-lang.in (GRS_OBJS): Add "rust-resolve-builtins.o".
* resolve/rust-late-name-resolver-2.0.cc: Include
"rust-resolve-builtins.h".
(next_node_id): Remove function.
(next_hir_id): Likewise.
(Late::setup_builtin_types): Likewise.
(Late::go): Use Builtins::setup_type_ctx instead of
Late::setup_builtin_types.
* resolve/rust-late-name-resolver-2.0.h
(Late::setup_builtin_types): Remove function.
* rust-session-manager.cc: Include "rust-resolve-builtins.h".
(Session::expansion): Call Builtins::setup_lang_prelude.
* resolve/rust-resolve-builtins.cc: New file.
* resolve/rust-resolve-builtins.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/primitive-import.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/Make-lang.in
gcc/rust/resolve/rust-late-name-resolver-2.0.cc
gcc/rust/resolve/rust-late-name-resolver-2.0.h
gcc/rust/resolve/rust-resolve-builtins.cc [new file with mode: 0644]
gcc/rust/resolve/rust-resolve-builtins.h [new file with mode: 0644]
gcc/rust/rust-session-manager.cc
gcc/testsuite/rust/compile/primitive-import.rs [new file with mode: 0644]

index 26ad514fae3d1a532abe44eb2c6bacb58c082ac4..bbc3cc4903e4137951916474080bc9f37690aa93 100644 (file)
@@ -150,6 +150,7 @@ GRS_OBJS = \
        rust/rust-immutable-name-resolution-context.o \
     rust/rust-early-name-resolver.o \
     rust/rust-name-resolver.o \
+    rust/rust-resolve-builtins.o \
     rust/rust-ast-resolve.o \
     rust/rust-ast-resolve-base.o \
     rust/rust-ast-resolve-item.o \
index e39ca152c836240703e26b3eeedf330cf98bf431..6effb7af42f162f2501cfe6944a16b909f3dd0c2 100644 (file)
@@ -24,6 +24,7 @@
 #include "rust-late-name-resolver-2.0.h"
 #include "rust-default-resolver.h"
 #include "rust-name-resolution-context.h"
+#include "rust-resolve-builtins.h"
 #include "rust-path.h"
 #include "rust-system.h"
 #include "rust-tyty.h"
@@ -38,84 +39,10 @@ Late::Late (NameResolutionContext &ctx)
   : DefaultResolver (ctx), funny_error (false), block_big_self (false)
 {}
 
-static NodeId
-next_node_id ()
-{
-  return Analysis::Mappings::get ().get_next_node_id ();
-};
-
-static HirId
-next_hir_id ()
-{
-  return Analysis::Mappings::get ().get_next_hir_id ();
-};
-
-void
-Late::setup_builtin_types ()
-{
-  // access the global type context to setup the TyTys
-  auto &ty_ctx = *Resolver::TypeCheckContext::get ();
-
-  // Late builtin type struct helper
-  struct LType
-  {
-    std::string name;
-    NodeId node_id;
-    NodeId hir_id;
-    TyTy::BaseType *type;
-
-    explicit LType (std::string name, TyTy::BaseType *type)
-      : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()),
-       type (type)
-    {}
-  };
-
-  static const LType builtins[] = {
-    {LType ("bool", new TyTy::BoolType (next_hir_id ()))},
-    {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
-    {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
-    {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},
-    {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))},
-    {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))},
-    {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))},
-    {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))},
-    {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))},
-    {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))},
-    {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))},
-    {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))},
-    {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))},
-    {LType ("usize", new TyTy::USizeType (next_hir_id ()))},
-    {LType ("isize", new TyTy::ISizeType (next_hir_id ()))},
-    {LType ("char", new TyTy::CharType (next_hir_id ()))},
-    {LType ("str", new TyTy::StrType (next_hir_id ()))},
-    {LType ("!", new TyTy::NeverType (next_hir_id ()))},
-
-    // the unit type `()` does not play a part in name-resolution - so we only
-    // insert it in the type context...
-  };
-
-  // There's a special Rib for putting prelude items, since prelude items need
-  // to satisfy certain special rules.
-  ctx.scoped (Rib::Kind::Prelude, 0, [this, &ty_ctx] (void) -> void {
-    for (const auto &builtin : builtins)
-      {
-       auto ok = ctx.types.insert (builtin.name, builtin.node_id);
-       rust_assert (ok);
-
-       ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
-       ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
-      }
-  });
-
-  // ...here!
-  auto *unit_type = TyTy::TupleType::get_unit_type ();
-  ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
-}
-
 void
 Late::go (AST::Crate &crate)
 {
-  setup_builtin_types ();
+  Builtins::setup_type_ctx ();
 
   visit (crate);
 }
index 95540e34005329ff002fd57a3a5a4e631bec0da4..608ae38eb5c168f2c47bdd4dabe0350c26cf67b2 100644 (file)
@@ -75,9 +75,6 @@ public:
 private:
   void resolve_label (AST::Lifetime &lifetime);
 
-  /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
-  void setup_builtin_types ();
-
   bool funny_error;
 
   /* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
diff --git a/gcc/rust/resolve/rust-resolve-builtins.cc b/gcc/rust/resolve/rust-resolve-builtins.cc
new file mode 100644 (file)
index 0000000..b16db9a
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-resolve-builtins.h"
+#include "rust-name-resolution-context.h"
+#include "rust-tyty.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+namespace Builtins {
+
+// Use X-macros
+
+#define TYPE_UINT(n, enum_ident) TYPE1 (n, UintType, UintType::enum_ident)
+#define TYPE_INT(n, enum_ident) TYPE1 (n, IntType, IntType::enum_ident)
+
+#define BUILTIN_TYPES                                                          \
+  TYPE0 ("bool", BoolType)                                                     \
+  TYPE_UINT ("u8", U8)                                                         \
+  TYPE_UINT ("u16", U16)                                                       \
+  TYPE_UINT ("u32", U32)                                                       \
+  TYPE_UINT ("u64", U64)                                                       \
+  TYPE_UINT ("u128", U128)                                                     \
+  TYPE_INT ("i8", I8)                                                          \
+  TYPE_INT ("i16", I16)                                                        \
+  TYPE_INT ("i32", I32)                                                        \
+  TYPE_INT ("i64", I64)                                                        \
+  TYPE_INT ("i128", I128)                                                      \
+  TYPE1 ("f32", FloatType, FloatType::F32)                                     \
+  TYPE1 ("f64", FloatType, FloatType::F64)                                     \
+  TYPE0 ("usize", USizeType)                                                   \
+  TYPE0 ("isize", ISizeType)                                                   \
+  TYPE0 ("char", CharType)                                                     \
+  TYPE0 ("str", StrType)                                                       \
+  TYPE0 ("!", NeverType)
+
+// Define constants using X macros
+
+#define TYPE0(...) 1 +
+#define TYPE1(...) 1 +
+static constexpr size_t builtin_count = BUILTIN_TYPES 0;
+#undef TYPE0
+#undef TYPE1
+
+#define TYPE0(n, ...) n,
+#define TYPE1(n, ...) n,
+static constexpr const char *builtin_names[] = {BUILTIN_TYPES};
+#undef TYPE0
+#undef TYPE1
+
+static NodeId builtin_node_ids[builtin_count];
+
+void
+setup_lang_prelude (NameResolutionContext &ctx)
+{
+  auto &mappings = Analysis::Mappings::get ();
+
+  // insert into prelude rib
+  ctx.scoped (Rib::Kind::Prelude, 0, [&mappings, &ctx] (void) -> void {
+    for (size_t i = 0; i < builtin_count; i++)
+      {
+       NodeId node_id = mappings.get_next_node_id ();
+       rust_assert (ctx.types.insert (Identifier (builtin_names[i]), node_id));
+       builtin_node_ids[i] = node_id;
+      }
+  });
+}
+
+void
+setup_type_ctx ()
+{
+  auto &mappings = Analysis::Mappings::get ();
+  auto &ty_ctx = *Resolver::TypeCheckContext::get ();
+
+  HirId hir_ids[builtin_count];
+  for (size_t i = 0; i < builtin_count; i++)
+    hir_ids[i] = mappings.get_next_hir_id ();
+
+  TyTy::BaseType *types[builtin_count];
+  {
+    size_t i = 0;
+#define TYPE_BASE(stub)                                                        \
+  types[i] = new TyTy::stub;                                                   \
+  i++;
+#define TYPE0(n, ty) TYPE_BASE (ty (hir_ids[i]))
+#define TYPE1(n, ty, p1) TYPE_BASE (ty (hir_ids[i], TyTy::p1))
+    BUILTIN_TYPES
+#undef TYPE_BASE
+#undef TYPE0
+#undef TYPE1
+  }
+
+  for (size_t i = 0; i < builtin_count; i++)
+    {
+      NodeId node_id = builtin_node_ids[i];
+      HirId hir_id = hir_ids[i];
+      mappings.insert_node_to_hir (node_id, hir_id);
+      ty_ctx.insert_builtin (hir_id, node_id, types[i]);
+    }
+
+  // handle unit type separately
+  auto *unit_type = TyTy::TupleType::get_unit_type ();
+  ty_ctx.insert_builtin (unit_type->get_ref (), mappings.get_next_node_id (),
+                        unit_type);
+}
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-resolve-builtins.h b/gcc/rust/resolve/rust-resolve-builtins.h
new file mode 100644 (file)
index 0000000..e7e1bd2
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_RESOLVE_BUILTINS_H
+#define RUST_RESOLVE_BUILTINS_H
+
+namespace Rust {
+namespace Resolver2_0 {
+
+// forward declare
+class NameResolutionContext;
+
+namespace Builtins {
+
+void setup_lang_prelude (NameResolutionContext &ctx);
+void setup_type_ctx ();
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif // RUST_RESOLVE_BUILTINS_H
index e99fd6b8c0ce71ef7003e192ccd52f7928063f03..6418118468328a377951114e39438b24d3c20013 100644 (file)
@@ -48,6 +48,7 @@
 #include "rust-name-resolution-context.h"
 #include "rust-early-name-resolver-2.0.h"
 #include "rust-late-name-resolver-2.0.h"
+#include "rust-resolve-builtins.h"
 #include "rust-cfg-strip.h"
 #include "rust-expand-visitor.h"
 #include "rust-unicode.h"
@@ -935,6 +936,8 @@ Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx)
   MacroExpander expander (crate, cfg, *this);
   std::vector<Error> macro_errors;
 
+  Resolver2_0::Builtins::setup_lang_prelude (ctx);
+
   while (!fixed_point_reached && iterations < cfg.recursion_limit)
     {
       CfgStrip (cfg).go (crate);
diff --git a/gcc/testsuite/rust/compile/primitive-import.rs b/gcc/testsuite/rust/compile/primitive-import.rs
new file mode 100644 (file)
index 0000000..cc750af
--- /dev/null
@@ -0,0 +1,7 @@
+mod primitive {
+    pub use i32;
+}
+
+pub fn foo() -> primitive::i32 {
+    1
+}