Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename "object safe" to "dyn compatible" #1666

Merged
merged 4 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions src/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,14 @@ the hierarchy has its own collection of named entities.
### Nominal types

Types that can be referred to by a path directly. Specifically [enums],
[structs], [unions], and [trait objects].
[structs], [unions], and [trait object types].

### Object safe traits
### Dyn-compatible traits

[Traits] that can be used as [trait objects]. Only traits that follow specific
[rules][object safety] are object safe.
[Traits] that can be used in [trait object types] (`dyn Trait`).
Only traits that follow specific [rules][dyn compatibility] are *dyn compatible*.

These were formerly known as *object safe* traits.

### Path

Expand Down Expand Up @@ -293,6 +295,7 @@ example of an uninhabited type is the [never type] `!`, or an enum with no varia
[attributes]: attributes.md
[*entity*]: names.md
[crate]: crates-and-source-files.md
[dyn compatibility]: items/traits.md#dyn-compatibility
[enums]: items/enumerations.md
[fields]: expressions/field-expr.md
[free item]: #free-item
Expand All @@ -315,12 +318,11 @@ example of an uninhabited type is the [never type] `!`, or an enum with no varia
[*name*]: names.md
[*namespace*]: names/namespaces.md
[never type]: types/never.md
[object safety]: items/traits.md#object-safety
[*path*]: paths.md
[Paths]: paths.md
[*scope*]: names/scopes.md
[structs]: items/structs.md
[trait objects]: types/trait-object.md
[trait object types]: types/trait-object.md
[traits]: items/traits.md
[turbofish test]: https://github.com/rust-lang/rust/blob/1.58.0/src/test/ui/parser/bastion-of-the-turbofish.rs
[types of crates]: linkage.md
Expand All @@ -329,3 +331,17 @@ example of an uninhabited type is the [never type] `!`, or an enum with no varia
[unions]: items/unions.md
[variable bindings]: patterns.md
[visibility rules]: visibility-and-privacy.md

<script>
(function() {
var fragments = {
"#object-safe-traits": "glossary.html#dyn-compatible-traits",
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + "/" + target);
}
})();
</script>
44 changes: 30 additions & 14 deletions src/items/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Trait functions are not allowed to be [`const`].

Generic items may use traits as [bounds] on their type parameters.

## Generic Traits
## Generic traits

Type parameters can be specified for a trait to make it generic. These appear
after the trait name, using the same syntax used in [generic functions].
Expand All @@ -65,12 +65,13 @@ trait Seq<T> {
}
```

## Object Safety
<a id="object-safety"></a>
## Dyn compatibility

Object safe traits can be the base trait of a [trait object]. A trait is
*object safe* if it has the following qualities (defined in [RFC 255]):
A dyn-compatible trait can be the base trait of a [trait object]. A trait is
*dyn compatible* if it has the following qualities:

* All [supertraits] must also be object safe.
* All [supertraits] must also be dyn compatible.
* `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`.
* It must not have any associated constants.
* It must not have any associated types with generics.
Expand All @@ -92,11 +93,13 @@ Object safe traits can be the base trait of a [trait object]. A trait is
* Explicitly non-dispatchable functions require:
* Have a `where Self: Sized` bound (receiver type of `Self` (i.e. `self`) implies this).

> **Note**: This concept was formerly known as *object safety*.

```rust
# use std::rc::Rc;
# use std::sync::Arc;
# use std::pin::Pin;
// Examples of object safe methods.
// Examples of dyn compatible methods.
trait TraitMethods {
fn by_ref(self: &Self) {}
fn by_ref_mut(self: &mut Self) {}
Expand All @@ -113,7 +116,7 @@ trait TraitMethods {
```

```rust,compile_fail
// This trait is object-safe, but these methods cannot be dispatched on a trait object.
// This trait is dyn compatible, but these methods cannot be dispatched on a trait object.
trait NonDispatchable {
// Non-methods cannot be dispatched.
fn foo() where Self: Sized {}
Expand All @@ -137,8 +140,8 @@ obj.typed(1); // ERROR: cannot call with generic type

```rust,compile_fail
# use std::rc::Rc;
// Examples of non-object safe traits.
trait NotObjectSafe {
// Examples of dyn-incompatible traits.
trait DynIncompatible {
const CONST: i32 = 1; // ERROR: cannot have associated const

fn foo() {} // ERROR: associated function without Sized
Expand All @@ -148,14 +151,14 @@ trait NotObjectSafe {
}

struct S;
impl NotObjectSafe for S {
impl DynIncompatible for S {
fn returns(&self) -> Self { S }
}
let obj: Box<dyn NotObjectSafe> = Box::new(S); // ERROR
let obj: Box<dyn DynIncompatible> = Box::new(S); // ERROR
```

```rust,compile_fail
// Self: Sized traits are not object-safe.
// `Self: Sized` traits are dyn-incompatible.
trait TraitWithSize where Self: Sized {}

struct S;
Expand All @@ -164,7 +167,7 @@ let obj: Box<dyn TraitWithSize> = Box::new(S); // ERROR
```

```rust,compile_fail
// Not object safe if `Self` is a type argument.
// Dyn-incompatible if `Self` is a type argument.
trait Super<A> {}
trait WithSelf: Super<Self> where Self: Sized {}

Expand Down Expand Up @@ -330,7 +333,6 @@ fn main() {
[_WhereClause_]: generics.md#where-clauses
[bounds]: ../trait-bounds.md
[trait object]: ../types/trait-object.md
[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md
[associated items]: associated-items.md
[method]: associated-items.md#methods
[supertraits]: #supertraits
Expand All @@ -349,3 +351,17 @@ fn main() {
[`async`]: functions.md#async-functions
[`const`]: functions.md#const-functions
[type namespace]: ../names/namespaces.md

<script>
(function() {
var fragments = {
"#object-safety": "traits.html#dyn-compatibility",
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + "/" + target);
}
})();
</script>
4 changes: 2 additions & 2 deletions src/type-coercions.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ r[coerce.unsize.slice]
* `[T; n]` to `[T]`.

r[coerce.unsize.trait-object]
* `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [object safe].
* `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [dyn compatible].

r[coerce.unsized.composite]
* `Foo<..., T, ...>` to `Foo<..., U, ...>`, when:
Expand Down Expand Up @@ -322,7 +322,7 @@ precisely.
[RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
[RFC 1558]: https://github.com/rust-lang/rfcs/blob/master/text/1558-closure-to-fn-coercion.md
[subtype]: subtyping.md
[object safe]: items/traits.md#object-safety
[dyn compatible]: items/traits.md#dyn-compatibility
[type cast operator]: expressions/operator-expr.md#type-cast-expressions
[`Unsize`]: std::marker::Unsize
[`CoerceUnsized`]: std::ops::CoerceUnsized
Expand Down
4 changes: 2 additions & 2 deletions src/types/trait-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ r[type.trait-object.syntax]
r[type.trait-object.intro]
A *trait object* is an opaque value of another type that implements a set of
traits. The set of traits is made up of an [object safe] *base trait* plus any
traits. The set of traits is made up of a [dyn compatible] *base trait* plus any
number of [auto traits].

r[type.trait-object.impls]
Expand Down Expand Up @@ -116,6 +116,6 @@ inferred with a sensible choice.
[_TypeParamBounds_]: ../trait-bounds.md
[auto traits]: ../special-types-and-traits.md#auto-traits
[defaults]: ../lifetime-elision.md#default-trait-object-lifetimes
[dyn compatible]: ../items/traits.md#dyn-compatibility
[dynamically sized types]: ../dynamically-sized-types.md
[object safe]: ../items/traits.md#object-safety
[supertraits]: ../items/traits.md#supertraits