diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index b68c73a46425e..71273deeb5b04 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -66,6 +66,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } + ty::Slice(ty) => { + let (variant, variant_place) = downcast(sym::Slice)?; + let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + self.write_slice_type_info(slice_place, *ty)?; + + variant + } ty::Bool => { let (variant, _variant_place) = downcast(sym::Bool)?; variant @@ -115,7 +123,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { ty::Adt(_, _) | ty::Foreign(_) | ty::Pat(_, _) - | ty::Slice(_) | ty::RawPtr(..) | ty::FnDef(..) | ty::FnPtr(..) @@ -246,6 +253,27 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + pub(crate) fn write_slice_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Slice`. + 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 { + // Write the `TypeId` of the slice's elements to the `element_ty` field. + sym::element_ty => self.write_type_id(ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + fn write_int_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d21580c16db20..e3dee9e689c9a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -362,6 +362,7 @@ symbols! { Send, SeqCst, Sized, + Slice, SliceIndex, SliceIter, Some, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 1d6cc034dbac8..7ea6c69aee9aa 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -45,6 +45,8 @@ pub enum TypeKind { Tuple(Tuple), /// Arrays. Array(Array), + /// Slices. + Slice(Slice), /// Primitive boolean type. Bool(Bool), /// Primitive character type. @@ -92,6 +94,15 @@ pub struct Array { pub len: usize, } +/// Compile-time type information about slices. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Slice { + /// The type of each element in the slice. + pub element_ty: TypeId, +} + /// Compile-time type information about `bool`. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 1e15446967b97..6eaa92b030a00 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -22,6 +22,14 @@ fn test_arrays() { } } +#[test] +fn test_slices() { + match const { Type::of::<[usize]>() }.kind { + TypeKind::Slice(slice) => assert_eq!(slice.element_ty, TypeId::of::()), + _ => unreachable!(), + } +} + #[test] fn test_tuples() { fn assert_tuple_arity() { diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index 0c8a835923be7..d15b46509ff20 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -194,7 +194,11 @@ Type { size: None, } Type { - kind: Other, + kind: Slice( + Slice { + element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + }, + ), size: None, } Type { diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 20af4deb4e416..efae226539515 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -194,7 +194,11 @@ Type { size: None, } Type { - kind: Other, + kind: Slice( + Slice { + element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + }, + ), size: None, } Type {