Skip to content

Commit 47f4975

Browse files
committed
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.
2 parents 2a1d6c8 + 70aeb22 commit 47f4975

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
lines changed

src/librustc_mir/interpret/intrinsics.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc::mir::interpret::{
1111
};
1212

1313
use super::{
14-
Machine, PlaceTy, OpTy, InterpretCx,
14+
Machine, PlaceTy, OpTy, InterpretCx, Immediate,
1515
};
1616

1717
mod type_name;
@@ -78,6 +78,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
7878
let id_val = Scalar::from_uint(type_id, dest.layout.size);
7979
self.write_scalar(id_val, dest)?;
8080
}
81+
82+
"type_name" => {
83+
let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
84+
let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
85+
let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
86+
let alloc_len = alloc.bytes.len() as u64;
87+
let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
88+
self.write_immediate(name_val, dest)?;
89+
}
90+
8191
| "ctpop"
8292
| "cttz"
8393
| "cttz_nonzero"

src/librustc_mir/interpret/intrinsics/type_name.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,23 @@ impl Write for AbsolutePathPrinter<'_, '_> {
213213
/// Produces an absolute path representation of the given type. See also the documentation on
214214
/// `std::any::type_name`
215215
pub fn type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
216-
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
217-
let len = path.len();
218-
let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
219-
let alloc = tcx.intern_const_alloc(alloc);
216+
let alloc = alloc_type_name(tcx, ty);
220217
tcx.mk_const(ty::Const {
221218
val: ConstValue::Slice {
222219
data: alloc,
223220
start: 0,
224-
end: len,
221+
end: alloc.bytes.len(),
225222
},
226223
ty: tcx.mk_static_str(),
227224
})
228225
}
226+
227+
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
228+
pub(super) fn alloc_type_name<'a, 'tcx>(
229+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
230+
ty: Ty<'tcx>
231+
) -> &'tcx Allocation {
232+
let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
233+
let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
234+
tcx.intern_const_alloc(alloc)
235+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// run-pass
2+
3+
#![feature(core_intrinsics)]
4+
#![feature(const_fn)]
5+
#![allow(dead_code)]
6+
7+
const fn type_name_wrapper<T>(_: &T) -> &'static str {
8+
unsafe { core::intrinsics::type_name::<T>() }
9+
}
10+
11+
struct Struct<TA, TB, TC> {
12+
a: TA,
13+
b: TB,
14+
c: TC,
15+
}
16+
17+
type StructInstantiation = Struct<i8, f64, bool>;
18+
19+
const CONST_STRUCT: StructInstantiation = StructInstantiation {
20+
a: 12,
21+
b: 13.7,
22+
c: false,
23+
};
24+
25+
const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT);
26+
27+
fn main() {
28+
let non_const_struct = StructInstantiation {
29+
a: 87,
30+
b: 65.99,
31+
c: true,
32+
};
33+
34+
let non_const_struct_name = type_name_wrapper(&non_const_struct);
35+
36+
assert_eq!(CONST_STRUCT_NAME, non_const_struct_name);
37+
}

0 commit comments

Comments
 (0)