Skip to content

Commit 28e8f60

Browse files
authored
Merge pull request #29 from matthewjasper/spec-attributes
Document internal specialization attributes
2 parents 1e31613 + 104f78a commit 28e8f60

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/code-considerations/using-unstable-lang/specialization.md

+34
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,40 @@ impl<T: Copy> RcFromSlice<T> for Rc<[T]> {
5858

5959
Only specialization using the `min_specialization` feature should be used. The full `specialization` feature is known to be unsound.
6060

61+
## Specialization attributes
62+
63+
There are two unstable attributes that can be used to allow a trait bound in a specializing implementation that does not appear in the default implementation.
64+
65+
`rustc_specialization_trait` restricts the implementations of a trait to be "always applicable". Implementing traits annotated with `rustc_specialization_trait` is unstable, so this should not be used on any stable traits exported from the standard library. `Sized` is an exception, and can have this attribute because it already cannot be implemented by an `impl` block.
66+
**Note**: `rustc_specialization_trait` only prevents incorrect monomorphizations, it does not prevent a type from being coerced between specialized and unspecialized types which can be important when specialization must be applied consistently. See [rust-lang/rust#85863](https://github.com/rust-lang/rust/issues/85863) for more details.
67+
68+
`rustc_unsafe_specialization_marker` allows specializing on a trait with no associated items. The attribute is `unsafe` because lifetime constraints from the implementations of the trait are not considered when specializing. The following example demonstrates a limitation of `rustc_unsafe_specialization_marker`, the specialized implementation is used for *all* shared reference types, not just those with `'static` lifetime. Because of this, new uses of `rustc_unsafe_specialization_marker` should be avoided.
69+
70+
```rust,ignore
71+
#[rustc_unsafe_specialization_marker]
72+
trait StaticRef {}
73+
74+
impl<T> StaticRef for &'static T {}
75+
76+
trait DoThing: Sized {
77+
fn do_thing(self);
78+
}
79+
80+
impl<T> DoThing for T {
81+
default fn do_thing(self) {
82+
// slow impl
83+
}
84+
}
85+
86+
impl<T: StaticRef> DoThing for T {
87+
fn do_thing(self) {
88+
// fast impl
89+
}
90+
}
91+
```
92+
93+
`rustc_unsafe_specialization_marker` exists to allow existing specializations that are based on marker traits exported from `std`, such as `Copy`, `FusedIterator` or `Eq`.
94+
6195
## For reviewers
6296

6397
Look out for any `default` annotations on public trait implementations. These will need to be refactored into a private dispatch trait. Also look out for uses of specialization that do more than pick a more optimized implementation.

0 commit comments

Comments
 (0)