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
11 changes: 11 additions & 0 deletions gcc/rust/backend/rust-compile-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ CompileItem::visit (HIR::ConstantItem &constant)
// canonical path
Resolver::CanonicalPath canonical_path
= nr_ctx.to_canonical_path (mappings.get_nodeid ());
if (constant_type->is<const TyTy::FnType> ())
{
if (concrete == nullptr)
return;

rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);

concrete_fnty->override_context ();
constant_type = expr_type = concrete_fnty->get_return_type ();
}

ctx->push_const_context ();
tree const_expr
Expand Down
20 changes: 17 additions & 3 deletions gcc/rust/typecheck/rust-hir-type-check-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,19 @@ TypeCheckExpr::Resolve (HIR::Expr &expr)
if (resolver.infered == nullptr)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());

auto ref = expr.get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
if (resolver.infered->get_kind () != TyTy::TypeKind::CONST)
{
auto ref = expr.get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
}
resolver.context->insert_type (expr.get_mappings (), resolver.infered);

if (auto fn = resolver.infered->try_as<const TyTy::FnType> ())
{
if (fn->is_syn_constant ())
resolver.infered = fn->get_return_type ();
}

return resolver.infered;
}

Expand Down Expand Up @@ -2358,7 +2367,12 @@ bool
TypeCheckExpr::validate_arithmetic_type (
const TyTy::BaseType *tyty, HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
{
const TyTy::BaseType *type = tyty->destructure ();
auto type = tyty->destructure ();
if (type->get_kind () == TyTy::TypeKind::CONST)
{
auto base_const = type->as_const_type ();
type = base_const->get_specified_type ();
}

// https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
// this will change later when traits are added
Expand Down
28 changes: 26 additions & 2 deletions gcc/rust/typecheck/rust-hir-type-check-implitem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,32 @@ TypeCheckImplItem::visit (HIR::ConstantItem &constant)
TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
constant.get_locus ());
context->insert_type (constant.get_mappings (), unified);
result = unified;

if (substitutions.empty ())
{
context->insert_type (constant.get_mappings (), unified);
result = unified;
return;
}

// special case when this is a generic constant
auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
CanonicalPath canonical_path
= nr_ctx.to_canonical_path (constant.get_mappings ().get_nodeid ());
RustIdent ident{canonical_path, constant.get_locus ()};
auto fnType = new TyTy::FnType (
constant.get_mappings ().get_hirid (),
constant.get_mappings ().get_defid (),
constant.get_identifier ().as_string (), ident,
TyTy::FnType::FNTYPE_IS_SYN_CONST_FLAG, ABI::RUST, {}, unified,
std::move (substitutions),
TyTy::SubstitutionArgumentMappings::empty (
context->get_lifetime_resolver ().get_num_bound_regions ()),
{});

context->insert_type (constant.get_mappings (), fnType);
result = fnType;
}

void
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/typecheck/rust-tyty.h
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,7 @@ class FnType : public CallableTypeInterface, public SubstitutionRef
static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01;
static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02;
static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
static const uint8_t FNTYPE_IS_SYN_CONST_FLAG = 0X08;

FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
Expand Down Expand Up @@ -1111,6 +1112,11 @@ class FnType : public CallableTypeInterface, public SubstitutionRef

bool is_variadic () const { return (flags & FNTYPE_IS_VARADIC_FLAG) != 0; }

bool is_syn_constant () const
{
return (flags & FNTYPE_IS_SYN_CONST_FLAG) != 0;
}

DefId get_id () const { return id; }

// get the Self type for the method
Expand Down
13 changes: 13 additions & 0 deletions gcc/testsuite/rust/execute/torture/const-generics-5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[lang = "sized"]
trait Sized {}

struct Foo<const N: usize>;

impl<const N: usize> Foo<N> {
const VALUE: usize = N;
}

fn main() -> i32 {
let val = Foo::<7>::VALUE;
val as i32 - 7
}
15 changes: 15 additions & 0 deletions gcc/testsuite/rust/execute/torture/const-generics-6.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#[lang = "sized"]
trait Sized {}

struct Foo<const N: usize>;

impl<const N: usize> Foo<N> {
const VALUE: usize = N;
const SQUARE: usize = N * N;
}

fn main() -> i32 {
let a = Foo::<5>::VALUE; // 5
let b = Foo::<5>::SQUARE; // 25
(a + b) as i32 - 30
}
22 changes: 22 additions & 0 deletions gcc/testsuite/rust/execute/torture/const-generics-7.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![feature(intrinsics)]

#[lang = "sized"]
pub trait Sized {}

mod mem {
extern "rust-intrinsic" {
#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
pub fn size_of<T>() -> usize;
}
}

struct Foo<T>;

impl<T> Foo<T> {
const MAGIC: usize = mem::size_of::<T>();
}

fn main() -> i32 {
let sz = Foo::<u16>::MAGIC;
sz as i32 - 2
}
Loading