Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,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 \
Expand Down
77 changes: 2 additions & 75 deletions gcc/rust/resolve/rust-late-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
}
Expand Down
3 changes: 0 additions & 3 deletions gcc/rust/resolve/rust-late-name-resolver-2.0.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ class Late : public DefaultResolver
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 */
Expand Down
125 changes: 125 additions & 0 deletions gcc/rust/resolve/rust-resolve-builtins.cc
Original file line number Diff line number Diff line change
@@ -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
37 changes: 37 additions & 0 deletions gcc/rust/resolve/rust-resolve-builtins.h
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions gcc/rust/rust-session-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -934,6 +935,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);
Expand Down
7 changes: 7 additions & 0 deletions gcc/testsuite/rust/compile/primitive-import.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod primitive {
pub use i32;
}

pub fn foo() -> primitive::i32 {
1
}
Loading