Skip to content

Commit

Permalink
Merge pull request #1666 from fmease/mv-obj-safe-dyn-compat
Browse files Browse the repository at this point in the history
Rename "object safe" to "dyn compatible"
  • Loading branch information
ehuss authored Oct 30, 2024
2 parents 23ce619 + 70cd4e3 commit 85c4a7a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 24 deletions.
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

0 comments on commit 85c4a7a

Please sign in to comment.