Rollup merge of #130826 - fmease:compiler-mv-obj-safe-dyn-compat, r=compiler-errors
Compiler: Rename "object safe" to "dyn compatible" Completed T-lang FCP: https://github.com/rust-lang/lang-team/issues/286#issuecomment-2338905118. Tracking issue: https://github.com/rust-lang/rust/issues/130852 Excludes `compiler/rustc_codegen_cranelift` (to be filed separately). Includes Stable MIR. Regarding https://github.com/rust-lang/rust/labels/relnotes, I guess I will manually open a https://github.com/rust-lang/rust/labels/relnotes-tracking-issue since this change affects everything (compiler, library, tools, docs, books, everyday language). r? ghost
This commit is contained in:
commit
a935064fae
183 changed files with 523 additions and 510 deletions
|
@ -5,9 +5,9 @@ trait, written in type positions) but this was a bit too confusing, so we now
|
|||
write `dyn Trait`.
|
||||
|
||||
Some traits are not allowed to be used as trait object types. The traits that
|
||||
are allowed to be used as trait object types are called "object-safe" traits.
|
||||
Attempting to use a trait object type for a trait that is not object-safe will
|
||||
trigger error E0038.
|
||||
are allowed to be used as trait object types are called "dyn-compatible"[^1]
|
||||
traits. Attempting to use a trait object type for a trait that is not
|
||||
dyn-compatible will trigger error E0038.
|
||||
|
||||
Two general aspects of trait object types give rise to the restrictions:
|
||||
|
||||
|
@ -25,13 +25,16 @@ Two general aspects of trait object types give rise to the restrictions:
|
|||
objects with the same trait object type may point to vtables from different
|
||||
implementations.
|
||||
|
||||
The specific conditions that violate object-safety follow, most of which relate
|
||||
to missing size information and vtable polymorphism arising from these aspects.
|
||||
The specific conditions that violate dyn-compatibility follow, most of which
|
||||
relate to missing size information and vtable polymorphism arising from these
|
||||
aspects.
|
||||
|
||||
[^1]: Formerly known as "object-safe".
|
||||
|
||||
### The trait requires `Self: Sized`
|
||||
|
||||
Traits that are declared as `Trait: Sized` or which otherwise inherit a
|
||||
constraint of `Self:Sized` are not object-safe.
|
||||
constraint of `Self:Sized` are not dyn-compatible.
|
||||
|
||||
The reasoning behind this is somewhat subtle. It derives from the fact that Rust
|
||||
requires (and defines) that every trait object type `dyn Trait` automatically
|
||||
|
@ -58,7 +61,7 @@ implement a sized trait like `Trait:Sized`. So, rather than allow an exception
|
|||
to the rule that `dyn Trait` always implements `Trait`, Rust chooses to prohibit
|
||||
such a `dyn Trait` from existing at all.
|
||||
|
||||
Only unsized traits are considered object-safe.
|
||||
Only unsized traits are considered dyn-compatible.
|
||||
|
||||
Generally, `Self: Sized` is used to indicate that the trait should not be used
|
||||
as a trait object. If the trait comes from your own crate, consider removing
|
||||
|
@ -103,8 +106,8 @@ fn call_foo(x: Box<dyn Trait>) {
|
|||
}
|
||||
```
|
||||
|
||||
If only some methods aren't object-safe, you can add a `where Self: Sized` bound
|
||||
on them to mark them as explicitly unavailable to trait objects. The
|
||||
If only some methods aren't dyn-compatible, you can add a `where Self: Sized`
|
||||
bound on them to mark them as explicitly unavailable to trait objects. The
|
||||
functionality will still be available to all other implementers, including
|
||||
`Box<dyn Trait>` which is itself sized (assuming you `impl Trait for Box<dyn
|
||||
Trait>`).
|
||||
|
@ -117,7 +120,7 @@ trait Trait {
|
|||
```
|
||||
|
||||
Now, `foo()` can no longer be called on a trait object, but you will now be
|
||||
allowed to make a trait object, and that will be able to call any object-safe
|
||||
allowed to make a trait object, and that will be able to call any dyn-compatible
|
||||
methods. With such a bound, one can still call `foo()` on types implementing
|
||||
that trait that aren't behind trait objects.
|
||||
|
||||
|
@ -306,7 +309,7 @@ Here, the supertrait might have methods as follows:
|
|||
|
||||
```
|
||||
trait Super<A: ?Sized> {
|
||||
fn get_a(&self) -> &A; // note that this is object safe!
|
||||
fn get_a(&self) -> &A; // note that this is dyn-compatible!
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -314,10 +317,10 @@ If the trait `Trait` was deriving from something like `Super<String>` or
|
|||
`Super<T>` (where `Foo` itself is `Foo<T>`), this is okay, because given a type
|
||||
`get_a()` will definitely return an object of that type.
|
||||
|
||||
However, if it derives from `Super<Self>`, even though `Super` is object safe,
|
||||
the method `get_a()` would return an object of unknown type when called on the
|
||||
function. `Self` type parameters let us make object safe traits no longer safe,
|
||||
so they are forbidden when specifying supertraits.
|
||||
However, if it derives from `Super<Self>`, even though `Super` is
|
||||
dyn-compatible, the method `get_a()` would return an object of unknown type when
|
||||
called on the function. `Self` type parameters let us make dyn-compatible traits
|
||||
no longer compatible, so they are forbidden when specifying supertraits.
|
||||
|
||||
There's no easy fix for this. Generally, code will need to be refactored so that
|
||||
you no longer need to derive from `Super<Self>`.
|
||||
|
|
|
@ -623,7 +623,7 @@ E0800: 0800,
|
|||
// E0314, // closure outlives stack frame
|
||||
// E0315, // cannot invoke closure outside of its lifetime
|
||||
// E0319, // trait impls for defaulted traits allowed just for structs/enums
|
||||
// E0372, // coherence not object safe
|
||||
// E0372, // coherence not dyn-compatible
|
||||
// E0385, // {} in an aliasable location
|
||||
// E0402, // cannot use an outer type parameter in this context
|
||||
// E0406, // merged into 420
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue