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.
Thanks to Eric Huss for the glossary entry added here.
Copy file name to clipboardExpand all lines: src/glossary.md
+16Lines changed: 16 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -188,6 +188,21 @@ A [*path*] is a sequence of one or more path segments used to refer to an
188
188
[entity](#entity) in the current scope or other levels of a
189
189
[namespace](#namespace) hierarchy.
190
190
191
+
r[glossary.pointer-metadata]
192
+
### Pointer metadata
193
+
194
+
Pointer metadata is additional information associated with a raw pointer or reference type.
195
+
196
+
Pointers for statically sized types (that implement the [`Sized`] trait) and `extern` types are said to be "thin" and their metadata is of type `()` (and is zero-sized).
197
+
198
+
Pointers for [dynamically sized types] (DSTs) are said to be "wide" or "fat" and consist of the data pointer (that contains the memory address of the value) and some non-zero-sized metadata:
199
+
200
+
* For structs whose last field is a DST, metadata is the metadata for the last field.
201
+
* For the `str` type, metadata is the length in bytes as `usize`.
202
+
* For slice types like `[T]`, metadata is the length in items as `usize`.
203
+
* For trait objects like `dyn SomeTrait`, metadata is [`DynMetadata<Self>`][DynMetadata]
204
+
(e.g. `DynMetadata<dyn SomeTrait>`).
205
+
191
206
### Prelude
192
207
193
208
Prelude, or The Rust Prelude, is a small collection of items - mostly traits - that are
@@ -290,6 +305,7 @@ uninhabited type is "empty" in the sense that there are no values of the type. T
290
305
example of an uninhabited type is the [never type]`!`, or an enum with no variants
291
306
`enum Never { }`. Opposite of [Inhabited](#inhabited).
Copy file name to clipboardExpand all lines: src/type-coercions.md
+89-29Lines changed: 89 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]`.
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