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:
bors 2019-06-05 15:40:16 +00:00
commit 47f4975cd7
3 changed files with 60 additions and 6 deletions

View File

@ -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"

View File

@ -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)
}

View 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);
}