Skip to content

Commit 6be59ca

Browse files
committed
Address feedback
1 parent 4c32c86 commit 6be59ca

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

text/0000-re-rebalancing-coherence.md

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,23 +181,21 @@ definition of blanket impl given above.
181181

182182
Assumes the same definitions [as above](#definitions).
183183

184-
Given `impl<P1...Pn> Trait<T1...Tn> for Target`, an impl is valid only if at
184+
Given `impl<P1..=Pn> Trait<T1..=Tn> for T0`, an impl is valid only if at
185185
least one of the following is true:
186186

187187
- `Trait` is a local trait
188-
- `Target` is a local type
189188
- All of
190-
- `Target` is not an uncovered type parameter (is not any of `P1...Pn`)
191-
- At least one of the types `T1...Tn` must be a local type. Let `Ti` be the
189+
- At least one of the types `T0..=Tn` must be a local type. Let `Ti` be the
192190
first such type.
193-
- No type parameters `P1...Pn` may appear *anywhere* in `T1...Tn` before `Ti`.
191+
- No uncovered type parameters `P1..=Pn` may appear in `T0..Ti` (excluding
192+
`Ti`)
194193

195-
Note that this is not just written as the removal of `T0` from the rules defined
196-
in [RFC #1023]. We have the special case rule that `Target` must not be an
197-
uncovered type parameter, because we want to continue to reject `impl<T>
198-
ForeignTrait<LocalType> for T`. This must continue to be rejected to avoid
199-
sibling crates being able to conflict, as this impl would conflict with `impl<T>
200-
ForeignTrait<T> for LocalTypeInCrateB`.
194+
The primary change from the rules defined in in [RFC #1023] is that we only
195+
restrict the appearance of *uncovered* type parameters. Once again, it is
196+
important to note that for the purposes of coherence, `#[fundamental]` types are
197+
special. `Box<T>` is not considered covered, and `Box<LocalType>` is considered
198+
local.
201199

202200
Under this proposal, the orphan rules continue to work generally as they did
203201
before, with one notable exception; We will permit `impl<T>
@@ -228,14 +226,34 @@ conflicting impls, with or without this proposal.
228226
## Effects on parent crates
229227

230228
[RFC #1023] is amended to state that adding a new impl to an existing trait is
231-
considered a breaking change if, given `impl<P1...Pn> Trait<T1...Tn> for T0`,
232-
any type `T0...Tn` is an uncovered type parameter (is any of `P1...Pn`).
229+
considered a breaking change unless, given `impl<P1..=Pn> Trait<T1..=Tn> for
230+
T0`:
231+
232+
- At least one of the types `T0..=Tn` must be a local type, added in this
233+
revision. Let `Ti` be the first such type.
234+
- No uncovered type parameters `P1..=Pn` appear in `T0..Ti` (excluding `Ti`)
235+
236+
The more general way to put this rule is: "Adding an impl to an existing trait
237+
is a breaking change if it could possibly conflict with a legal impl in a
238+
downstream crate".
233239

234240
This clarification is true regardless of whether the changes in this proposal
235241
are accepted or not. Given that the compiler currently accepts `impl From<Foo> for
236242
Vec<Foo>`, adding the impl `impl<T> From<T> for Vec<T>` *must* be considered a
237-
major breaking change. Note that the problem is `From<T>`, not `Vec<T>`. Adding
238-
`impl<T> From<i32> for Vec<T>` is not a breaking change.
243+
major breaking change.
244+
245+
To be specific, the following adding any of the following impls would be
246+
considered a breaking change:
247+
248+
- `impl<T> OldTrait<T> for OldType`
249+
- `impl<T> OldTrait<AnyType> for T`
250+
- `impl<T> OldTrait<T> for ForeignType`
251+
252+
However, the following impls would not be considered a breaking change:
253+
254+
- `impl NewTrait<AnyType> for AnyType`
255+
- `impl<T> OldTrait<T> for NewType`
256+
- `impl<T> OldTrait<NewType, T> for OldType`
239257

240258
# Drawbacks
241259
[drawbacks]: #drawbacks

0 commit comments

Comments
 (0)