// 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
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;
}
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
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
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,
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
--- /dev/null
+#[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
+}
--- /dev/null
+#[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
+}
--- /dev/null
+#![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
+}