Merge type info variant Uint into Int

This commit is contained in:
Asuna 2026-01-15 22:17:43 +01:00
parent 5c057ad896
commit b2a7b18ec4
6 changed files with 85 additions and 46 deletions

View file

@ -1,6 +1,6 @@
use rustc_abi::FieldIdx;
use rustc_hir::LangItem;
use rustc_middle::mir::interpret::CtfeProvenance;
use rustc_middle::mir::interpret::{CtfeProvenance, Scalar};
use rustc_middle::span_bug;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Const, ScalarInt, Ty};
@ -76,25 +76,27 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
ty::Int(int_ty) => {
let (variant, variant_place) = downcast(sym::Int)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_int_float_type_info(
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) = downcast(sym::Uint)?;
let (variant, variant_place) = downcast(sym::Int)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_int_float_type_info(
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) = downcast(sym::Float)?;
let place = self.project_field(&variant_place, FieldIdx::ZERO)?;
self.write_int_float_type_info(place, float_ty.bit_width())?;
self.write_float_type_info(place, float_ty.bit_width())?;
variant
}
ty::Str => {
@ -236,7 +238,29 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
interp_ok(())
}
fn write_int_float_type_info(
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::bit_width => self.write_scalar(
ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(),
&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,

View file

@ -391,7 +391,6 @@ symbols! {
Ty,
TyCtxt,
TyKind,
Uint,
Unknown,
Unsize,
UnsizedConstParamTy,
@ -2066,6 +2065,7 @@ symbols! {
shr_assign,
sig_dfl,
sig_ign,
signed,
simd,
simd_add,
simd_and,

View file

@ -49,10 +49,8 @@ pub enum TypeKind {
Bool(Bool),
/// Primitive character type.
Char(Char),
/// Primitive signed integer type.
/// Primitive signed and unsigned integer type.
Int(Int),
/// Primitive unsigned integer type.
Uint(Uint),
/// Primitive floating-point type.
Float(Float),
/// String slice type.
@ -108,22 +106,15 @@ pub struct Char {
// No additional information to provide for now.
}
/// Compile-time type information about signed integer types.
/// 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 bit_width: usize,
}
/// Compile-time type information about unsigned integer types.
#[derive(Debug)]
#[non_exhaustive]
#[unstable(feature = "type_info", issue = "146922")]
pub struct Uint {
/// The bit width of the unsigned integer type.
pub bit_width: usize,
/// Whether the integer type is signed.
pub signed: bool,
}
/// Compile-time type information about floating-point types.

View file

@ -38,7 +38,7 @@ fn test_tuples() {
assert_tuple_arity::<(u8, u8), 2>();
const {
match Type::of::<(u8, u8)>().kind {
match Type::of::<(i8, u8)>().kind {
TypeKind::Tuple(tup) => {
let [a, b] = tup.fields else { unreachable!() };
@ -46,9 +46,9 @@ fn test_tuples() {
assert!(b.offset == 1);
match (a.ty.info().kind, b.ty.info().kind) {
(TypeKind::Uint(a), TypeKind::Uint(b)) => {
assert!(a.bit_width == 8);
assert!(b.bit_width == 8);
(TypeKind::Int(a), TypeKind::Int(b)) => {
assert!(a.bit_width == 8 && a.signed);
assert!(b.bit_width == 8 && !b.signed);
}
_ => unreachable!(),
}
@ -71,18 +71,22 @@ fn test_primitives() {
let Type { kind: Int(ty), size, .. } = (const { Type::of::<i32>() }) else { panic!() };
assert_eq!(size, Some(4));
assert_eq!(ty.bit_width, 32);
assert!(ty.signed);
let Type { kind: Int(ty), size, .. } = (const { Type::of::<isize>() }) else { panic!() };
assert_eq!(size, Some(size_of::<isize>()));
assert_eq!(ty.bit_width, size_of::<isize>() * 8);
assert!(ty.signed);
let Type { kind: Uint(ty), size, .. } = (const { Type::of::<u32>() }) else { panic!() };
let Type { kind: Int(ty), size, .. } = (const { Type::of::<u32>() }) else { panic!() };
assert_eq!(size, Some(4));
assert_eq!(ty.bit_width, 32);
assert!(!ty.signed);
let Type { kind: Uint(ty), size, .. } = (const { Type::of::<usize>() }) else { panic!() };
let Type { kind: Int(ty), size, .. } = (const { Type::of::<usize>() }) else { panic!() };
assert_eq!(size, Some(size_of::<usize>()));
assert_eq!(ty.bit_width, size_of::<usize>() * 8);
assert!(!ty.signed);
let Type { kind: Float(ty), size, .. } = (const { Type::of::<f32>() }) else { panic!() };
assert_eq!(size, Some(4));

View file

@ -36,6 +36,7 @@ Type {
kind: Int(
Int {
bit_width: 8,
signed: true,
},
),
size: Some(
@ -46,6 +47,7 @@ Type {
kind: Int(
Int {
bit_width: 32,
signed: true,
},
),
size: Some(
@ -56,6 +58,7 @@ Type {
kind: Int(
Int {
bit_width: 64,
signed: true,
},
),
size: Some(
@ -66,6 +69,7 @@ Type {
kind: Int(
Int {
bit_width: 128,
signed: true,
},
),
size: Some(
@ -76,6 +80,7 @@ Type {
kind: Int(
Int {
bit_width: 32,
signed: true,
},
),
size: Some(
@ -83,9 +88,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 8,
signed: false,
},
),
size: Some(
@ -93,9 +99,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 32,
signed: false,
},
),
size: Some(
@ -103,9 +110,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 64,
signed: false,
},
),
size: Some(
@ -113,9 +121,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 128,
signed: false,
},
),
size: Some(
@ -123,9 +132,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 32,
signed: false,
},
),
size: Some(

View file

@ -36,6 +36,7 @@ Type {
kind: Int(
Int {
bit_width: 8,
signed: true,
},
),
size: Some(
@ -46,6 +47,7 @@ Type {
kind: Int(
Int {
bit_width: 32,
signed: true,
},
),
size: Some(
@ -56,6 +58,7 @@ Type {
kind: Int(
Int {
bit_width: 64,
signed: true,
},
),
size: Some(
@ -66,6 +69,7 @@ Type {
kind: Int(
Int {
bit_width: 128,
signed: true,
},
),
size: Some(
@ -76,6 +80,7 @@ Type {
kind: Int(
Int {
bit_width: 64,
signed: true,
},
),
size: Some(
@ -83,9 +88,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 8,
signed: false,
},
),
size: Some(
@ -93,9 +99,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 32,
signed: false,
},
),
size: Some(
@ -103,9 +110,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 64,
signed: false,
},
),
size: Some(
@ -113,9 +121,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 128,
signed: false,
},
),
size: Some(
@ -123,9 +132,10 @@ Type {
),
}
Type {
kind: Uint(
Uint {
kind: Int(
Int {
bit_width: 64,
signed: false,
},
),
size: Some(