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
69 changes: 6 additions & 63 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
// Fill all fields of the `TypeInfo` struct.
for (idx, field) in ty_struct.fields.iter_enumerated() {
let field_dest = self.project_field(dest, idx)?;
let ptr_bit_width = || self.tcx.data_layout.pointer_size().bits();
match field.name {
sym::kind => {
let variant_index = match ty.kind() {
Expand Down Expand Up @@ -115,33 +114,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
self.project_downcast_named(&field_dest, sym::Char)?;
variant
}
ty::Int(int_ty) => {
let (variant, variant_place) =
ty::Int(_) => {
let (variant, _variant_place) =
self.project_downcast_named(&field_dest, sym::Int)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_int_type_info(
place,
int_ty.bit_width().unwrap_or_else(/* isize */ ptr_bit_width),
true,
)?;
variant
}
ty::Uint(uint_ty) => {
let (variant, variant_place) =
ty::Uint(_) => {
let (variant, _variant_place) =
self.project_downcast_named(&field_dest, sym::Int)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_int_type_info(
place,
uint_ty.bit_width().unwrap_or_else(/* usize */ ptr_bit_width),
false,
)?;
variant
}
ty::Float(float_ty) => {
let (variant, variant_place) =
ty::Float(_) => {
let (variant, _variant_place) =
self.project_downcast_named(&field_dest, sym::Float)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_float_type_info(place, float_ty.bit_width())?;
variant
}
ty::Str => {
Expand Down Expand Up @@ -316,48 +301,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
interp_ok(())
}

fn write_int_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
bit_width: u64,
signed: bool,
) -> InterpResult<'tcx> {
for (field_idx, field) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;
match field.name {
sym::bits => self.write_scalar(
Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")),
&field_place,
)?,
sym::signed => self.write_scalar(Scalar::from_bool(signed), &field_place)?,
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
}
}
interp_ok(())
}

fn write_float_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
bit_width: u64,
) -> InterpResult<'tcx> {
for (field_idx, field) in
place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
{
let field_place = self.project_field(&place, field_idx)?;
match field.name {
sym::bits => self.write_scalar(
Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")),
&field_place,
)?,
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
}
}
interp_ok(())
}

pub(crate) fn write_reference_type_info(
&mut self,
place: impl Writeable<'tcx, CtfeProvenance>,
Expand Down
44 changes: 4 additions & 40 deletions library/core/src/mem/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ pub enum TypeKind {
/// Unions.
Union,
/// Primitive boolean type.
Bool(Bool),
Comment thread
oli-obk marked this conversation as resolved.
Bool,
/// Primitive character type.
Char(Char),
Char,
/// Primitive signed and unsigned integer type.
Int(Int),
Int,
Comment thread
oli-obk marked this conversation as resolved.
/// Primitive floating-point type.
Float(Float),
Float,

@bjorn3 bjorn3 Aug 20, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the float format? (IEEE 754 f16 vs something like bf16 for example)

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be a misunderstanding here (I neglected to provide the context for this work as Oli has that).

Nothing new is being introduced for reflection. We are simply moving from an enum with fields to members on TypeId. Unless I'm mistaken we had no way to get the float format before so we did not lose it here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea this wasn't available before, but we can def add it if/when necessary

/// String slice type.
Str(Str),
/// References.
Expand Down Expand Up @@ -199,42 +199,6 @@ pub struct Const {
pub ty: TypeId,
}

/// Compile-time type information about `bool`.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Bool {
// No additional information to provide for now.
}

/// Compile-time type information about `char`.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Char {
// No additional information to provide for now.
}

/// Compile-time type information about signed and unsigned integer types.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Int {
/// The bit width of the signed integer type.
pub bits: u32,
/// Whether the integer type is signed.
pub signed: bool,
}

/// Compile-time type information about floating-point types.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Float {
/// The bit width of the floating-point type.
pub bits: u32,
}

/// Compile-time type information about string slice types.
#[derive(Debug)]
#[non_exhaustive]
Expand Down
27 changes: 11 additions & 16 deletions library/coretests/tests/mem/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,46 +223,41 @@ fn test_primitives() {
use TypeKind::*;

const {
let Type { kind: Bool(_ty), .. } = (const { Type::of::<bool>() }) else { panic!() };
let Type { kind: Bool, .. } = (const { Type::of::<bool>() }) else { panic!() };
let ty_id = TypeId::of::<bool>();
assert!(ty_id.size() == Some(size_of::<bool>()));
assert!(ty_id.variants() == 1);

let Type { kind: Char(_ty), .. } = (const { Type::of::<char>() }) else { panic!() };
let Type { kind: Char, .. } = (const { Type::of::<char>() }) else { panic!() };
let ty_id = TypeId::of::<char>();
assert!(ty_id.size() == Some(size_of::<char>()));
assert!(ty_id.variants() == 1);

let Type { kind: Int(ty), .. } = (const { Type::of::<i32>() }) else { panic!() };
assert!(ty.bits == 32);
assert!(ty.signed);
let Type { kind: Int, .. } = (const { Type::of::<i32>() }) else { panic!() };
let ty_id = TypeId::of::<i32>();
assert!(ty_id.is_signed());
assert!(ty_id.size() == Some(size_of::<i32>()));
assert!(ty_id.variants() == 1);

let Type { kind: Int(ty), .. } = (const { Type::of::<isize>() }) else { panic!() };
assert!(ty.bits as usize == size_of::<isize>() * 8);
assert!(ty.signed);
let Type { kind: Int, .. } = (const { Type::of::<isize>() }) else { panic!() };
let ty_id = TypeId::of::<isize>();
assert!(ty_id.is_signed());
assert!(ty_id.size() == Some(size_of::<isize>()));
assert!(ty_id.variants() == 1);

let Type { kind: Int(ty), .. } = (const { Type::of::<u32>() }) else { panic!() };
assert!(ty.bits == 32);
assert!(!ty.signed);
let Type { kind: Int, .. } = (const { Type::of::<u32>() }) else { panic!() };
let ty_id = TypeId::of::<u32>();
assert!(!ty_id.is_signed());
assert!(ty_id.size() == Some(size_of::<u32>()));
assert!(ty_id.variants() == 1);

let Type { kind: Int(ty), .. } = (const { Type::of::<usize>() }) else { panic!() };
assert!(ty.bits as usize == size_of::<usize>() * 8);
assert!(!ty.signed);
let Type { kind: Int, .. } = (const { Type::of::<usize>() }) else { panic!() };
let ty_id = TypeId::of::<usize>();
assert!(!ty_id.is_signed());
assert!(ty_id.size() == Some(size_of::<usize>()));
assert!(ty_id.variants() == 1);

let Type { kind: Float(ty), .. } = (const { Type::of::<f32>() }) else { panic!() };
assert!(ty.bits == 32);
let Type { kind: Float, .. } = (const { Type::of::<f32>() }) else { panic!() };
let ty_id = TypeId::of::<f32>();
assert!(ty_id.size() == Some(size_of::<f32>()));
assert!(ty_id.variants() == 1);
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/lint/recommend-literal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//~vv HELP consider importing this struct

type Real = double;
//~^ ERROR cannot find type `double` in this scope
//~| HELP perhaps you intended to use this type
Expand All @@ -16,6 +14,7 @@ fn main() {
//~^ ERROR: cannot find type `Bool` in this scope [E0425]
//~| HELP a builtin type with a similar name exists
//~| HELP perhaps you intended to use this type
//~| HELP: there is an enum variant `std::mem::type_info::TypeKind::Bool`; try using the variant's enum
}

fn z(a: boolean) {
Expand Down
27 changes: 14 additions & 13 deletions tests/ui/lint/recommend-literal.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0425]: cannot find type `double` in this scope
--> $DIR/recommend-literal.rs:3:13
--> $DIR/recommend-literal.rs:1:13
|
LL | type Real = double;
| ^^^^^^
Expand All @@ -8,7 +8,7 @@ LL | type Real = double;
| help: perhaps you intended to use this type: `f64`

error[E0425]: cannot find type `long` in this scope
--> $DIR/recommend-literal.rs:9:12
--> $DIR/recommend-literal.rs:7:12
|
LL | let y: long = 74802374902374923;
| ^^^^
Expand All @@ -17,7 +17,7 @@ LL | let y: long = 74802374902374923;
| help: perhaps you intended to use this type: `i64`

error[E0425]: cannot find type `Boolean` in this scope
--> $DIR/recommend-literal.rs:12:13
--> $DIR/recommend-literal.rs:10:13
|
LL | let v1: Boolean = true;
| ^^^^^^^
Expand All @@ -26,11 +26,16 @@ LL | let v1: Boolean = true;
| help: perhaps you intended to use this type: `bool`

error[E0425]: cannot find type `Bool` in this scope
--> $DIR/recommend-literal.rs:15:13
--> $DIR/recommend-literal.rs:13:13
|
LL | let v2: Bool = true;
| ^^^^
|
help: there is an enum variant `std::mem::type_info::TypeKind::Bool`; try using the variant's enum
|
LL - let v2: Bool = true;
LL + let v2: std::mem::type_info::TypeKind = true;
|
help: a builtin type with a similar name exists
|
LL - let v2: Bool = true;
Expand All @@ -41,13 +46,9 @@ help: perhaps you intended to use this type
LL - let v2: Bool = true;
LL + let v2: bool = true;
|
help: consider importing this struct
|
LL + use std::mem::type_info::Bool;
|

error[E0425]: cannot find type `boolean` in this scope
--> $DIR/recommend-literal.rs:21:9
--> $DIR/recommend-literal.rs:20:9
|
LL | fn z(a: boolean) {
| ^^^^^^^
Expand All @@ -56,7 +57,7 @@ LL | fn z(a: boolean) {
| help: perhaps you intended to use this type: `bool`

error[E0425]: cannot find type `byte` in this scope
--> $DIR/recommend-literal.rs:26:11
--> $DIR/recommend-literal.rs:25:11
|
LL | fn a() -> byte {
| ^^^^
Expand All @@ -65,7 +66,7 @@ LL | fn a() -> byte {
| help: perhaps you intended to use this type: `u8`

error[E0425]: cannot find type `float` in this scope
--> $DIR/recommend-literal.rs:33:12
--> $DIR/recommend-literal.rs:32:12
|
LL | width: float,
| ^^^^^
Expand All @@ -74,7 +75,7 @@ LL | width: float,
| help: perhaps you intended to use this type: `f32`

error[E0425]: cannot find type `int` in this scope
--> $DIR/recommend-literal.rs:36:19
--> $DIR/recommend-literal.rs:35:19
|
LL | depth: Option<int>,
| ^^^ not found in this scope
Expand All @@ -90,7 +91,7 @@ LL | struct Data<int> {
| +++++

error[E0425]: cannot find type `short` in this scope
--> $DIR/recommend-literal.rs:42:16
--> $DIR/recommend-literal.rs:41:16
|
LL | impl Stuff for short {}
| ^^^^^
Expand Down
Loading