diff options
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/builtin.rs | 16 | ||||
| -rw-r--r-- | tests/ui/deriving/deriving-coerce-pointee-neg.rs | 3 | ||||
| -rw-r--r-- | tests/ui/deriving/deriving-coerce-pointee-neg.stderr | 49 |
3 files changed, 19 insertions, 49 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 9d6bb1cf6bf..cee2f487639 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -195,8 +195,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E // Just compute this for the side-effects, in particular reporting // errors; other parts of the code may demand it for the info of // course. - let span = tcx.def_span(impl_did); - tcx.at(span).ensure_ok().coerce_unsized_info(impl_did) + tcx.ensure_ok().coerce_unsized_info(impl_did) } fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool { @@ -218,13 +217,24 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); let source = trait_ref.self_ty(); - assert!(!source.has_escaping_bound_vars()); let target = { assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait); trait_ref.args.type_at(1) }; + // Check `CoercePointee` impl is WF -- if not, then there's no reason to report + // redundant errors for `DispatchFromDyn`. This is best effort, though. + let mut res = Ok(()); + tcx.for_each_relevant_impl( + tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + source, + |impl_def_id| { + res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id)); + }, + ); + res?; + debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target); let param_env = tcx.param_env(impl_did); diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.rs b/tests/ui/deriving/deriving-coerce-pointee-neg.rs index e660e7baacb..2713366945e 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.rs +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.rs @@ -145,7 +145,6 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>` -//~| ERROR for `RcWithId<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>` struct RcWithId<T: ?Sized> { inner: std::rc::Rc<(i32, Box<T>)>, } @@ -153,7 +152,6 @@ struct RcWithId<T: ?Sized> { #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced -//~| ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced struct MoreThanOneField<T: ?Sized> { //~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2 inner1: Box<T>, @@ -165,7 +163,6 @@ struct NotCoercePointeeData<T: ?Sized>(T); #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>` -//~| ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData<T>` struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>); fn main() {} diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr index e346d13ff5c..d3d73132078 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr @@ -118,43 +118,6 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr( LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: for `RcWithId<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>` - --> $DIR/deriving-coerce-pointee-neg.rs:146:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ -... -LL | inner: std::rc::Rc<(i32, Box<T>)>, - | --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized - | - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced - --> $DIR/deriving-coerce-pointee-neg.rs:154:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ - | -note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced - --> $DIR/deriving-coerce-pointee-neg.rs:159:5 - | -LL | inner1: Box<T>, - | ^^^^^^^^^^^^^^ -LL | inner2: Box<T>, - | ^^^^^^^^^^^^^^ - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData<T>` - --> $DIR/deriving-coerce-pointee-neg.rs:166:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ -... -LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>); - | ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized - | - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - error: for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>` --> $DIR/deriving-coerce-pointee-neg.rs:146:10 | @@ -167,13 +130,13 @@ LL | inner: std::rc::Rc<(i32, Box<T>)>, = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced - --> $DIR/deriving-coerce-pointee-neg.rs:154:10 + --> $DIR/deriving-coerce-pointee-neg.rs:153:10 | LL | #[derive(CoercePointee)] | ^^^^^^^^^^^^^ | note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced - --> $DIR/deriving-coerce-pointee-neg.rs:159:5 + --> $DIR/deriving-coerce-pointee-neg.rs:157:5 | LL | inner1: Box<T>, | ^^^^^^^^^^^^^^ @@ -182,18 +145,18 @@ LL | inner2: Box<T>, = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>` - --> $DIR/deriving-coerce-pointee-neg.rs:166:10 + --> $DIR/deriving-coerce-pointee-neg.rs:164:10 | LL | #[derive(CoercePointee)] | ^^^^^^^^^^^^^ -... +LL | LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>); | ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized | = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 - --> $DIR/deriving-coerce-pointee-neg.rs:157:1 + --> $DIR/deriving-coerce-pointee-neg.rs:155:1 | LL | struct MoreThanOneField<T: ?Sized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 @@ -203,7 +166,7 @@ LL | inner1: Box<T>, LL | inner2: Box<T>, | -------------- this field has non-zero size or requires alignment -error: aborting due to 24 previous errors +error: aborting due to 21 previous errors Some errors have detailed explanations: E0375, E0392, E0690, E0802. For more information about an error, try `rustc --explain E0375`. |
