Fix unsize coerce for structs containing PhantomData
like Unique
This commit is contained in:
parent
73248114ea
commit
19eb4194b2
@ -12,6 +12,7 @@ pub trait Unsize<T: ?Sized> {}
|
||||
pub trait CoerceUnsized<T> {}
|
||||
|
||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
||||
|
||||
#[lang = "copy"]
|
||||
@ -169,6 +170,9 @@ impl<T: ?Sized> PartialEq for *const T {
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "phantom_data"]
|
||||
pub struct PhantomData<T: ?Sized>;
|
||||
|
||||
#[lang = "fn_once"]
|
||||
#[rustc_paren_sugar]
|
||||
pub trait FnOnce<Args> {
|
||||
|
@ -102,6 +102,13 @@ macro_rules! assert_eq {
|
||||
}
|
||||
}
|
||||
|
||||
struct Unique<T: ?Sized> {
|
||||
pointer: *const T,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let hello: &[u8] = b"Hello\0" as &[u8; 6];
|
||||
@ -133,6 +140,11 @@ fn main() {
|
||||
|
||||
assert!(!intrinsics::needs_drop::<u8>());
|
||||
assert!(intrinsics::needs_drop::<NoisyDrop>());
|
||||
|
||||
Unique {
|
||||
pointer: 0 as *const &str,
|
||||
_marker: PhantomData,
|
||||
} as Unique<dyn SomeTrait>;
|
||||
}
|
||||
|
||||
let _ = NoisyDrop {
|
||||
|
@ -259,6 +259,17 @@ impl<'tcx> CValue<'tcx> {
|
||||
for idx in 0..field_count {
|
||||
let field_dest = dest.place_field(fx, mir::Field::new(idx));
|
||||
let field_src = self.value_field(fx, mir::Field::new(idx));
|
||||
if field_src.layout().ty.is_phantom_data() {
|
||||
// Ignore PhantomData so for example `Unique<()>` can coerce to `Unique<Debug>`
|
||||
//
|
||||
// ```rust
|
||||
// struct Unique<T: ?Sized> {
|
||||
// pointer: NonZero<*const T>,
|
||||
// _marker: PhantomData<T>,
|
||||
// }
|
||||
// ```
|
||||
continue;
|
||||
}
|
||||
if field_src.layout().ty != field_dest.layout().ty {
|
||||
assert!(!found_unsize_field);
|
||||
found_unsize_field = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user