From 6af30ec720c3a8f074b61c9003b7e63f78f148a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 1 Nov 2023 20:16:11 +0000 Subject: [PATCH 1/2] Remove a false statement from Unsize docs, add a test --- library/core/src/marker.rs | 1 - .../unsize-coerce-multiple-adt-params.rs | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/ui/unsized/unsize-coerce-multiple-adt-params.rs diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index d396a707b55da..39e4abb10e926 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -158,7 +158,6 @@ pub trait Sized { /// - Types implementing a trait `Trait` also implement `Unsize`. /// - Structs `Foo<..., T, ...>` implement `Unsize>` if all of these conditions /// are met: -/// - `T: Unsize`. /// - Only the last field of `Foo` has a type involving `T`. /// - `Bar: Unsize>`, where `Bar` stands for the actual type of that last field. /// diff --git a/tests/ui/unsized/unsize-coerce-multiple-adt-params.rs b/tests/ui/unsized/unsize-coerce-multiple-adt-params.rs new file mode 100644 index 0000000000000..eba341ff2847f --- /dev/null +++ b/tests/ui/unsized/unsize-coerce-multiple-adt-params.rs @@ -0,0 +1,29 @@ +// check-pass + +struct Foo +where + (T, U): Trait, +{ + f: <(T, U) as Trait>::Assoc, +} + +trait Trait { + type Assoc: ?Sized; +} + +struct Count; + +impl Trait for (i32, Count) { + type Assoc = [(); N]; +} + +impl<'a> Trait for (u32, ()) { + type Assoc = [()]; +} + +// Test that we can unsize several trait params in creative ways. +fn unsize(x: &Foo>) -> &Foo { + x +} + +fn main() {} From 1221b7b652a9859340fad0cd6db78c7493f3847f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 1 Nov 2023 20:16:24 +0000 Subject: [PATCH 2/2] Rework unsize documentation --- library/core/src/marker.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 39e4abb10e926..13437d8f96120 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -155,11 +155,18 @@ pub trait Sized { /// Those implementations are: /// /// - Arrays `[T; N]` implement `Unsize<[T]>`. -/// - Types implementing a trait `Trait` also implement `Unsize`. -/// - Structs `Foo<..., T, ...>` implement `Unsize>` if all of these conditions -/// are met: -/// - Only the last field of `Foo` has a type involving `T`. -/// - `Bar: Unsize>`, where `Bar` stands for the actual type of that last field. +/// - A type implements `Unsize` 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>` +/// 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: Unsize>`, 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