diff --git a/src/libcore/any.rs b/src/libcore/any.rs index d043ce34effcd..f7aef66942d9b 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -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::>()` could return the +/// `"Option"` or `"std::option::Option"`, 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() -> &'static str { + #[cfg(bootstrap)] + unsafe { + intrinsics::type_name::() + } + #[cfg(not(bootstrap))] + intrinsics::type_name::() +} diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 55e622e46b966..2ffcd0fd4d941 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -34,7 +34,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { { debug!( "normalize::<{}>(value={:?}, param_env={:?})", - unsafe { ::std::intrinsics::type_name::() }, + ::std::any::type_name::(), value, self.param_env, ); diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs index 3218ff062ce5e..d09288461d444 100644 --- a/src/librustc/traits/query/normalize_erasing_regions.rs +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -22,7 +22,7 @@ impl<'tcx> TyCtxt<'tcx> { { debug!( "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", - unsafe { ::std::intrinsics::type_name::() }, + ::std::any::type_name::(), value, param_env, ); diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index b921272856e28..1cc083ea93c6c 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -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::() }; + let name = ::std::any::type_name::(); format!("processing {:?} with query `{}`", def_id, name).into() } } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index e788628bc58e2..f4b99ca368874 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -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; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index a25c1e34cf154..24bce7e338bd9 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -1060,7 +1060,7 @@ where Q::Value: Encodable, { let desc = &format!("encode_query_results for {}", - unsafe { ::std::intrinsics::type_name::() }); + ::std::any::type_name::()); time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || { let map = Q::query_cache(tcx).borrow(); diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 0c9e31e1ff28e..ce9f67db59232 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -782,9 +782,9 @@ macro_rules! define_queries_inner { #[cfg(not(debug_assertions))] cache_hits: 0, key_size: mem::size_of::(), - key_type: unsafe { type_name::() }, + key_type: type_name::(), value_size: mem::size_of::(), - value_type: unsafe { type_name::() }, + value_type: type_name::(), entry_count: map.results.len(), } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 9e23d06145330..195a652b0a2e6 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -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() -> Cow<'static, str> { - let name = unsafe { ::std::intrinsics::type_name::() }; + let name = ::std::any::type_name::(); if let Some(tail) = name.rfind(":") { Cow::from(&name[tail+1..]) } else { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 531ecd11dcb20..4d8f564123634 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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, } diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 2def2a455fb64..a5f7b4898ae0e 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -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 SpecializationError for E { default fn not_found(trait_name: &'static str, method_name: &'static str) -> E { panic!("missing specialization: `<{} as {}<{}>>::{}` not overridden", - unsafe { intrinsics::type_name::() }, + any::type_name::(), trait_name, - unsafe { intrinsics::type_name::() }, + any::type_name::(), method_name); } } diff --git a/src/test/run-pass/consts/const-fn-type-name.rs b/src/test/run-pass/consts/const-fn-type-name.rs index 2ee6415aa68b7..2bb1aeecf376d 100644 --- a/src/test/run-pass/consts/const-fn-type-name.rs +++ b/src/test/run-pass/consts/const-fn-type-name.rs @@ -5,7 +5,7 @@ #![allow(dead_code)] const fn type_name_wrapper(_: &T) -> &'static str { - unsafe { core::intrinsics::type_name::() } + core::intrinsics::type_name::() } struct Struct { diff --git a/src/test/run-pass/issues/issue-21058.rs b/src/test/run-pass/issues/issue-21058.rs index 3efa94ce6835c..6facf0b2dd578 100644 --- a/src/test/run-pass/issues/issue-21058.rs +++ b/src/test/run-pass/issues/issue-21058.rs @@ -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() { } fn type_name_of_val(_: T) -> &'static str { - unsafe { std::intrinsics::type_name::() } + std::any::type_name::() } #[derive(Debug)] diff --git a/src/test/run-pass/issues/issue-61894.rs b/src/test/run-pass/issues/issue-61894.rs index 9ab969be46a45..4d407125299a7 100644 --- a/src/test/run-pass/issues/issue-61894.rs +++ b/src/test/run-pass/issues/issue-61894.rs @@ -1,6 +1,6 @@ #![feature(core_intrinsics)] -use std::intrinsics::type_name; +use std::any::type_name; struct Bar(M); @@ -8,7 +8,7 @@ impl Bar { fn foo(&self) -> &'static str { fn f() {} fn type_name_of(_: T) -> &'static str { - unsafe { type_name::() } + type_name::() } type_name_of(f) } diff --git a/src/test/run-pass/tydesc-name.rs b/src/test/run-pass/tydesc-name.rs index 91578b71d04ae..d9d947bd4c062 100644 --- a/src/test/run-pass/tydesc-name.rs +++ b/src/test/run-pass/tydesc-name.rs @@ -1,16 +1,12 @@ #![allow(dead_code)] -#![feature(core_intrinsics)] - -use std::intrinsics::type_name; +use std::any::type_name; struct Foo { x: T } pub fn main() { - unsafe { - assert_eq!(type_name::(), "isize"); - assert_eq!(type_name::>(), "tydesc_name::Foo"); - } + assert_eq!(type_name::(), "isize"); + assert_eq!(type_name::>(), "tydesc_name::Foo"); }