Consolidate and rework CoercePointee and DispatchFromDyn errors
This commit is contained in:
parent
b6899ab921
commit
96d966b07a
19 changed files with 163 additions and 281 deletions
|
@ -1,5 +1,5 @@
|
||||||
`CoerceUnsized` was implemented on a struct which does not contain a field with
|
`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which does not
|
||||||
an unsized type.
|
contain a field that is being unsized.
|
||||||
|
|
||||||
Example of erroneous code:
|
Example of erroneous code:
|
||||||
|
|
||||||
|
@ -11,47 +11,20 @@ struct Foo<T: ?Sized> {
|
||||||
a: i32,
|
a: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
|
// error: Struct `Foo` has no unsized fields that need to be coerced.
|
||||||
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||||
where T: CoerceUnsized<U> {}
|
where T: CoerceUnsized<U> {}
|
||||||
```
|
```
|
||||||
|
|
||||||
An [unsized type][1] is any type where the compiler does not know the length or
|
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||||
alignment of at compile time. Any struct containing an unsized type is also
|
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||||
unsized.
|
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||||
|
trait.
|
||||||
|
|
||||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
If the struct doesn't have any fields of unsized types then there is no
|
||||||
|
meaningful way to implement `CoerceUnsized` or `DispatchFromDyn`, since
|
||||||
|
there is no coercion taking place.
|
||||||
|
|
||||||
`CoerceUnsized` is used to coerce one struct containing an unsized type
|
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||||
into another struct containing a different unsized type. If the struct
|
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||||
doesn't have any fields of unsized types then you don't need explicit
|
that they are pointing at.
|
||||||
coercion to get the types you want. To fix this you can either
|
|
||||||
not try to implement `CoerceUnsized` or you can add a field that is
|
|
||||||
unsized to the struct.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
#![feature(coerce_unsized)]
|
|
||||||
use std::ops::CoerceUnsized;
|
|
||||||
|
|
||||||
// We don't need to impl `CoerceUnsized` here.
|
|
||||||
struct Foo {
|
|
||||||
a: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// We add the unsized type field to the struct.
|
|
||||||
struct Bar<T: ?Sized> {
|
|
||||||
a: i32,
|
|
||||||
b: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
// The struct has an unsized field so we can implement
|
|
||||||
// `CoerceUnsized` for it.
|
|
||||||
impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
|
|
||||||
where T: CoerceUnsized<U> {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
|
|
||||||
and `Arc` to be able to mark that they can coerce unsized types that they
|
|
||||||
are pointing at.
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
`CoerceUnsized` was implemented on a struct which contains more than one field
|
`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which contains
|
||||||
with an unsized type.
|
more than one field that is being unsized.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
|
@ -17,39 +17,14 @@ struct Foo<T: ?Sized, U: ?Sized> {
|
||||||
impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
||||||
```
|
```
|
||||||
|
|
||||||
A struct with more than one field containing an unsized type cannot implement
|
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||||
`CoerceUnsized`. This only occurs when you are trying to coerce one of the
|
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||||
types in your struct to another type in the struct. In this case we try to
|
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||||
impl `CoerceUnsized` from `T` to `U` which are both types that the struct
|
trait.
|
||||||
takes. An [unsized type][1] is any type that the compiler doesn't know the
|
|
||||||
length or alignment of at compile time. Any struct containing an unsized type
|
|
||||||
is also unsized.
|
|
||||||
|
|
||||||
`CoerceUnsized` only allows for coercion from a structure with a single
|
If the struct has multiple fields that must be unsized, then the compiler has no
|
||||||
unsized type field to another struct with a single unsized type field.
|
way to generate a valid implementation of `CoerceUnsized` or `DispatchFromDyn`.
|
||||||
In fact Rust only allows for a struct to have one unsized type in a struct
|
|
||||||
and that unsized type must be the last field in the struct. So having two
|
|
||||||
unsized types in a single struct is not allowed by the compiler. To fix this
|
|
||||||
use only one field containing an unsized type in the struct and then use
|
|
||||||
multiple structs to manage each unsized type field you need.
|
|
||||||
|
|
||||||
Example:
|
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||||
|
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||||
```
|
that they are pointing at.
|
||||||
#![feature(coerce_unsized)]
|
|
||||||
use std::ops::CoerceUnsized;
|
|
||||||
|
|
||||||
struct Foo<T: ?Sized> {
|
|
||||||
a: i32,
|
|
||||||
b: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
|
||||||
where T: CoerceUnsized<U> {}
|
|
||||||
|
|
||||||
fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
|
|
||||||
Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
`CoerceUnsized` was implemented on something that isn't a struct.
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
|
`CoerceUnsized` or `DispatchFromDyn` was implemented between two types that
|
||||||
|
are not structs.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0376
|
```compile_fail,E0377
|
||||||
#![feature(coerce_unsized)]
|
#![feature(coerce_unsized)]
|
||||||
use std::ops::CoerceUnsized;
|
use std::ops::CoerceUnsized;
|
||||||
|
|
||||||
|
@ -14,33 +17,4 @@ struct Foo<T: ?Sized> {
|
||||||
impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
||||||
```
|
```
|
||||||
|
|
||||||
`CoerceUnsized` can only be implemented for a struct. Unsized types are
|
`CoerceUnsized` or `DispatchFromDyn` can only be implemented between structs.
|
||||||
already able to be coerced without an implementation of `CoerceUnsized`
|
|
||||||
whereas a struct containing an unsized type needs to know the unsized type
|
|
||||||
field it's containing is able to be coerced. An [unsized type][1]
|
|
||||||
is any type that the compiler doesn't know the length or alignment of at
|
|
||||||
compile time. Any struct containing an unsized type is also unsized.
|
|
||||||
|
|
||||||
[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
|
|
||||||
|
|
||||||
The `CoerceUnsized` trait takes a struct type. Make sure the type you are
|
|
||||||
providing to `CoerceUnsized` is a struct with only the last field containing an
|
|
||||||
unsized type.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
#![feature(coerce_unsized)]
|
|
||||||
use std::ops::CoerceUnsized;
|
|
||||||
|
|
||||||
struct Foo<T> {
|
|
||||||
a: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
// The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
|
|
||||||
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that in Rust, structs can only contain an unsized type if the field
|
|
||||||
containing the unsized type is the last and only unsized type field in the
|
|
||||||
struct.
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
The trait `CoerceUnsized` may only be implemented for a coercion between
|
`CoerceUnsized` or `DispatchFromDyn` may only be implemented between structs
|
||||||
structures with the same definition.
|
of the same type.
|
||||||
|
|
||||||
Example of erroneous code:
|
Example of erroneous code:
|
||||||
|
|
||||||
|
@ -20,10 +20,15 @@ pub struct Bar<T: ?Sized> {
|
||||||
impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
|
||||||
```
|
```
|
||||||
|
|
||||||
When attempting to implement `CoerceUnsized`, the `impl` signature must look
|
`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
|
||||||
like: `impl CoerceUnsized<Type<U>> for Type<T> where T: CoerceUnsized<U>`;
|
like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
|
||||||
the *implementer* and *`CoerceUnsized` type parameter* must be the same
|
is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
|
||||||
type. In this example, `Bar` and `Foo` (even though structurally identical)
|
trait.
|
||||||
are *not* the same type and are rejected. Learn more about the `CoerceUnsized`
|
|
||||||
trait and DST coercion in
|
The compiler cannot support coercions between structs of different types, so
|
||||||
[the `CoerceUnsized` docs](../std/ops/trait.CoerceUnsized.html).
|
a valid implementation of `CoerceUnsized` or `DispatchFromDyn` should be
|
||||||
|
implemented between the same struct with different generic parameters.
|
||||||
|
|
||||||
|
Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
|
||||||
|
like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
|
||||||
|
that they are pointing at.
|
||||||
|
|
|
@ -85,6 +85,10 @@ hir_analysis_cmse_output_stack_spill =
|
||||||
.note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
|
.note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
|
||||||
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
hir_analysis_coerce_multi = implementing `{$trait_name}` does not allow multiple fields to be coerced
|
||||||
|
.note = the trait `{$trait_name}` may only be implemented when a single field is being coerced
|
||||||
|
.label = these fields must be coerced for `{$trait_name}` to be valid
|
||||||
|
|
||||||
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
|
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
|
||||||
|
|
||||||
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
|
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
|
||||||
|
@ -97,10 +101,7 @@ hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only ap
|
||||||
|
|
||||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||||
|
|
||||||
hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions
|
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
|
||||||
.note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
|
||||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
|
||||||
.label = requires multiple coercions
|
|
||||||
|
|
||||||
hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
|
hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
|
||||||
|
|
||||||
|
@ -139,10 +140,6 @@ hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `
|
||||||
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
|
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
|
||||||
.label = can't implement cross-crate trait for type in another crate
|
.label = can't implement cross-crate trait for type in another crate
|
||||||
|
|
||||||
hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions
|
|
||||||
.note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
|
||||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
|
||||||
|
|
||||||
hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
||||||
|
|
||||||
hir_analysis_dispatch_from_dyn_zst = 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
|
hir_analysis_dispatch_from_dyn_zst = 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
|
||||||
|
|
|
@ -240,16 +240,17 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||||
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
(&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => {
|
||||||
if def_a != def_b {
|
if def_a != def_b {
|
||||||
let source_path = tcx.def_path_str(def_a.did());
|
if def_a != def_b {
|
||||||
let target_path = tcx.def_path_str(def_b.did());
|
let source_path = tcx.def_path_str(def_a.did());
|
||||||
|
let target_path = tcx.def_path_str(def_b.did());
|
||||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion {
|
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||||
span,
|
span,
|
||||||
trait_name: "DispatchFromDyn",
|
trait_name: "DispatchFromDyn",
|
||||||
note: true,
|
note: true,
|
||||||
source_path,
|
source_path,
|
||||||
target_path,
|
target_path,
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if def_a.repr().c() || def_a.repr().packed() {
|
if def_a.repr().c() || def_a.repr().packed() {
|
||||||
|
@ -301,43 +302,33 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((i, ty_a, ty_b))
|
Some((i, ty_a, ty_b, tcx.def_span(field.did)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
res?;
|
res?;
|
||||||
|
|
||||||
if coerced_fields.is_empty() {
|
if coerced_fields.is_empty() {
|
||||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle {
|
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||||
span,
|
span,
|
||||||
trait_name: "DispatchFromDyn",
|
trait_name: "DispatchFromDyn",
|
||||||
note: true,
|
note: true,
|
||||||
}));
|
}));
|
||||||
} else if coerced_fields.len() > 1 {
|
} else if coerced_fields.len() > 1 {
|
||||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti {
|
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||||
span,
|
span,
|
||||||
coercions_note: true,
|
trait_name: "DispatchFromDyn",
|
||||||
number: coerced_fields.len(),
|
number: coerced_fields.len(),
|
||||||
coercions: coerced_fields
|
fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||||
.iter()
|
|
||||||
.map(|&(i, ty_a, ty_b)| {
|
|
||||||
format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", "),
|
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||||
for (_, ty_a, ty_b) in coerced_fields {
|
for (_, ty_a, ty_b, _) in coerced_fields {
|
||||||
ocx.register_obligation(Obligation::new(
|
ocx.register_obligation(Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
param_env,
|
param_env,
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]),
|
||||||
tcx,
|
|
||||||
dispatch_from_dyn_trait,
|
|
||||||
[ty_a, ty_b],
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let errors = ocx.select_all_or_error();
|
let errors = ocx.select_all_or_error();
|
||||||
|
@ -353,7 +344,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
}
|
}
|
||||||
_ => Err(tcx
|
_ => Err(tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })),
|
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +410,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
if def_a != def_b {
|
if def_a != def_b {
|
||||||
let source_path = tcx.def_path_str(def_a.did());
|
let source_path = tcx.def_path_str(def_a.did());
|
||||||
let target_path = tcx.def_path_str(def_b.did());
|
let target_path = tcx.def_path_str(def_b.did());
|
||||||
return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame {
|
return Err(tcx.dcx().emit_err(errors::CoerceSameStruct {
|
||||||
span,
|
span,
|
||||||
trait_name: "CoerceUnsized",
|
trait_name: "CoerceUnsized",
|
||||||
note: true,
|
note: true,
|
||||||
|
@ -501,12 +492,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
|
|
||||||
// Collect up all fields that were significantly changed
|
// Collect up all fields that were significantly changed
|
||||||
// i.e., those that contain T in coerce_unsized T -> U
|
// i.e., those that contain T in coerce_unsized T -> U
|
||||||
Some((i, a, b))
|
Some((i, a, b, tcx.def_span(f.did)))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if diff_fields.is_empty() {
|
if diff_fields.is_empty() {
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField {
|
return Err(tcx.dcx().emit_err(errors::CoerceNoField {
|
||||||
span,
|
span,
|
||||||
trait_name: "CoerceUnsized",
|
trait_name: "CoerceUnsized",
|
||||||
note: true,
|
note: true,
|
||||||
|
@ -519,19 +510,15 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
tcx.def_span(impl_did)
|
tcx.def_span(impl_did)
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti {
|
return Err(tcx.dcx().emit_err(errors::CoerceMulti {
|
||||||
span,
|
span,
|
||||||
coercions_note: true,
|
trait_name: "CoerceUnsized",
|
||||||
number: diff_fields.len(),
|
number: diff_fields.len(),
|
||||||
coercions: diff_fields
|
fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::<Vec<_>>().into(),
|
||||||
.iter()
|
|
||||||
.map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", "),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (i, a, b) = diff_fields[0];
|
let (i, a, b, _) = diff_fields[0];
|
||||||
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
let kind = ty::adjustment::CustomCoerceUnsized::Struct(i);
|
||||||
(a, b, coerce_unsized_trait, Some(kind))
|
(a, b, coerce_unsized_trait, Some(kind))
|
||||||
}
|
}
|
||||||
|
@ -539,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
_ => {
|
_ => {
|
||||||
return Err(tcx
|
return Err(tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }));
|
.emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1164,18 +1164,6 @@ pub(crate) struct InherentTyOutside {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
|
||||||
pub(crate) struct DispatchFromDynCoercion<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub trait_name: &'a str,
|
|
||||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
|
||||||
pub note: bool,
|
|
||||||
pub source_path: String,
|
|
||||||
pub target_path: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
|
#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
|
||||||
pub(crate) struct DispatchFromDynRepr {
|
pub(crate) struct DispatchFromDynRepr {
|
||||||
|
@ -1293,78 +1281,46 @@ pub(crate) struct DispatchFromDynZST<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
#[diag(hir_analysis_coerce_zero, code = E0374)]
|
||||||
pub(crate) struct DispatchFromDynSingle<'a> {
|
pub(crate) struct CoerceNoField {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub trait_name: &'a str,
|
pub trait_name: &'static str,
|
||||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
#[note(hir_analysis_coercion_between_struct_single_note)]
|
||||||
pub note: bool,
|
pub note: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
|
#[diag(hir_analysis_coerce_multi, code = E0375)]
|
||||||
#[note]
|
pub(crate) struct CoerceMulti {
|
||||||
pub(crate) struct DispatchFromDynMulti {
|
pub trait_name: &'static str,
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[note(hir_analysis_coercions_note)]
|
|
||||||
pub coercions_note: bool,
|
|
||||||
pub number: usize,
|
pub number: usize,
|
||||||
pub coercions: String,
|
#[note]
|
||||||
}
|
pub fields: MultiSpan,
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
|
|
||||||
pub(crate) struct DispatchFromDynStruct<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub trait_name: &'a str,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||||
pub(crate) struct DispatchFromDynSame<'a> {
|
pub(crate) struct CoerceUnsizedNonStruct {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub trait_name: &'a str,
|
pub trait_name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
|
||||||
|
pub(crate) struct CoerceSameStruct {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub trait_name: &'static str,
|
||||||
#[note(hir_analysis_coercion_between_struct_same_note)]
|
#[note(hir_analysis_coercion_between_struct_same_note)]
|
||||||
pub note: bool,
|
pub note: bool,
|
||||||
pub source_path: String,
|
pub source_path: String,
|
||||||
pub target_path: String,
|
pub target_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
|
|
||||||
pub(crate) struct CoerceUnsizedOneField<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub trait_name: &'a str,
|
|
||||||
#[note(hir_analysis_coercion_between_struct_single_note)]
|
|
||||||
pub note: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
|
|
||||||
#[note]
|
|
||||||
pub(crate) struct CoerceUnsizedMulti {
|
|
||||||
#[primary_span]
|
|
||||||
#[label]
|
|
||||||
pub span: Span,
|
|
||||||
#[note(hir_analysis_coercions_note)]
|
|
||||||
pub coercions_note: bool,
|
|
||||||
pub number: usize,
|
|
||||||
pub coercions: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
|
|
||||||
pub(crate) struct CoerceUnsizedMay<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub trait_name: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
|
#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
|
||||||
pub(crate) struct TraitCannotImplForTy {
|
pub(crate) struct TraitCannotImplForTy {
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
|
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||||
--> $DIR/issue-26905.rs:16:40
|
--> $DIR/issue-26905.rs:16:40
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<MyRc<U>> for MyRc<T>{ }
|
LL | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<MyRc<U>> for MyRc<T>{ }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||||
= note: currently, 2 fields need coercions: `_ptr` (`*const T` to `*const U`), `_boo` (`NotPhantomData<T>` to `NotPhantomData<U>`)
|
--> $DIR/issue-26905.rs:12:5
|
||||||
|
|
|
||||||
|
LL | _ptr: *const T,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | _boo: NotPhantomData<T>,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | struct Foo<T: ?Sized> {
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
|
error[E0374]: implementing `CoerceUnsized` requires a field to be coerced
|
||||||
--> $DIR/E0374.rs:8:1
|
--> $DIR/E0374.rs:8:1
|
||||||
|
|
|
|
||||||
LL | / impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
LL | / impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
|
||||||
|
|
|
@ -23,14 +23,19 @@ help: the `Box` type always has a statically known size and allocates its conten
|
||||||
LL | b: Box<T>,
|
LL | b: Box<T>,
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
||||||
error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
|
error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
|
||||||
--> $DIR/E0375.rs:10:12
|
--> $DIR/E0375.rs:10:12
|
||||||
|
|
|
|
||||||
LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
|
note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
|
||||||
= note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`)
|
--> $DIR/E0375.rs:6:5
|
||||||
|
|
|
||||||
|
LL | b: T,
|
||||||
|
| ^^^^
|
||||||
|
LL | c: U,
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#![feature(coerce_unsized)]
|
|
||||||
use std::ops::CoerceUnsized;
|
|
||||||
|
|
||||||
struct Foo<T: ?Sized> {
|
|
||||||
a: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, U> CoerceUnsized<U> for Foo<T> {} //~ ERROR E0376
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0376]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
|
|
||||||
--> $DIR/E0376.rs:8:1
|
|
||||||
|
|
|
||||||
LL | impl<T, U> CoerceUnsized<U> for Foo<T> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0376`.
|
|
|
@ -8,9 +8,10 @@ use std::{
|
||||||
struct WrapperWithExtraField<T>(T, i32);
|
struct WrapperWithExtraField<T>(T, i32);
|
||||||
|
|
||||||
impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
||||||
|
//~^ ERROR [E0378]
|
||||||
where
|
where
|
||||||
T: DispatchFromDyn<U>,
|
T: DispatchFromDyn<U>,
|
||||||
{} //~^^^ ERROR [E0378]
|
{}
|
||||||
|
|
||||||
|
|
||||||
struct MultiplePointers<T: ?Sized>{
|
struct MultiplePointers<T: ?Sized>{
|
||||||
|
@ -19,9 +20,10 @@ struct MultiplePointers<T: ?Sized>{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
||||||
|
//~^ implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
where
|
where
|
||||||
T: Unsize<U>,
|
T: Unsize<U>,
|
||||||
{} //~^^^ ERROR [E0378]
|
{}
|
||||||
|
|
||||||
|
|
||||||
struct NothingToCoerce<T: ?Sized> {
|
struct NothingToCoerce<T: ?Sized> {
|
||||||
|
@ -29,23 +31,25 @@ struct NothingToCoerce<T: ?Sized> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
||||||
//~^ ERROR [E0378]
|
//~^ ERROR implementing `DispatchFromDyn` requires a field to be coerced
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct HasReprC<T: ?Sized>(Box<T>);
|
struct HasReprC<T: ?Sized>(Box<T>);
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
||||||
|
//~^ ERROR [E0378]
|
||||||
where
|
where
|
||||||
T: Unsize<U>,
|
T: Unsize<U>,
|
||||||
{} //~^^^ ERROR [E0378]
|
{}
|
||||||
|
|
||||||
#[repr(align(64))]
|
#[repr(align(64))]
|
||||||
struct OverAlignedZst;
|
struct OverAlignedZst;
|
||||||
struct OverAligned<T: ?Sized>(Box<T>, OverAlignedZst);
|
struct OverAligned<T: ?Sized>(Box<T>, OverAlignedZst);
|
||||||
|
|
||||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
||||||
|
//~^ ERROR [E0378]
|
||||||
where
|
where
|
||||||
T: Unsize<U>,
|
T: Unsize<U>,
|
||||||
{} //~^^^ ERROR [E0378]
|
{}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -2,25 +2,32 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs co
|
||||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
|
||||||
|
|
|
|
||||||
LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
|
||||||
|
LL | |
|
||||||
LL | | where
|
LL | | where
|
||||||
LL | | T: DispatchFromDyn<U>,
|
LL | | T: DispatchFromDyn<U>,
|
||||||
| |__________________________^
|
| |__________________________^
|
||||||
|
|
|
|
||||||
= note: extra field `1` of type `i32` is not allowed
|
= note: extra field `1` of type `i32` is not allowed
|
||||||
|
|
||||||
error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
|
error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:21:1
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:22:1
|
||||||
|
|
|
|
||||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
|
||||||
|
LL | |
|
||||||
LL | | where
|
LL | | where
|
||||||
LL | | T: Unsize<U>,
|
LL | | T: Unsize<U>,
|
||||||
| |_________________^
|
| |_________________^
|
||||||
|
|
|
|
||||||
= note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
|
||||||
= note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`)
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:18:5
|
||||||
|
|
|
||||||
|
LL | ptr1: *const T,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | ptr2: *const T,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
error[E0374]: implementing `DispatchFromDyn` requires a field to be coerced
|
||||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:33:1
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -28,17 +35,19 @@ LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingT
|
||||||
= note: expected a single field to be coerced, none found
|
= note: expected a single field to be coerced, none found
|
||||||
|
|
||||||
error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
|
||||||
--> $DIR/invalid_dispatch_from_dyn_impls.rs:37:1
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:39:1
|
||||||
|
|
|
|
||||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
|
||||||
|
LL | |
|
||||||
LL | | where
|
LL | | where
|
||||||
LL | | T: Unsize<U>,
|
LL | | T: Unsize<U>,
|
||||||
| |_________________^
|
| |_________________^
|
||||||
|
|
||||||
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
|
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/invalid_dispatch_from_dyn_impls.rs:46:1
|
--> $DIR/invalid_dispatch_from_dyn_impls.rs:49:1
|
||||||
|
|
|
|
||||||
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
|
||||||
|
LL | |
|
||||||
LL | | where
|
LL | | where
|
||||||
LL | | T: Unsize<U>,
|
LL | | T: Unsize<U>,
|
||||||
| |_____________________^
|
| |_____________________^
|
||||||
|
@ -47,4 +56,5 @@ LL | | T: Unsize<U>,
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0378`.
|
Some errors have detailed explanations: E0374, E0375, E0378.
|
||||||
|
For more information about an error, try `rustc --explain E0374`.
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Dispatchable<T: ?Sized, Z> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
|
impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
|
||||||
//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
|
//~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
where
|
where
|
||||||
T: Unsize<U> + ?Sized,
|
T: Unsize<U> + ?Sized,
|
||||||
U: ?Sized,
|
U: ?Sized,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
|
error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
--> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1
|
--> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1
|
||||||
|
|
|
|
||||||
LL | / impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
|
LL | / impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
|
||||||
|
@ -8,9 +8,14 @@ LL | | T: Unsize<U> + ?Sized,
|
||||||
LL | | U: ?Sized,
|
LL | | U: ?Sized,
|
||||||
| |______________^
|
| |______________^
|
||||||
|
|
|
|
||||||
= note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
|
||||||
= note: currently, 2 fields need coercions: `_ptr` (`Box<T>` to `Box<U>`), `z` (`()` to `i32`)
|
--> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:13:5
|
||||||
|
|
|
||||||
|
LL | _ptr: Box<T>,
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
LL | z: Z,
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0378`.
|
For more information about this error, try `rustc --explain E0375`.
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Foo<'a, U: ?Sized> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
|
impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
|
||||||
//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
|
//~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
where
|
where
|
||||||
T: Unsize<U> + ?Sized,
|
T: Unsize<U> + ?Sized,
|
||||||
U: ?Sized {}
|
U: ?Sized {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
|
error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
|
||||||
--> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1
|
--> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1
|
||||||
|
|
|
|
||||||
LL | / impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
|
LL | / impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
|
||||||
|
@ -8,9 +8,14 @@ LL | | T: Unsize<U> + ?Sized,
|
||||||
LL | | U: ?Sized {}
|
LL | | U: ?Sized {}
|
||||||
| |_____________^
|
| |_____________^
|
||||||
|
|
|
|
||||||
= note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
|
||||||
= note: currently, 2 fields need coercions: `token` (`IsSendToken<T>` to `IsSendToken<U>`), `ptr` (`&'a T` to `&'a U`)
|
--> $DIR/dispatch-from-dyn-zst-transmute.rs:13:5
|
||||||
|
|
|
||||||
|
LL | token: IsSendToken<U>,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | ptr: &'a U,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0378`.
|
For more information about this error, try `rustc --explain E0375`.
|
||||||
|
|
|
@ -65,7 +65,7 @@ LL | fn foo(self: Smaht<Self, T>);
|
||||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||||
|
|
||||||
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
error[E0377]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
|
||||||
--> $DIR/issue-78372.rs:3:1
|
--> $DIR/issue-78372.rs:3:1
|
||||||
|
|
|
|
||||||
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
||||||
|
@ -73,5 +73,5 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0307, E0378, E0412, E0658.
|
Some errors have detailed explanations: E0307, E0377, E0412, E0658.
|
||||||
For more information about an error, try `rustc --explain E0307`.
|
For more information about an error, try `rustc --explain E0307`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue