Rollup merge of #60066 - sfackler:type-name, r=Centril
Stabilize the type_name intrinsic in core::any Stabilize `type_name` in `core::any`. Closes rust-lang/rfcs#1428 FCP completed over there. `RELEASES.md`: Prefer T-libs for categorization.
This commit is contained in:
commit
3b19dc96fc
@ -450,3 +450,29 @@ pub const fn of<T: ?Sized + 'static>() -> 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>()
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
|
||||
{
|
||||
debug!(
|
||||
"normalize::<{}>(value={:?}, param_env={:?})",
|
||||
unsafe { ::std::intrinsics::type_name::<T>() },
|
||||
::std::any::type_name::<T>(),
|
||||
value,
|
||||
self.param_env,
|
||||
);
|
||||
|
@ -22,7 +22,7 @@ pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value:
|
||||
{
|
||||
debug!(
|
||||
"normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
|
||||
unsafe { ::std::intrinsics::type_name::<T>() },
|
||||
::std::any::type_name::<T>(),
|
||||
value,
|
||||
param_env,
|
||||
);
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
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;
|
||||
|
@ -1060,7 +1060,7 @@ fn encode_query_results<'a, 'tcx, Q, E>(
|
||||
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();
|
||||
|
@ -782,9 +782,9 @@ fn stats<'tcx, Q: QueryConfig<'tcx>>(
|
||||
#[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(),
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ pub fn def_id(&self) -> DefId {
|
||||
/// 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 {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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>");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user