|
| 1 | +// revisions: traits lifetimes |
| 2 | +#![feature(ptr_metadata, ptr_metadata_cast)] |
| 3 | + |
| 4 | +use std::ptr::{Pointee, MetadataCast, DynMetadata}; |
| 5 | + |
| 6 | +fn cast<T: ?Sized, U: ?Sized>(_: *mut T) -> *mut U |
| 7 | +where |
| 8 | + <T as Pointee>::Metadata: MetadataCast<<U as Pointee>::Metadata>, |
| 9 | +{ |
| 10 | + todo!() |
| 11 | +} |
| 12 | + |
| 13 | +fn check<T: ?Sized, U: ?Sized>() where T: MetadataCast<U> {} |
| 14 | + |
| 15 | +trait Trait {} |
| 16 | +trait Trait2 {} |
| 17 | + |
| 18 | +fn main() { |
| 19 | + // any to () is OK |
| 20 | + check::<(), ()>(); |
| 21 | + check::<usize, ()>(); |
| 22 | + check::<DynMetadata<dyn Trait>, ()>(); |
| 23 | + |
| 24 | + // same types are OK |
| 25 | + check::<usize, usize>(); |
| 26 | + check::<i32, i32>(); |
| 27 | + check::<DynMetadata<dyn Trait>, DynMetadata<dyn Trait>>(); |
| 28 | + |
| 29 | + // changing auto traits of trait object in DynMetadata is OK |
| 30 | + check::<DynMetadata<dyn Send>, DynMetadata<dyn Sync>>(); |
| 31 | + check::<DynMetadata<dyn Trait + Send>, DynMetadata<dyn Trait + Sync>>(); |
| 32 | + |
| 33 | + #[cfg(traits)] |
| 34 | + { |
| 35 | + check::<(), usize>(); //[traits]~ ERROR not satisfied |
| 36 | + check::<(), DynMetadata<dyn Trait>>(); //[traits]~ ERROR not satisfied |
| 37 | + check::<usize, DynMetadata<dyn Trait>>(); //[traits]~ ERROR not satisfied |
| 38 | + check::<DynMetadata<dyn Trait>, usize>(); //[traits]~ ERROR not satisfied |
| 39 | + check::<DynMetadata<dyn Trait>, DynMetadata<dyn Trait2>>(); //[traits]~ ERROR not satisfied |
| 40 | + check::<dyn Trait + Send, dyn Trait + Sync>(); //[traits]~ ERROR not satisfied |
| 41 | + } |
| 42 | + |
| 43 | + // `dyn MetadataCast<usize>` should not implement `MetadataCast<usize>` |
| 44 | + check::<dyn MetadataCast<usize>, ()>(); |
| 45 | + check::<dyn MetadataCast<usize>, dyn MetadataCast<usize>>(); |
| 46 | + #[cfg(traits)] |
| 47 | + check::<dyn MetadataCast<usize>, usize>(); //[traits]~ ERROR not satisfied |
| 48 | + |
| 49 | + // this could pass in the future, but for now it matches the behavior of `as` casts |
| 50 | + #[cfg(traits)] |
| 51 | + check::<DynMetadata<dyn Trait>, DynMetadata<dyn Send>>(); //[traits]~ ERROR not satisfied |
| 52 | +} |
| 53 | + |
| 54 | +fn lifetimes_ok<'a, 'b>() { |
| 55 | + // changing lifetimes of trait object in DynMetadata is OK |
| 56 | + check::<DynMetadata<dyn Trait + 'a>, DynMetadata<dyn Trait + 'b>>(); |
| 57 | + check::<DynMetadata<dyn Trait + 'b>, DynMetadata<dyn Trait + 'a>>(); |
| 58 | + |
| 59 | + // otherwise, require equal lifetimes |
| 60 | + check::<&'a (), &'a ()>(); |
| 61 | +} |
| 62 | +fn lifetimes_err1<'a, 'b>() { |
| 63 | + check::<DynMetadata<&'a ()>, DynMetadata<&'b ()>>(); |
| 64 | + //[lifetimes]~^ ERROR may not live long enough |
| 65 | + //[lifetimes]~| ERROR may not live long enough |
| 66 | +} |
| 67 | +fn lifetimes_err2<'a, 'b>() { |
| 68 | + check::<&'a (), &'b ()>(); |
| 69 | + //[lifetimes]~^ ERROR may not live long enough |
| 70 | + //[lifetimes]~| ERROR may not live long enough |
| 71 | +} |
| 72 | + |
| 73 | +fn do_casts<'a>(thin: &mut i32, slice: &mut [i32], trait_object: &mut dyn Trait) { |
| 74 | + let _: *mut u8 = cast(thin); |
| 75 | + let _: *mut u8 = cast(slice); |
| 76 | + let _: *mut [u8] = cast(slice); |
| 77 | + let _: *mut u8 = cast(trait_object); |
| 78 | + let _: *mut (dyn Trait + Send + 'a) = cast(trait_object); |
| 79 | + |
| 80 | + |
| 81 | + #[cfg(traits)] |
| 82 | + { |
| 83 | + let _: *mut [u8] = cast(thin); //[traits]~ ERROR not satisfied |
| 84 | + let _: *mut dyn Trait = cast(thin); //[traits]~ ERROR not satisfied |
| 85 | + let _: *mut [u8] = cast(trait_object); //[traits]~ ERROR not satisfied |
| 86 | + let _: *mut dyn Trait = cast(slice); //[traits]~ ERROR not satisfied |
| 87 | + let _: *mut dyn Trait2 = cast(trait_object); //[traits]~ ERROR not satisfied |
| 88 | + |
| 89 | + // may be allowed in the future |
| 90 | + let _: *mut dyn Send = cast(trait_object); //[traits]~ ERROR not satisfied |
| 91 | + } |
| 92 | +} |
0 commit comments