@@ -3284,6 +3284,164 @@ impl Baz for Bar { } // Note: This is OK
3284
3284
```
3285
3285
"## ,
3286
3286
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
+
3287
3445
E0379 : r##"
3288
3446
Trait methods cannot be declared `const` by design. For more information, see
3289
3447
[RFC 911].
@@ -3777,13 +3935,6 @@ register_diagnostics! {
3777
3935
E0320 , // recursive overflow during dropck
3778
3936
E0328 , // cannot implement Unsize explicitly
3779
3937
// 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
3787
3938
E0377 , // the trait `CoerceUnsized` may only be implemented for a coercion
3788
3939
// between structures with the same definition
3789
3940
E0399 , // trait items need to be implemented because the associated
0 commit comments