Rollup merge of #151118 - BD103:reflect-slices, r=oli-obk
Support slices in type reflection Tracking issue: rust-lang/rust#146922 This PR adds support for inspecting slices `[T]` through type reflection. It does so by adding the new `Slice` struct + variant, which is very similar to `Array` but without the `len` field: ```rust pub struct Slice { pub element_ty: TypeId, } ``` Here is an example reflecting a slice: ```rust match const { Type::of::<[u8]>() }.kind { TypeKind::Slice(slice) => assert_eq!(slice.element_ty, TypeId::of::<u8>()), _ => unreachable!(), } ``` In addition to this, I also re-arranged the type info unit tests. r? @oli-obk
This commit is contained in:
commit
a4cf93bccc
6 changed files with 59 additions and 3 deletions
|
|
@ -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
|
||||
|
|
@ -124,7 +132,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
|
|||
ty::Adt(_, _)
|
||||
| ty::Foreign(_)
|
||||
| ty::Pat(_, _)
|
||||
| ty::Slice(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::UnsafeBinder(..)
|
||||
|
|
@ -254,6 +261,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>,
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ symbols! {
|
|||
Send,
|
||||
SeqCst,
|
||||
Sized,
|
||||
Slice,
|
||||
SliceIndex,
|
||||
SliceIter,
|
||||
Some,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ pub enum TypeKind {
|
|||
Tuple(Tuple),
|
||||
/// Arrays.
|
||||
Array(Array),
|
||||
/// Slices.
|
||||
Slice(Slice),
|
||||
/// Primitive boolean type.
|
||||
Bool(Bool),
|
||||
/// Primitive character type.
|
||||
|
|
@ -94,6 +96,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]
|
||||
|
|
|
|||
|
|
@ -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::<usize>()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuples() {
|
||||
fn assert_tuple_arity<T: 'static, const N: usize>() {
|
||||
|
|
|
|||
|
|
@ -194,7 +194,11 @@ Type {
|
|||
size: None,
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Slice(
|
||||
Slice {
|
||||
element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
},
|
||||
),
|
||||
size: None,
|
||||
}
|
||||
Type {
|
||||
|
|
|
|||
|
|
@ -194,7 +194,11 @@ Type {
|
|||
size: None,
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Slice(
|
||||
Slice {
|
||||
element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
},
|
||||
),
|
||||
size: None,
|
||||
}
|
||||
Type {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue