Rollup merge of #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.
This commit is contained in:
commit
9575625835
@ -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
|
||||
/// - 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:
|
||||
/// - `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.
|
||||
/// - 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
|
||||
|
29
tests/ui/unsized/unsize-coerce-multiple-adt-params.rs
Normal file
29
tests/ui/unsized/unsize-coerce-multiple-adt-params.rs
Normal file
@ -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() {}
|
Loading…
Reference in New Issue
Block a user