Skip to content

Commit 1ad8c2e

Browse files
authored
Merge pull request #703 from ohadravid/rfc-2451-coherence
Update coherence and orphan rules documentation to match RFC 2451
2 parents 9070e8c + eadbdaf commit 1ad8c2e

File tree

2 files changed

+61
-13
lines changed

2 files changed

+61
-13
lines changed

src/glossary.md

+42
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ items are defined in [implementations] and declared in [traits]. Only
3030
functions, constants, and type aliases can be associated. Contrast to a [free
3131
item].
3232

33+
### Blanket implementation
34+
35+
Any implementation where a type appears [uncovered](#uncovered-type). `impl<T> Foo
36+
for T`, `impl<T> Bar<T> for T`, `impl<T> Bar<Vec<T>> for T`, and `impl<T> Bar<T>
37+
for Vec<T>` are considered blanket impls. However, `impl<T> Bar<Vec<T>> for
38+
Vec<T>` is not a blanket impl, as all instances of `T` which appear in this `impl`
39+
are covered by `Vec`.
40+
3341
### Bound
3442

3543
Bounds are constraints on a type or trait. For example, if a bound
@@ -65,6 +73,21 @@ For example, `2 + (3 * 4)` is an expression that returns the value 14.
6573
An [item] that is not a member of an [implementation], such as a *free
6674
function* or a *free const*. Contrast to an [associated item].
6775

76+
### Fundamental traits
77+
78+
A fundamental trait is one where adding an impl of it for an existing type is a breaking change.
79+
The `Fn` traits and `Sized` are fundamental.
80+
81+
### Fundamental type constructors
82+
83+
A fundamental type constructor is a type where implementing a [blanket implementation](#blanket-implementation) over it
84+
is a breaking change. `&`, `&mut`, `Box`, and `Pin` are fundamental.
85+
86+
Any time a type `T` is considered [local](#local-type), `&T`, `&mut T`, `Box<T>`, and `Pin<T>`
87+
are also considered local. Fundamental type constructors cannot [cover](#uncovered-type) other types.
88+
Any time the term "covered type" is used,
89+
the `T` in `&T`, `&mut T`, `Box<T>`, and `Pin<T>` is not considered covered.
90+
6891
### Inhabited
6992

7093
A type is inhabited if it has constructors and therefore can be instantiated. An inhabited type is
@@ -87,6 +110,19 @@ A variable is initialized if it has been assigned a value and hasn't since been
87110
moved from. All other memory locations are assumed to be uninitialized. Only
88111
unsafe Rust can create such a memory without initializing it.
89112

113+
### Local trait
114+
115+
A `trait` which was defined in the current crate. A trait definition is local
116+
or not independent of applied type arguments. Given `trait Foo<T, U>`,
117+
`Foo` is always local, regardless of the types substituted for `T` and `U`.
118+
119+
### Local type
120+
121+
A `struct`, `enum`, or `union` which was defined in the current crate.
122+
This is not affected by applied type arguments. `struct Foo` is considered local, but
123+
`Vec<Foo>` is not. `LocalType<ForeignType>` is local. Type aliases do not
124+
affect locality.
125+
90126
### Nominal types
91127

92128
Types that can be referred to by a path directly. Specifically [enums],
@@ -158,6 +194,12 @@ It allows a type to make certain promises about its behavior.
158194

159195
Generic functions and generic structs can use traits to constrain, or bound, the types they accept.
160196

197+
### Uncovered type
198+
199+
A type which does not appear as an argument to another type. For example,
200+
`T` is uncovered, but the `T` in `Vec<T>` is covered. This is only relevant for
201+
type arguments.
202+
161203
### Undefined behavior
162204

163205
Compile-time or run-time behavior that is not specified. This may result in,

src/items/implementations.md

+19-13
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,31 @@ impl Shape for Circle {
152152

153153
### Trait Implementation Coherence
154154

155-
A trait implementation is considered incoherent if either the orphan check fails
155+
A trait implementation is considered incoherent if either the orphan rules check fails
156156
or there are overlapping implementation instances.
157157

158158
Two trait implementations overlap when there is a non-empty intersection of the
159159
traits the implementation is for, the implementations can be instantiated with
160160
the same type. <!-- This is probably wrong? Source: No two implementations can
161161
be instantiable with the same set of types for the input type parameters. -->
162162

163-
The `Orphan Check` states that every trait implementation must meet either of
164-
the following conditions:
163+
#### Orphan rules
165164

166-
1. The trait being implemented is defined in the same crate.
165+
Given `impl<P1..=Pn> Trait<T1..=Tn> for T0`, an `impl` is valid only if at
166+
least one of the following is true:
167167

168-
2. At least one of either `Self` or a generic type parameter of the trait must
169-
meet the following grammar, where `C` is a nominal type defined
170-
within the containing crate:
168+
- `Trait` is a [local trait]
169+
- All of
170+
- At least one of the types `T0..=Tn` must be a [local type]. Let `Ti` be the
171+
first such type.
172+
- No [uncovered type] parameters `P1..=Pn` may appear in `T0..Ti` (excluding
173+
`Ti`)
174+
175+
Only the appearance of *uncovered* type parameters is restricted.
176+
Note that for the purposes of coherence, [fundamental types] are
177+
special. The `T` in `Box<T>` is not considered covered, and `Box<LocalType>`
178+
is considered local.
171179

172-
```ignore
173-
T = C
174-
| &C
175-
| &mut C
176-
| Box<C>
177-
```
178180

179181
## Generic Implementations
180182

@@ -224,3 +226,7 @@ attributes].
224226
[path]: ../paths.md
225227
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
226228
[Unsafe traits]: traits.md#unsafe-traits
229+
[local trait]: ../glossary.md#local-trait
230+
[local type]: ../glossary.md#local-type
231+
[fundamental types]: ../glossary.md#fundamental-type-constructors
232+
[uncovered type]: ../glossary.md#uncovered-type

0 commit comments

Comments
 (0)