Skip to content

Commit

Permalink
Auto merge of #61498 - TankhouseAle:const-fn-type-name, r=oli-obk
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jun 5, 2019
2 parents 2a1d6c8 + 70aeb22 commit 47f4975
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/librustc_mir/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc::mir::interpret::{
};

use super::{
Machine, PlaceTy, OpTy, InterpretCx,
Machine, PlaceTy, OpTy, InterpretCx, Immediate,
};

mod type_name;
Expand Down Expand Up @@ -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"
Expand Down
17 changes: 12 additions & 5 deletions src/librustc_mir/interpret/intrinsics/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 37 additions & 0 deletions src/test/run-pass/ctfe/const-fn-type-name.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 47f4975

Please sign in to comment.