feat: Support references in reflection type info
This commit is contained in:
parent
503745e917
commit
c7031e93c5
7 changed files with 161 additions and 8 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use rustc_abi::FieldIdx;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::mir::interpret::{CtfeProvenance, Scalar};
|
||||
use rustc_middle::span_bug;
|
||||
|
|
@ -103,12 +104,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
|
|||
let (variant, _variant_place) = downcast(sym::Str)?;
|
||||
variant
|
||||
}
|
||||
ty::Ref(_, ty, mutability) => {
|
||||
let (variant, variant_place) = downcast(sym::Reference)?;
|
||||
let reference_place =
|
||||
self.project_field(&variant_place, FieldIdx::ZERO)?;
|
||||
self.write_reference_type_info(reference_place, *ty, *mutability)?;
|
||||
|
||||
variant
|
||||
}
|
||||
ty::Adt(_, _)
|
||||
| ty::Foreign(_)
|
||||
| ty::Pat(_, _)
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::UnsafeBinder(..)
|
||||
|
|
@ -279,4 +287,29 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
|
|||
}
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn write_reference_type_info(
|
||||
&mut self,
|
||||
place: impl Writeable<'tcx, CtfeProvenance>,
|
||||
ty: Ty<'tcx>,
|
||||
mutability: Mutability,
|
||||
) -> InterpResult<'tcx> {
|
||||
// Iterate over all fields of `type_info::Reference`.
|
||||
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 reference's inner type to the `ty` field.
|
||||
sym::pointee => self.write_type_id(ty, &field_place)?,
|
||||
// Write the boolean representing the reference's mutability to the `mutable` field.
|
||||
sym::mutable => {
|
||||
self.write_scalar(Scalar::from_bool(mutability.is_mut()), &field_place)?
|
||||
}
|
||||
other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
|
||||
}
|
||||
}
|
||||
interp_ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ symbols! {
|
|||
RefCell,
|
||||
RefCellRef,
|
||||
RefCellRefMut,
|
||||
Reference,
|
||||
Relaxed,
|
||||
Release,
|
||||
Result,
|
||||
|
|
@ -1521,6 +1522,7 @@ symbols! {
|
|||
must_use,
|
||||
mut_preserve_binding_mode_2024,
|
||||
mut_ref,
|
||||
mutable,
|
||||
naked,
|
||||
naked_asm,
|
||||
naked_functions,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ pub enum TypeKind {
|
|||
Float(Float),
|
||||
/// String slice type.
|
||||
Str(Str),
|
||||
/// References.
|
||||
Reference(Reference),
|
||||
/// FIXME(#146922): add all the common types
|
||||
Other,
|
||||
}
|
||||
|
|
@ -133,3 +135,14 @@ pub struct Float {
|
|||
pub struct Str {
|
||||
// No additional information to provide for now.
|
||||
}
|
||||
|
||||
/// Compile-time type information about references.
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[unstable(feature = "type_info", issue = "146922")]
|
||||
pub struct Reference {
|
||||
/// The type of the value being referred to.
|
||||
pub pointee: TypeId,
|
||||
/// Whether this reference is mutable or not.
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::any::TypeId;
|
||||
use std::any::{Any, TypeId};
|
||||
use std::mem::type_info::{Type, TypeKind};
|
||||
|
||||
#[test]
|
||||
|
|
@ -95,3 +95,33 @@ fn test_primitives() {
|
|||
let Type { kind: Str(_ty), size, .. } = (const { Type::of::<str>() }) else { panic!() };
|
||||
assert_eq!(size, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_references() {
|
||||
// Immutable reference.
|
||||
match const { Type::of::<&u8>() }.kind {
|
||||
TypeKind::Reference(reference) => {
|
||||
assert_eq!(reference.pointee, TypeId::of::<u8>());
|
||||
assert!(!reference.mutable);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
// Mutable pointer.
|
||||
match const { Type::of::<&mut u64>() }.kind {
|
||||
TypeKind::Reference(reference) => {
|
||||
assert_eq!(reference.pointee, TypeId::of::<u64>());
|
||||
assert!(reference.mutable);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
// Wide pointer.
|
||||
match const { Type::of::<&dyn Any>() }.kind {
|
||||
TypeKind::Reference(reference) => {
|
||||
assert_eq!(reference.pointee, TypeId::of::<dyn Any>());
|
||||
assert!(!reference.mutable);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,19 +155,34 @@ Type {
|
|||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0xda1b6da9bd297bb2900de9303aadea79),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
8,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
8,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x641e3def269c37acc6dcb92bf8c5f196),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
8,
|
||||
),
|
||||
|
|
@ -182,3 +197,25 @@ Type {
|
|||
kind: Other,
|
||||
size: None,
|
||||
}
|
||||
Type {
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
4,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
mutable: true,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
4,
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,19 +155,34 @@ Type {
|
|||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0xda1b6da9bd297bb2900de9303aadea79),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
16,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
16,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Other,
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x641e3def269c37acc6dcb92bf8c5f196),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
16,
|
||||
),
|
||||
|
|
@ -182,3 +197,25 @@ Type {
|
|||
kind: Other,
|
||||
size: None,
|
||||
}
|
||||
Type {
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
mutable: false,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
8,
|
||||
),
|
||||
}
|
||||
Type {
|
||||
kind: Reference(
|
||||
Reference {
|
||||
pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
|
||||
mutable: true,
|
||||
},
|
||||
),
|
||||
size: Some(
|
||||
8,
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,5 +40,6 @@ fn main() {
|
|||
Foo, Bar,
|
||||
&Unsized, &str, &[u8],
|
||||
str, [u8],
|
||||
&u8, &mut u8,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue