@@ -252,33 +252,71 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
252
252
}
253
253
254
254
fn check_auto_trait ( & mut self ,
255
- trait_def_id : DefId ,
256
- span : Span )
255
+ trait_def_id : DefId ,
256
+ items : & [ hir:: TraitItem ] ,
257
+ span : Span )
257
258
{
259
+ // We want to ensure:
260
+ //
261
+ // 1) that there are no items contained within
262
+ // the trait defintion
263
+ //
264
+ // 2) that the definition doesn't violate the no-super trait rule
265
+ // for auto traits.
266
+ //
267
+ // 3) that the trait definition does not have any type parameters
268
+
258
269
let predicates = self . tcx ( ) . lookup_predicates ( trait_def_id) ;
259
270
260
- // If we must exclude the Self : Trait predicate contained by all
271
+ // We must exclude the Self : Trait predicate contained by all
261
272
// traits.
262
- let no_refl_predicates : Vec < _ > =
263
- predicates. predicates . iter ( ) . filter ( |predicate| {
264
- match * predicate {
265
- & ty:: Predicate :: Trait ( ref poly_trait_ref) =>
266
- poly_trait_ref. def_id ( ) != trait_def_id,
273
+ let has_predicates =
274
+ predicates. predicates . iter ( ) . any ( |predicate| {
275
+ match predicate {
276
+ & ty:: Predicate :: Trait ( ref poly_trait_ref) => {
277
+ let self_ty = poly_trait_ref. 0 . self_ty ( ) ;
278
+ !( self_ty. is_self ( ) && poly_trait_ref. def_id ( ) == trait_def_id)
279
+ } ,
267
280
_ => true ,
268
- }
269
- } ) . collect ( ) ;
281
+ }
282
+ } ) ;
270
283
271
284
let trait_def = self . tcx ( ) . lookup_trait_def ( trait_def_id) ;
272
285
286
+ let has_ty_params =
287
+ trait_def. generics
288
+ . types
289
+ . len ( ) > 1 ;
290
+
273
291
// We use an if-else here, since the generics will also trigger
274
292
// an extraneous error message when we find predicates like
275
293
// `T : Sized` for a trait like: `trait Magic<T>`.
276
- if !trait_def. generics . types . get_slice ( ParamSpace :: TypeSpace ) . is_empty ( ) {
277
- error_566 ( self . ccx , span) ;
278
- } else if !no_refl_predicates. is_empty ( ) {
279
- error_565 ( self . ccx , span) ;
294
+ //
295
+ // We also put the check on the number of items here,
296
+ // as it seems confusing to report an error about
297
+ // extraneous predicates created by things like
298
+ // an associated type inside the trait.
299
+
300
+ if !items. is_empty ( ) {
301
+ error_380 ( self . ccx , span) ;
302
+ } else if has_ty_params {
303
+ span_err ! ( self . tcx( ) . sess, span, E0566 ,
304
+ "traits with auto impls (`e.g. unsafe impl \
305
+ Trait for ..`) can not have type parameters")
306
+ } else if has_predicates {
307
+ span_err ! ( self . tcx( ) . sess, span, E0565 ,
308
+ "traits with auto impls (`e.g. unsafe impl \
309
+ Trait for ..`) can not have predicates")
280
310
}
281
311
312
+ // Finally if either of the above conditions apply we should add a note
313
+ // indicating that this error is the result of a recent soundness fix.
314
+ if has_ty_params || has_predicates {
315
+ self . tcx ( ) . sess . span_note_without_error (
316
+ span,
317
+ "the new auto trait rules are the result of a \
318
+ recent soundness fix; see #29859 for more details")
319
+ }
282
320
}
283
321
284
322
fn check_trait ( & mut self ,
@@ -287,19 +325,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
287
325
{
288
326
let trait_def_id = self . tcx ( ) . map . local_def_id ( item. id ) ;
289
327
328
+ // TODO: in a second pass, globally rename to auto_trait,
329
+ // from default_impl.
290
330
if self . tcx ( ) . trait_has_default_impl ( trait_def_id) {
291
- // We want to both ensure:
292
- // 1) that there are no items contained within
293
- // the trait defintion
294
- //
295
- // 2) that the definition doesn't violate the no-super trait rule
296
- // for auto traits.
297
-
298
- if !items. is_empty ( ) {
299
- error_380 ( self . ccx , item. span ) ;
300
- }
301
-
302
- self . check_auto_trait ( trait_def_id, item. span ) ;
331
+ self . check_auto_trait ( trait_def_id, items, item. span ) ;
303
332
}
304
333
305
334
self . for_item ( item) . with_fcx ( |fcx, this| {
@@ -311,8 +340,6 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
311
340
} ) ;
312
341
}
313
342
314
-
315
-
316
343
fn check_item_fn ( & mut self ,
317
344
item : & hir:: Item ,
318
345
body : & hir:: Block )
@@ -663,18 +690,6 @@ fn error_380(ccx: &CrateCtxt, span: Span) {
663
690
Trait for ..`) must have no methods or associated items")
664
691
}
665
692
666
- fn error_565 ( ccx : & CrateCtxt , span : Span ) {
667
- span_err ! ( ccx. tcx. sess, span, E0565 ,
668
- "traits with default impls (`e.g. unsafe impl \
669
- Trait for ..`) can not have predicates")
670
- }
671
-
672
- fn error_566 ( ccx : & CrateCtxt , span : Span ) {
673
- span_err ! ( ccx. tcx. sess, span, E0566 ,
674
- "traits with default impls (`e.g. unsafe impl \
675
- Trait for ..`) can not have type parameters")
676
- }
677
-
678
693
fn error_392 < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > , span : Span , param_name : ast:: Name )
679
694
-> DiagnosticBuilder < ' tcx > {
680
695
let mut err = struct_span_err ! ( ccx. tcx. sess, span, E0392 ,
0 commit comments