diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index bb25a14ef7443..719acc9b6b4aa 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -332,7 +332,11 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe // Ensure none of the other fields mention the parameters used // in unsizing. for field in prefix_fields { - for arg in tcx.type_of(field.did).instantiate_identity().walk() { + let field_ty = tcx.type_of(field.did).instantiate_identity(); + if field_ty.is_phantom_data() { + continue; + } + for arg in field_ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 68f22767d6cf0..0a76b64c09325 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -218,7 +218,7 @@ pub trait PointeeSized { /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize>` /// where any number of (type and const) parameters may be changed if all of these conditions /// are met: -/// - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`. +/// - Other than `PhantomData<_>` fields, only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`. /// - All other parameters of the struct are equal. /// - `Field: Unsize>`, where `Field<...>` stands for the actual /// type of the struct's last field. diff --git a/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs b/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs index f5f66ca69cfc1..a3ed983a1d88b 100644 --- a/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs +++ b/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs @@ -68,4 +68,16 @@ where { } +struct Ptr(Box); + +impl<'a, T: ?Sized, U: ?Sized> DispatchFromDyn<&'a Ptr> for &'a Ptr {} +//~^ ERROR conflicting implementations of trait `DispatchFromDyn<&Ptr<_>>` for type `&Ptr<_>` + +struct Inner(T); +#[repr(transparent)] +struct Outer(PhantomData, Inner); + +impl<'a, T: Unsize + ?Sized, U: ?Sized> DispatchFromDyn<&'a Outer> for &'a Outer {} +//~^ ERROR conflicting implementations of trait `DispatchFromDyn<&Outer<_>>` for type `&Outer<_>` + fn main() {} diff --git a/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr b/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr index 676da0ce81fb1..618e8906a3341 100644 --- a/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr +++ b/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr @@ -1,3 +1,24 @@ +error[E0119]: conflicting implementations of trait `DispatchFromDyn<&Ptr<_>>` for type `&Ptr<_>` + --> $DIR/dispatch-from-dyn-invalid-impls.rs:73:1 + | +LL | impl<'a, T: ?Sized, U: ?Sized> DispatchFromDyn<&'a Ptr> for &'a Ptr {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<'a, T, U> DispatchFromDyn<&'a U> for &'a T + where T: Unsize, T: ?Sized, U: ?Sized; + = note: downstream crates may implement trait `std::marker::Unsize>` for type `std::boxed::Box<_>` + +error[E0119]: conflicting implementations of trait `DispatchFromDyn<&Outer<_>>` for type `&Outer<_>` + --> $DIR/dispatch-from-dyn-invalid-impls.rs:80:1 + | +LL | impl<'a, T: Unsize + ?Sized, U: ?Sized> DispatchFromDyn<&'a Outer> for &'a Outer {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<'a, T, U> DispatchFromDyn<&'a U> for &'a T + where T: Unsize, T: ?Sized, U: ?Sized; + error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else --> $DIR/dispatch-from-dyn-invalid-impls.rs:19:1 | @@ -54,7 +75,7 @@ LL | | T: Unsize | = note: extra field `1` of type `OverAlignedZst` is not allowed -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0374, E0375, E0378. -For more information about an error, try `rustc --explain E0374`. +Some errors have detailed explanations: E0119, E0374, E0375, E0378. +For more information about an error, try `rustc --explain E0119`.