Skip to content

Commit

Permalink
Unrolled build for rust-lang#117495
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#117495 - compiler-errors:unsize-docs, r=lcnr

Clarify `Unsize` documentation

The documentation erroneously says that:

```rust
/// - Types implementing a trait `Trait` also implement `Unsize<dyn Trait>`.
/// - Structs `Foo<..., T, ...>` implement `Unsize<Foo<..., U, ...>>` if all of these conditions
///   are met:
///   - `T: Unsize<U>`.
///   - Only the last field of `Foo` has a type involving `T`.
///   - `Bar<T>: Unsize<Bar<U>>`, where `Bar<T>` stands for the actual type of that last field.
```

Specifically, `T: Unsize<U>` is not required to hold -- only the final field must implement `FinalField<T>: Unsize<FinalField<U>>`. This can be demonstrated by the test I added.

---

Second commit fleshes out the documentation a lot more.
  • Loading branch information
rust-timer committed Nov 2, 2023
2 parents b800c30 + 1221b7b commit d021503
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
18 changes: 12 additions & 6 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,18 @@ pub trait Sized {
/// Those implementations are:
///
/// - Arrays `[T; N]` implement `Unsize<[T]>`.
/// - Types implementing a trait `Trait` also implement `Unsize<dyn Trait>`.
/// - Structs `Foo<..., T, ...>` implement `Unsize<Foo<..., U, ...>>` if all of these conditions
/// are met:
/// - `T: Unsize<U>`.
/// - Only the last field of `Foo` has a type involving `T`.
/// - `Bar<T>: Unsize<Bar<U>>`, where `Bar<T>` stands for the actual type of that last field.
/// - A type implements `Unsize<dyn Trait + 'a>` if all of these conditions are met:
/// - The type implements `Trait`.
/// - `Trait` is object safe.
/// - The type is sized.
/// - The type outlives `'a`.
/// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize<Foo<..., U1, ..., Un, ...>>`
/// where any number of (type and const) parameters may be changed if all of these conditions
/// are met:
/// - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`.
/// - All other parameters of the struct are equal.
/// - `Field<T1, ..., Tn>: Unsize<Field<U1, ..., Un>>`, where `Field<...>` stands for the actual
/// type of the struct's last field.
///
/// `Unsize` is used along with [`ops::CoerceUnsized`] to allow
/// "user-defined" containers such as [`Rc`] to contain dynamically-sized
Expand Down
29 changes: 29 additions & 0 deletions tests/ui/unsized/unsize-coerce-multiple-adt-params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// check-pass

struct Foo<T, U>
where
(T, U): Trait,
{
f: <(T, U) as Trait>::Assoc,
}

trait Trait {
type Assoc: ?Sized;
}

struct Count<const N: usize>;

impl<const N: usize> Trait for (i32, Count<N>) {
type Assoc = [(); N];
}

impl<'a> Trait for (u32, ()) {
type Assoc = [()];
}

// Test that we can unsize several trait params in creative ways.
fn unsize<const N: usize>(x: &Foo<i32, Count<N>>) -> &Foo<u32, ()> {
x
}

fn main() {}

0 comments on commit d021503

Please sign in to comment.