/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
+// This trait is not unsafe, though we rely on the specifics of it's sole impl's
+// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
+// a problem, but because the only impl of `Any` is a blanket implementation, no
+// other code can implement `Any`.
+//
+// We could plausibly make this trait unsafe -- it would not cause breakage,
+// since we control all the implementations -- but we choose not to as that's
+// both not really necessary and may confuse users about the distinction of
+// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
+// but we would likely want to indicate as such in documentation).
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: 'static {
/// Gets the `TypeId` of `self`.
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: 'static + ?Sized > Any for T {
- fn type_id(&self) -> TypeId { TypeId::of::<T>() }
+impl<T: 'static + ?Sized> Any for T {
+ fn type_id(&self) -> TypeId {
+ TypeId::of::<T>()
+ }
}
///////////////////////////////////////////////////////////////////////////////
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
if self.is::<T>() {
// SAFETY: just checked whether we are pointing to the correct type
- unsafe {
- Some(&*(self as *const dyn Any as *const T))
- }
+ unsafe { Some(&*(self as *const dyn Any as *const T)) }
} else {
None
}
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
// SAFETY: just checked whether we are pointing to the correct type
- unsafe {
- Some(&mut *(self as *mut dyn Any as *mut T))
- }
+ unsafe { Some(&mut *(self as *mut dyn Any as *mut T)) }
} else {
None
}
}
}
-impl dyn Any+Send {
+impl dyn Any + Send {
/// Forwards to the method defined on the type `Any`.
///
/// # Examples
}
}
-impl dyn Any+Send+Sync {
+impl dyn Any + Send + Sync {
/// Forwards to the method defined on the type `Any`.
///
/// # Examples
/// assert_eq!(is_string(&"cookie monster".to_string()), true);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature="const_type_id", issue = "41875")]
+ #[rustc_const_unstable(feature = "const_type_id", issue = "41875")]
pub const fn of<T: ?Sized + 'static>() -> TypeId {
- TypeId {
- t: intrinsics::type_id::<T>(),
- }
+ TypeId { t: intrinsics::type_id::<T>() }
}
}
///
/// 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_of::<Option<String>>(None)` could return
+/// type. For example, `type_name_of_val::<Option<String>>(None)` could return
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
///
+/// This function does not resolve trait objects,
+/// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
+/// may return `"dyn Debug"`, but not `"u32"`.
+///
/// The type name should not be considered a unique identifier of a type;
/// multiple types may share the same type name.
///
/// ```
#[unstable(feature = "type_name_of_val", issue = "66359")]
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
-pub const fn type_name_of_val<T: ?Sized>(val: &T) -> &'static str {
- let _ = val;
+pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
type_name::<T>()
}