Auto merge of #61498 - TankhouseAle:const-fn-type-name, r=oli-obk
Add "type_name" support in emulate_intrinsic() I did some dumb Git things and deleted my original fork repo semi-accidentally (but probably for the best as I'd messed up the history.) This is the same issue as #61399, which was obviously auto-closed, to be clear.
This commit is contained in:
commit
47f4975cd7
@ -11,7 +11,7 @@ use rustc::mir::interpret::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
Machine, PlaceTy, OpTy, InterpretCx,
|
||||
Machine, PlaceTy, OpTy, InterpretCx, Immediate,
|
||||
};
|
||||
|
||||
mod type_name;
|
||||
@ -78,6 +78,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
||||
let id_val = Scalar::from_uint(type_id, dest.layout.size);
|
||||
self.write_scalar(id_val, dest)?;
|
||||
}
|
||||
|
||||
"type_name" => {
|
||||
let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
|
||||
let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
|
||||
let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
|
||||
let alloc_len = alloc.bytes.len() as u64;
|
||||
let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
|
||||
self.write_immediate(name_val, dest)?;
|
||||
}
|
||||
|
||||
| "ctpop"
|
||||
| "cttz"
|
||||
| "cttz_nonzero"
|
||||
|
@ -213,16 +213,23 @@ impl Write for AbsolutePathPrinter<'_, '_> {
|
||||
/// Produces an absolute path representation of the given type. See also the documentation on
|
||||
/// `std::any::type_name`
|
||||
pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
|
||||
let len = path.len();
|
||||
let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
|
||||
let alloc = tcx.intern_const_alloc(alloc);
|
||||
let alloc = alloc_type_name(tcx, ty);
|
||||
tcx.mk_const(ty::Const {
|
||||
val: ConstValue::Slice {
|
||||
data: alloc,
|
||||
start: 0,
|
||||
end: len,
|
||||
end: alloc.bytes.len(),
|
||||
},
|
||||
ty: tcx.mk_static_str(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
|
||||
pub(super) fn alloc_type_name<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>
|
||||
) -> &'tcx Allocation {
|
||||
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
|
||||
let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
|
||||
tcx.intern_const_alloc(alloc)
|
||||
}
|
||||
|
37
src/test/run-pass/ctfe/const-fn-type-name.rs
Normal file
37
src/test/run-pass/ctfe/const-fn-type-name.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(const_fn)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
const fn type_name_wrapper<T>(_: &T) -> &'static str {
|
||||
unsafe { core::intrinsics::type_name::<T>() }
|
||||
}
|
||||
|
||||
struct Struct<TA, TB, TC> {
|
||||
a: TA,
|
||||
b: TB,
|
||||
c: TC,
|
||||
}
|
||||
|
||||
type StructInstantiation = Struct<i8, f64, bool>;
|
||||
|
||||
const CONST_STRUCT: StructInstantiation = StructInstantiation {
|
||||
a: 12,
|
||||
b: 13.7,
|
||||
c: false,
|
||||
};
|
||||
|
||||
const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT);
|
||||
|
||||
fn main() {
|
||||
let non_const_struct = StructInstantiation {
|
||||
a: 87,
|
||||
b: 65.99,
|
||||
c: true,
|
||||
};
|
||||
|
||||
let non_const_struct_name = type_name_wrapper(&non_const_struct);
|
||||
|
||||
assert_eq!(CONST_STRUCT_NAME, non_const_struct_name);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user