Deduplicate CoerceUnsized and DispatchFromDyn impl errors
This commit is contained in:
parent
5c5ed92c37
commit
b46acc0191
3 changed files with 19 additions and 49 deletions
|
@ -195,8 +195,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
|
||||||
// Just compute this for the side-effects, in particular reporting
|
// Just compute this for the side-effects, in particular reporting
|
||||||
// errors; other parts of the code may demand it for the info of
|
// errors; other parts of the code may demand it for the info of
|
||||||
// course.
|
// course.
|
||||||
let span = tcx.def_span(impl_did);
|
tcx.ensure_ok().coerce_unsized_info(impl_did)
|
||||||
tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
|
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 dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span));
|
||||||
|
|
||||||
let source = trait_ref.self_ty();
|
let source = trait_ref.self_ty();
|
||||||
assert!(!source.has_escaping_bound_vars());
|
|
||||||
let target = {
|
let target = {
|
||||||
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
||||||
|
|
||||||
trait_ref.args.type_at(1)
|
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);
|
debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target);
|
||||||
|
|
||||||
let param_env = tcx.param_env(impl_did);
|
let param_env = tcx.param_env(impl_did);
|
||||||
|
|
|
@ -145,7 +145,6 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(CoercePointee)]
|
#[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 `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> {
|
struct RcWithId<T: ?Sized> {
|
||||||
inner: std::rc::Rc<(i32, Box<T>)>,
|
inner: std::rc::Rc<(i32, Box<T>)>,
|
||||||
}
|
}
|
||||||
|
@ -153,7 +152,6 @@ struct RcWithId<T: ?Sized> {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(CoercePointee)]
|
#[derive(CoercePointee)]
|
||||||
//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
//~^ 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> {
|
struct MoreThanOneField<T: ?Sized> {
|
||||||
//~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
//~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
|
||||||
inner1: Box<T>,
|
inner1: Box<T>,
|
||||||
|
@ -165,7 +163,6 @@ struct NotCoercePointeeData<T: ?Sized>(T);
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(CoercePointee)]
|
#[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 `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>);
|
struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -118,43 +118,6 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(
|
||||||
LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
|
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>)>`
|
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
|
--> $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)
|
= 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
|
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)]
|
LL | #[derive(CoercePointee)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
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>,
|
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)
|
= 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>`
|
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 | #[derive(CoercePointee)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
...
|
LL |
|
||||||
LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
|
||||||
| ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
|
| ----------------------- `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)
|
= 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
|
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> {
|
LL | struct MoreThanOneField<T: ?Sized> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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>,
|
LL | inner2: Box<T>,
|
||||||
| -------------- this field has non-zero size or requires alignment
|
| -------------- 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.
|
Some errors have detailed explanations: E0375, E0392, E0690, E0802.
|
||||||
For more information about an error, try `rustc --explain E0375`.
|
For more information about an error, try `rustc --explain E0375`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue