You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Let's make some editorial revisions to clarify wording and add and
clarify examples.
One thing we're struggling with a bit here is how much we want to
overlap with the documentation of the standard library. In some
cases, we've removed detailed descriptions of the implementation rule
when this is better covered in the library docs.
Copy file name to clipboardExpand all lines: src/type-coercions.md
+88-29Lines changed: 88 additions & 29 deletions
Original file line number
Diff line number
Diff line change
@@ -185,18 +185,16 @@ r[coerce.unsize]
185
185
### Unsized Coercions
186
186
187
187
r[coerce.unsize.intro]
188
-
The following coercions are called "unsized coercions", since their targets contain an unsized type.
189
-
Unsized coercions apply to pointer-like types which point to types which can lose some of their compile-time known information (such as size or implemented traits). For example:
188
+
The following coercions are called "unsized coercions", since their targets contain an unsized type. Unsized coercions apply to pointer-like types where some type information known about the referent at compile-time (e.g. its size or traits that it implements) can be *erased*. For example:
190
189
191
190
```rust
192
191
usestd::cell::Cell;
193
192
194
193
fnmain() {
195
194
// `&[u8; 0]` can be coerced to `&[u8]`.
196
195
//
197
-
// here `&_` is the pointer-like type,
198
-
// `[u8; 0]` is the original pointee,
199
-
// and `[u8]` is more erased pointee (it lost the length information).
196
+
// Here `&_` is the pointer-like type, `[u8; 0]` is the original
197
+
// pointee, and `[u8]` is more erased pointee (losing the length).
200
198
let_:&[u8] =&[];
201
199
202
200
traitA:Super {}
@@ -206,41 +204,102 @@ fn main() {
206
204
implSuperfor () {}
207
205
208
206
// `&()` can be coerced to `&dyn A`, losing the type information.
209
-
leta:&dynA=&();
207
+
let_:&dynA=&();
210
208
211
-
// `&dyn A` can be coerced to `&dyn Super`,
212
-
//losing the fact that the underlying type (unit) implements `A` too.
213
-
let_:&dynSuper=a;
209
+
// `&dyn A` can be coerced to `&dyn Super`, losing the fact that
210
+
// the underlying type (unit) implements `A` too.
211
+
let_:&dynSuper=&() as&dynA;
214
212
215
-
// The same coercions work with other pointer-like types and wrappers over them:
213
+
// The same coercions work with other pointer-like types and
// The result of the coercion doesn't *have* to be the same pointer-like type,
220
-
// although this is only allowed for certain pairs of pointer-like types.
218
+
// The result of the coercion doesn't *have* to be the same
219
+
// pointer-like type, although this is only allowed for certain
220
+
// pairs of pointer-like types.
221
221
let_:*constdynA=&mut ();
222
222
}
223
223
```
224
224
225
225
> [!NOTE]
226
-
> The term "unsized" might be quite confusing, since the coercion works on sized types (pointers) and the source pointer might point to an unsized type in the first place (`&dyn A -> &dyn Super` in the example above).
226
+
> The term "unsized" might be confusing, as the coercion works on sized types (the pointer-like type itself) and the source pointer might point to an unsized type in the first place (e.g. `&dyn A -> &dyn Super` in the example above).
227
227
>
228
-
> "unsized" refers to the main purpose of these coercions --- converting (pointers to) sized types to (pointers to) unsized types. The pointers being not the focus, since unsized types can't exist without them.
228
+
> Here, "unsized" refers to the main purpose of these coercions, which is to produce (pointers to) unsized types. Since unsized types can't exist except behind a pointer, the pointers are deemphasized.
229
229
230
-
r[coerce.unsize.metadata]
231
-
When performing unsized coercion, the pointer metadata type changes. For example, when unsized`&u32` to `&dyn Debug` metadate type changes from `()` to `DynMetadata<dyn Debug>` (note that exact metadata types are not yet stable). This can also lead to a change in the pointer size --- `&u32` is half the size of `&dyn Debug`.
230
+
> [!NOTE]
231
+
> When doing an unsized coercion, the internal pointer metadata type changes. For example, when coercing`&u32` to `&dyn Debug`, the metadata type changes from `()` to `DynMetadata<dyn Debug>` (these metadata types are not yet stable, see [#81513]). This can also lead to a change in the pointer size --- `&u32` is half the size of `&dyn Debug`.
232
232
233
233
r[coerce.unsize.traits]
234
-
Three internal traits, [`Unsize`], [`CoerceUnsized`], and [`PinCoerceUnsized`] are used to assist in this process and expose it for library use.
234
+
Three internal traits, [`Unsize`], [`CoerceUnsized`], and [`PinCoerceUnsized`] are used to assist in this process.
235
235
236
236
r[coerce.unsize.traits.unsize]
237
-
[`Unsize`] represents the fact that the target type is layout compatible with the source type and the pointer metadata of the target type can be derived from the metadata of the source, meaning that a pointer to the source type can be converted to a pointer to the target type. For example `[T; N]` implements `Unsize<[T]>` meaning that you can *unsize* former into the later, allowing coercions such as `&[T; N] -> &[T]`.
237
+
[`Unsize`] represents that the target type is layout compatible with the source type and the pointer metadata of the target type can be derived from the metadata of the source. This implies that a pointer to the source type can be converted to a pointer to the target type.
238
+
239
+
> [!EXAMPLE]
240
+
> Because `[T; N]` implements `Unsize<[T]>`, you can *unsize*`[T; N]` into `[T]`, allowing coercions such as `&[T; N] -> &[T]`.
238
241
239
242
r[coerce.unsize.traits.coerce-unsized]
240
-
[`CoerceUnsized`] represents the fact that a pointer-like type can be coerced to another pointer-like type, due to `Unsize` being implemented for their pointees. For example, `&T` implements `CoerceUnsized<&U>` when `T: Unsize<U>`.
243
+
[`CoerceUnsized`] represents that a pointer-like type can be coerced to another pointer-like type when `Unsize` is implemented for the pointee of the source type.
244
+
245
+
> [!EXAMPLE]
246
+
> `&T` implements `CoerceUnsized<&U>` when `T: Unsize<U>`. So, since `u8: Unsize<dyn Display>`, `&u8: CoerceUnsized<&dyn Display>`.
[`PinCoerceUnsized`] is an unsafe marker trait for pointer-like types, unsized coercion of which does not break [`Pin`] guarantees. [`PinCoerceUnsized`] being implemented for the pointer is a requirement of the `CoerceUnsized` implementation for `Pin`. That is, `&D: PinCoerceUnsized` implies `Pin<&T>: CoerceUnsized<Pin<&U>>`.
0 commit comments