Stabilize the type_name intrinsic in core::any

Closes rust-lang/rfcs#1428
This commit is contained in:
Steven Fackler 2019-04-17 19:38:17 -07:00
parent 03f19f7ff1
commit 91fa898975
14 changed files with 46 additions and 25 deletions

View File

@ -450,3 +450,29 @@ impl TypeId {
}
}
}
/// Returns the name of a type as a string slice.
///
/// # Note
///
/// This is intended for diagnostic use. The exact contents and format of the
/// string are not specified, other than being a best-effort description of the
/// type. For example, `type_name::<Option<String>>()` could return the
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
///
/// The type name should not be considered a unique identifier of a type;
/// multiple types may share the same type name.
///
/// The current implementation uses the same infrastructure as compiler
/// diagnostics and debuginfo, but this is not guaranteed.
#[stable(feature = "type_name", since = "1.38.0")]
pub fn type_name<T: ?Sized>() -> &'static str {
#[cfg(bootstrap)]
unsafe {
intrinsics::type_name::<T>()
}
#[cfg(not(bootstrap))]
intrinsics::type_name::<T>()
}

View File

@ -34,7 +34,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
{
debug!(
"normalize::<{}>(value={:?}, param_env={:?})",
unsafe { ::std::intrinsics::type_name::<T>() },
::std::any::type_name::<T>(),
value,
self.param_env,
);

View File

@ -22,7 +22,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
debug!(
"normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
unsafe { ::std::intrinsics::type_name::<T>() },
::std::any::type_name::<T>(),
value,
param_env,
);

View File

@ -69,7 +69,7 @@ impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
if !tcx.sess.verbose() {
format!("processing `{}`", tcx.def_path_str(def_id)).into()
} else {
let name = unsafe { ::std::intrinsics::type_name::<M>() };
let name = ::std::any::type_name::<M>();
format!("processing {:?} with query `{}`", def_id, name).into()
}
}

View File

@ -54,7 +54,7 @@ use rustc_target::spec::PanicStrategy;
use std::borrow::Cow;
use std::ops::Deref;
use std::sync::Arc;
use std::intrinsics::type_name;
use std::any::type_name;
use syntax_pos::{Span, DUMMY_SP};
use syntax_pos::symbol::InternedString;
use syntax::attr;

View File

@ -1060,7 +1060,7 @@ where
Q::Value: Encodable,
{
let desc = &format!("encode_query_results for {}",
unsafe { ::std::intrinsics::type_name::<Q>() });
::std::any::type_name::<Q>());
time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || {
let map = Q::query_cache(tcx).borrow();

View File

@ -782,9 +782,9 @@ macro_rules! define_queries_inner {
#[cfg(not(debug_assertions))]
cache_hits: 0,
key_size: mem::size_of::<Q::Key>(),
key_type: unsafe { type_name::<Q::Key>() },
key_type: type_name::<Q::Key>(),
value_size: mem::size_of::<Q::Value>(),
value_type: unsafe { type_name::<Q::Value>() },
value_type: type_name::<Q::Value>(),
entry_count: map.results.len(),
}
}

View File

@ -127,7 +127,7 @@ impl<'tcx> MirSource<'tcx> {
/// Generates a default name for the pass based on the name of the
/// type `T`.
pub fn default_name<T: ?Sized>() -> Cow<'static, str> {
let name = unsafe { ::std::intrinsics::type_name::<T>() };
let name = ::std::any::type_name::<T>();
if let Some(tail) = name.rfind(":") {
Cow::from(&name[tail+1..])
} else {

View File

@ -71,7 +71,7 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
"saturating_add" | "saturating_sub" |
"rotate_left" | "rotate_right" |
"ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
"minnumf32" | "minnumf64" | "maxnumf32" | "maxnumf64"
"minnumf32" | "minnumf64" | "maxnumf32" | "maxnumf64" | "type_name"
=> hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
}

View File

@ -4,8 +4,8 @@
Core encoding and decoding interfaces.
*/
use std::any;
use std::borrow::Cow;
use std::intrinsics;
use std::marker::PhantomData;
use std::path;
use std::rc::Rc;
@ -849,9 +849,9 @@ pub trait SpecializationError {
impl<E> SpecializationError for E {
default fn not_found<S, T: ?Sized>(trait_name: &'static str, method_name: &'static str) -> E {
panic!("missing specialization: `<{} as {}<{}>>::{}` not overridden",
unsafe { intrinsics::type_name::<S>() },
any::type_name::<S>(),
trait_name,
unsafe { intrinsics::type_name::<T>() },
any::type_name::<T>(),
method_name);
}
}

View File

@ -5,7 +5,7 @@
#![allow(dead_code)]
const fn type_name_wrapper<T>(_: &T) -> &'static str {
unsafe { core::intrinsics::type_name::<T>() }
core::intrinsics::type_name::<T>()
}
struct Struct<TA, TB, TC> {

View File

@ -1,6 +1,5 @@
// run-pass
#![allow(dead_code)]
#![feature(core_intrinsics)]
use std::fmt::Debug;
@ -12,7 +11,7 @@ macro_rules! check {
assert_eq!(type_name_of_val($ty_of), $expected);
};
($ty:ty, $expected:expr) => {
assert_eq!(unsafe { std::intrinsics::type_name::<$ty>()}, $expected);
assert_eq!(std::any::type_name::<$ty>(), $expected);
};
}
@ -50,7 +49,7 @@ fn bar<T: Trait>() {
}
fn type_name_of_val<T>(_: T) -> &'static str {
unsafe { std::intrinsics::type_name::<T>() }
std::any::type_name::<T>()
}
#[derive(Debug)]

View File

@ -1,6 +1,6 @@
#![feature(core_intrinsics)]
use std::intrinsics::type_name;
use std::any::type_name;
struct Bar<M>(M);
@ -8,7 +8,7 @@ impl<M> Bar<M> {
fn foo(&self) -> &'static str {
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
unsafe { type_name::<T>() }
type_name::<T>()
}
type_name_of(f)
}

View File

@ -1,16 +1,12 @@
#![allow(dead_code)]
#![feature(core_intrinsics)]
use std::intrinsics::type_name;
use std::any::type_name;
struct Foo<T> {
x: T
}
pub fn main() {
unsafe {
assert_eq!(type_name::<isize>(), "isize");
assert_eq!(type_name::<Foo<usize>>(), "tydesc_name::Foo<usize>");
}
assert_eq!(type_name::<isize>(), "isize");
assert_eq!(type_name::<Foo<usize>>(), "tydesc_name::Foo<usize>");
}