@@ -256,16 +256,84 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
256
256
} ) ;
257
257
}
258
258
259
+ fn check_auto_trait ( & mut self ,
260
+ trait_def_id : DefId ,
261
+ items : & [ hir:: TraitItem ] ,
262
+ span : Span )
263
+ {
264
+ // We want to ensure:
265
+ //
266
+ // 1) that there are no items contained within
267
+ // the trait defintion
268
+ //
269
+ // 2) that the definition doesn't violate the no-super trait rule
270
+ // for auto traits.
271
+ //
272
+ // 3) that the trait definition does not have any type parameters
273
+
274
+ let predicates = self . tcx ( ) . lookup_predicates ( trait_def_id) ;
275
+
276
+ // We must exclude the Self : Trait predicate contained by all
277
+ // traits.
278
+ let has_predicates =
279
+ predicates. predicates . iter ( ) . any ( |predicate| {
280
+ match predicate {
281
+ & ty:: Predicate :: Trait ( ref poly_trait_ref) => {
282
+ let self_ty = poly_trait_ref. 0 . self_ty ( ) ;
283
+ !( self_ty. is_self ( ) && poly_trait_ref. def_id ( ) == trait_def_id)
284
+ } ,
285
+ _ => true ,
286
+ }
287
+ } ) ;
288
+
289
+ let trait_def = self . tcx ( ) . lookup_trait_def ( trait_def_id) ;
290
+
291
+ let has_ty_params =
292
+ trait_def. generics
293
+ . types
294
+ . len ( ) > 1 ;
295
+
296
+ // We use an if-else here, since the generics will also trigger
297
+ // an extraneous error message when we find predicates like
298
+ // `T : Sized` for a trait like: `trait Magic<T>`.
299
+ //
300
+ // We also put the check on the number of items here,
301
+ // as it seems confusing to report an error about
302
+ // extraneous predicates created by things like
303
+ // an associated type inside the trait.
304
+ let mut err = None ;
305
+ if !items. is_empty ( ) {
306
+ error_380 ( self . ccx , span) ;
307
+ } else if has_ty_params {
308
+ err = Some ( struct_span_err ! ( self . tcx( ) . sess, span, E0567 ,
309
+ "traits with auto impls (`e.g. impl \
310
+ Trait for ..`) can not have type parameters") ) ;
311
+ } else if has_predicates {
312
+ err = Some ( struct_span_err ! ( self . tcx( ) . sess, span, E0568 ,
313
+ "traits with auto impls (`e.g. impl \
314
+ Trait for ..`) cannot have predicates") ) ;
315
+ }
316
+
317
+ // Finally if either of the above conditions apply we should add a note
318
+ // indicating that this error is the result of a recent soundness fix.
319
+ match err {
320
+ None => { } ,
321
+ Some ( mut e) => {
322
+ e. note ( "the new auto trait rules are the result of a \
323
+ recent soundness fix; see #29859 for more details") ;
324
+ e. emit ( ) ;
325
+ }
326
+ }
327
+ }
328
+
259
329
fn check_trait ( & mut self ,
260
330
item : & hir:: Item ,
261
331
items : & [ hir:: TraitItem ] )
262
332
{
263
333
let trait_def_id = self . tcx ( ) . map . local_def_id ( item. id ) ;
264
334
265
335
if self . tcx ( ) . trait_has_default_impl ( trait_def_id) {
266
- if !items. is_empty ( ) {
267
- error_380 ( self . ccx , item. span ) ;
268
- }
336
+ self . check_auto_trait ( trait_def_id, items, item. span ) ;
269
337
}
270
338
271
339
self . for_item ( item) . with_fcx ( |fcx, this| {
@@ -626,7 +694,7 @@ fn error_192(ccx: &CrateCtxt, span: Span) {
626
694
627
695
fn error_380 ( ccx : & CrateCtxt , span : Span ) {
628
696
span_err ! ( ccx. tcx. sess, span, E0380 ,
629
- "traits with default impls (`e.g. unsafe impl \
697
+ "traits with default impls (`e.g. impl \
630
698
Trait for ..`) must have no methods or associated items")
631
699
}
632
700
0 commit comments