mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Parameterize DynMetadata
over its dyn SomeTrait
type
This commit is contained in:
parent
696b239f72
commit
b1e15fa8a2
@ -2164,7 +2164,10 @@ impl<'tcx> TyS<'tcx> {
|
||||
| ty::Tuple(..) => tcx.types.unit,
|
||||
|
||||
ty::Str | ty::Slice(_) => tcx.types.usize,
|
||||
ty::Dynamic(..) => tcx.type_of(tcx.lang_items().dyn_metadata().unwrap()),
|
||||
ty::Dynamic(..) => {
|
||||
let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap();
|
||||
tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()])
|
||||
},
|
||||
|
||||
ty::Projection(_)
|
||||
| ty::Param(_)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![unstable(feature = "ptr_metadata", issue = /* FIXME */ "none")]
|
||||
|
||||
use crate::fmt;
|
||||
use crate::hash::Hash;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
/// FIXME docs
|
||||
@ -61,17 +61,60 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
|
||||
|
||||
/// The metadata for a `dyn SomeTrait` trait object type.
|
||||
#[lang = "dyn_metadata"]
|
||||
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||
pub struct DynMetadata {
|
||||
pub struct DynMetadata<Dyn: ?Sized> {
|
||||
#[allow(unused)]
|
||||
vtable_ptr: NonNull<()>,
|
||||
phantom: crate::marker::PhantomData<Dyn>,
|
||||
}
|
||||
|
||||
unsafe impl Send for DynMetadata {}
|
||||
unsafe impl Sync for DynMetadata {}
|
||||
unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {}
|
||||
unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
|
||||
|
||||
impl fmt::Debug for DynMetadata {
|
||||
impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("DynMetadata { … }")
|
||||
}
|
||||
}
|
||||
|
||||
// Manual impls needed to avoid `Dyn: $Trait` bounds.
|
||||
|
||||
impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.vtable_ptr == other.vtable_ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
|
||||
self.vtable_ptr.cmp(&other.vtable_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> {
|
||||
Some(self.vtable_ptr.cmp(&other.vtable_ptr))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
self.vtable_ptr.hash(hasher)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::cell::RefCell;
|
||||
use core::ptr::*;
|
||||
use std::fmt::Display;
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
#[test]
|
||||
fn test_const_from_raw_parts() {
|
||||
@ -452,20 +452,25 @@ fn ptr_metadata() {
|
||||
assert_eq!(metadata(dst_struct), 3_usize);
|
||||
}
|
||||
|
||||
let vtable_1: DynMetadata = metadata(&4_u32 as &dyn Display);
|
||||
let vtable_2: DynMetadata = metadata(&(true, 7_u32) as &(bool, dyn Display));
|
||||
let vtable_3: DynMetadata = metadata(&Pair(true, 7_u32) as &Pair<bool, dyn Display>);
|
||||
let vtable_4: DynMetadata = metadata(&4_u16 as &dyn Display);
|
||||
let vtable_1: DynMetadata<dyn Debug> = metadata(&4_u16 as &dyn Debug);
|
||||
let vtable_2: DynMetadata<dyn Display> = metadata(&4_u16 as &dyn Display);
|
||||
let vtable_3: DynMetadata<dyn Display> = metadata(&4_u32 as &dyn Display);
|
||||
let vtable_4: DynMetadata<dyn Display> = metadata(&(true, 7_u32) as &(bool, dyn Display));
|
||||
let vtable_5: DynMetadata<dyn Display> =
|
||||
metadata(&Pair(true, 7_u32) as &Pair<bool, dyn Display>);
|
||||
unsafe {
|
||||
let address_1: usize = std::mem::transmute(vtable_1);
|
||||
let address_2: usize = std::mem::transmute(vtable_2);
|
||||
let address_3: usize = std::mem::transmute(vtable_3);
|
||||
let address_4: usize = std::mem::transmute(vtable_4);
|
||||
// Same erased type and same trait: same vtable pointer
|
||||
assert_eq!(address_1, address_2);
|
||||
assert_eq!(address_1, address_3);
|
||||
// Different erased type: different vtable pointer
|
||||
assert_ne!(address_1, address_4);
|
||||
let address_5: usize = std::mem::transmute(vtable_5);
|
||||
// Different trait => different vtable pointer
|
||||
assert_ne!(address_1, address_2);
|
||||
// Different erased type => different vtable pointer
|
||||
assert_ne!(address_2, address_3);
|
||||
// Same erased type and same trait => same vtable pointer
|
||||
assert_eq!(address_3, address_4);
|
||||
assert_eq!(address_3, address_5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,11 +491,11 @@ fn ptr_metadata_bounds() {
|
||||
|
||||
// For this reason, let’s check here that bounds are satisfied:
|
||||
|
||||
static_assert_expected_bounds_for_metadata::<()>();
|
||||
static_assert_expected_bounds_for_metadata::<usize>();
|
||||
static_assert_expected_bounds_for_metadata::<DynMetadata>();
|
||||
fn static_assert_associated_type<T: ?Sized>() {
|
||||
static_assert_expected_bounds_for_metadata::<<T as Pointee>::Metadata>()
|
||||
let _ = static_assert_expected_bounds_for_metadata::<()>;
|
||||
let _ = static_assert_expected_bounds_for_metadata::<usize>;
|
||||
let _ = static_assert_expected_bounds_for_metadata::<DynMetadata<dyn Display>>;
|
||||
fn _static_assert_associated_type<T: ?Sized>() {
|
||||
let _ = static_assert_expected_bounds_for_metadata::<<T as Pointee>::Metadata>;
|
||||
}
|
||||
|
||||
fn static_assert_expected_bounds_for_metadata<Meta>()
|
||||
|
Loading…
Reference in New Issue
Block a user