@@ -3284,6 +3284,164 @@ impl Baz for Bar { } // Note: This is OK
32843284```
32853285"## ,
32863286
3287+ E0374 : r##"
3288+ A struct without a field containing an unsized type cannot implement
3289+ `CoerceUnsized`. An
3290+ [unsized type](https://doc.rust-lang.org/book/unsized-types.html)
3291+ is any type that the compiler doesn't know the length or alignment of at
3292+ compile time. Any struct containing an unsized type is also unsized.
3293+
3294+ Example of erroneous code:
3295+
3296+ ```compile_fail
3297+ #![feature(coerce_unsized)]
3298+ use std::ops::CoerceUnsized;
3299+
3300+ struct Foo<T: ?Sized> {
3301+ a: i32,
3302+ }
3303+
3304+ // error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
3305+ impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
3306+ where T: CoerceUnsized<U> {}
3307+ ```
3308+
3309+ `CoerceUnsized` is used to coerce one struct containing an unsized type
3310+ into another struct containing a different unsized type. If the struct
3311+ doesn't have any fields of unsized types then you don't need explicit
3312+ coercion to get the types you want. To fix this you can either
3313+ not try to implement `CoerceUnsized` or you can add a field that is
3314+ unsized to the struct.
3315+
3316+ Example:
3317+
3318+ ```
3319+ #![feature(coerce_unsized)]
3320+ use std::ops::CoerceUnsized;
3321+
3322+ // We don't need to impl `CoerceUnsized` here.
3323+ struct Foo {
3324+ a: i32,
3325+ }
3326+
3327+ // We add the unsized type field to the struct.
3328+ struct Bar<T: ?Sized> {
3329+ a: i32,
3330+ b: T,
3331+ }
3332+
3333+ // The struct has an unsized field so we can implement
3334+ // `CoerceUnsized` for it.
3335+ impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
3336+ where T: CoerceUnsized<U> {}
3337+ ```
3338+
3339+ Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
3340+ and `Arc` to be able to mark that they can coerce unsized types that they
3341+ are pointing at.
3342+ "## ,
3343+
3344+ E0375 : r##"
3345+ A struct with more than one field containing an unsized type cannot implement
3346+ `CoerceUnsized`. This only occurs when you are trying to coerce one of the
3347+ types in your struct to another type in the struct. In this case we try to
3348+ impl `CoerceUnsized` from `T` to `U` which are both types that the struct
3349+ takes. An [unsized type](https://doc.rust-lang.org/book/unsized-types.html)
3350+ is any type that the compiler doesn't know the length or alignment of at
3351+ compile time. Any struct containing an unsized type is also unsized.
3352+
3353+ Example of erroneous code:
3354+
3355+ ```compile_fail
3356+ #![feature(coerce_unsized)]
3357+ use std::ops::CoerceUnsized;
3358+
3359+ struct Foo<T: ?Sized, U: ?Sized> {
3360+ a: i32,
3361+ b: T,
3362+ c: U,
3363+ }
3364+
3365+ // error: Struct `Foo` has more than one unsized field.
3366+ impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
3367+ ```
3368+
3369+ `CoerceUnsized` only allows for coercion from a structure with a single
3370+ unsized type field to another struct with a single unsized type field.
3371+ In fact Rust only allows for a struct to have one unsized type in a struct
3372+ and that unsized type must be the last field in the struct. So having two
3373+ unsized types in a single struct is not allowed by the compiler. To fix this
3374+ use only one field containing an unsized type in the struct and then use
3375+ multiple structs to manage each unsized type field you need.
3376+
3377+ Example:
3378+
3379+ ```
3380+ #![feature(coerce_unsized)]
3381+ use std::ops::CoerceUnsized;
3382+
3383+ struct Foo<T: ?Sized> {
3384+ a: i32,
3385+ b: T,
3386+ }
3387+
3388+ impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
3389+ where T: CoerceUnsized<U> {}
3390+
3391+ fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
3392+ Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
3393+ }
3394+ ```
3395+
3396+ "## ,
3397+
3398+ E0376 : r##"
3399+ The type you are trying to impl `CoerceUnsized` for is not a struct.
3400+ `CoerceUnsized` can only be implemented for a struct. Unsized types are
3401+ already able to be coerced without an implementation of `CoerceUnsized`
3402+ whereas a struct containing an unsized type needs to know the unsized type
3403+ field it's containing is able to be coerced. An
3404+ [unsized type](https://doc.rust-lang.org/book/unsized-types.html)
3405+ is any type that the compiler doesn't know the length or alignment of at
3406+ compile time. Any struct containing an unsized type is also unsized.
3407+
3408+ Example of erroneous code:
3409+
3410+ ```compile_fail
3411+ #![feature(coerce_unsized)]
3412+ use std::ops::CoerceUnsized;
3413+
3414+ struct Foo<T: ?Sized> {
3415+ a: T,
3416+ }
3417+
3418+ // error: The type `U` is not a struct
3419+ impl<T, U> CoerceUnsized<U> for Foo<T> {}
3420+ ```
3421+
3422+ The `CoerceUnsized` trait takes a struct type. Make sure the type you are
3423+ providing to `CoerceUnsized` is a struct with only the last field containing an
3424+ unsized type.
3425+
3426+ Example:
3427+
3428+ ```
3429+ #![feature(coerce_unsized)]
3430+ use std::ops::CoerceUnsized;
3431+
3432+ struct Foo<T> {
3433+ a: T,
3434+ }
3435+
3436+ // The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
3437+ impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
3438+ ```
3439+
3440+ Note that in Rust, structs can only contain an unsized type if the field
3441+ containing the unsized type is the last and only unsized type field in the
3442+ struct.
3443+ "## ,
3444+
32873445E0379 : r##"
32883446Trait methods cannot be declared `const` by design. For more information, see
32893447[RFC 911].
@@ -3777,13 +3935,6 @@ register_diagnostics! {
37773935 E0320 , // recursive overflow during dropck
37783936 E0328 , // cannot implement Unsize explicitly
37793937// E0372, // coherence not object safe
3780- E0374 , // the trait `CoerceUnsized` may only be implemented for a coercion
3781- // between structures with one field being coerced, none found
3782- E0375 , // the trait `CoerceUnsized` may only be implemented for a coercion
3783- // between structures with one field being coerced, but multiple
3784- // fields need coercions
3785- E0376 , // the trait `CoerceUnsized` may only be implemented for a coercion
3786- // between structures
37873938 E0377 , // the trait `CoerceUnsized` may only be implemented for a coercion
37883939 // between structures with the same definition
37893940 E0399 , // trait items need to be implemented because the associated
0 commit comments