77 decl_macro,
88 rustc_attrs,
99 transparent_unions,
10+ pattern_types,
1011 auto_traits,
1112 freeze_impls
1213) ]
1314#![ cfg_attr( not( all( windows, target_env = "gnu" ) ) , feature( thread_local) ) ]
1415#![ no_core]
1516#![ allow( dead_code, internal_features, ambiguous_wide_pointer_comparisons) ]
1617
18+ #[ lang = "pointee_trait" ]
19+ pub trait Pointee : PointeeSized {
20+ #[ lang = "metadata_type" ]
21+ // needed so that layout_of will return `TooGeneric` instead of `Unknown`
22+ // when asked for the layout of `*const T`. Which is important for making
23+ // transmutes between raw pointers (and especially pattern types of raw pointers)
24+ // work.
25+ type Metadata : Copy + Sync + Unpin + Freeze ;
26+ }
27+
28+ #[ lang = "dyn_metadata" ]
29+ pub struct DynMetadata < Dyn : PointeeSized > {
30+ _vtable_ptr : NonNull < VTable > ,
31+ _phantom : PhantomData < Dyn > ,
32+ }
33+
34+ unsafe extern "C" {
35+ /// Opaque type for accessing vtables.
36+ ///
37+ /// Private implementation detail of `DynMetadata::size_of` etc.
38+ /// There is conceptually not actually any Abstract Machine memory behind this pointer.
39+ type VTable ;
40+ }
41+
1742#[ lang = "pointee_sized" ]
1843pub trait PointeeSized { }
1944
@@ -104,7 +129,7 @@ unsafe impl<'a, T: PointeeSized> Sync for &'a T {}
104129unsafe impl < T : Sync , const N : usize > Sync for [ T ; N ] { }
105130
106131#[ lang = "freeze" ]
107- unsafe auto trait Freeze { }
132+ pub unsafe auto trait Freeze { }
108133
109134unsafe impl < T : PointeeSized > Freeze for PhantomData < T > { }
110135unsafe impl < T : PointeeSized > Freeze for * const T { }
@@ -569,10 +594,24 @@ pub trait Deref {
569594 fn deref ( & self ) -> & Self :: Target ;
570595}
571596
597+ #[ rustc_builtin_macro( pattern_type) ]
598+ #[ macro_export]
599+ macro_rules! pattern_type {
600+ ( $( $arg: tt) * ) => {
601+ /* compiler built-in */
602+ } ;
603+ }
604+
605+ impl < T : PointeeSized , U : PointeeSized > CoerceUnsized < pattern_type ! ( * const U is !null) > for pattern_type ! ( * const T is !null) where
606+ T : Unsize < U >
607+ {
608+ }
609+
610+ impl < T : DispatchFromDyn < U > , U > DispatchFromDyn < pattern_type ! ( U is !null) > for pattern_type ! ( T is !null) { }
611+
572612#[ repr( transparent) ]
573- #[ rustc_layout_scalar_valid_range_start( 1 ) ]
574613#[ rustc_nonnull_optimization_guaranteed]
575- pub struct NonNull < T : PointeeSized > ( pub * const T ) ;
614+ pub struct NonNull < T : PointeeSized > ( pub pattern_type ! ( * const T is !null ) ) ;
576615
577616impl < T : PointeeSized , U : PointeeSized > CoerceUnsized < NonNull < U > > for NonNull < T > where T : Unsize < U > { }
578617impl < T : PointeeSized , U : PointeeSized > DispatchFromDyn < NonNull < U > > for NonNull < T > where T : Unsize < U > { }
@@ -599,7 +638,16 @@ impl<T> Box<T> {
599638 let size = size_of :: < T > ( ) ;
600639 let ptr = libc:: malloc ( size) ;
601640 intrinsics:: copy ( & val as * const T as * const u8 , ptr, size) ;
602- Box ( Unique { pointer : NonNull ( ptr as * const T ) , _marker : PhantomData } , Global )
641+ Box (
642+ Unique {
643+ pointer : NonNull ( intrinsics:: transmute :: <
644+ * mut u8 ,
645+ pattern_type ! ( * const T is !null) ,
646+ > ( ptr) ) ,
647+ _marker : PhantomData ,
648+ } ,
649+ Global ,
650+ )
603651 }
604652 }
605653}
@@ -608,7 +656,9 @@ impl<T: ?Sized, A> Drop for Box<T, A> {
608656 fn drop ( & mut self ) {
609657 // inner value is dropped by compiler
610658 unsafe {
611- libc:: free ( self . 0 . pointer . 0 as * mut u8 ) ;
659+ libc:: free ( intrinsics:: transmute :: < pattern_type ! ( * const T is !null) , * const T > (
660+ self . 0 . pointer . 0 ,
661+ ) as * mut u8 ) ;
612662 }
613663 }
614664}
0 commit comments