@@ -181,23 +181,21 @@ definition of blanket impl given above.
181
181
182
182
Assumes the same definitions [ as above] ( #definitions ) .
183
183
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
185
185
least one of the following is true:
186
186
187
187
- ` Trait ` is a local trait
188
- - ` Target ` is a local type
189
188
- 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
192
190
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 ` )
194
193
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.
201
199
202
200
Under this proposal, the orphan rules continue to work generally as they did
203
201
before, with one notable exception; We will permit `impl<T >
@@ -228,14 +226,34 @@ conflicting impls, with or without this proposal.
228
226
## Effects on parent crates
229
227
230
228
[ 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".
233
239
234
240
This clarification is true regardless of whether the changes in this proposal
235
241
are accepted or not. Given that the compiler currently accepts `impl From<Foo > for
236
242
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 `
239
257
240
258
# Drawbacks
241
259
[ drawbacks ] : #drawbacks
0 commit comments