@@ -251,16 +251,84 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
251
251
} ) ;
252
252
}
253
253
254
+ fn check_auto_trait ( & mut self ,
255
+ trait_def_id : DefId ,
256
+ items : & [ hir:: TraitItem ] ,
257
+ span : Span )
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
+
269
+ let predicates = self . tcx ( ) . lookup_predicates ( trait_def_id) ;
270
+
271
+ // We must exclude the Self : Trait predicate contained by all
272
+ // traits.
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
+ } ,
280
+ _ => true ,
281
+ }
282
+ } ) ;
283
+
284
+ let trait_def = self . tcx ( ) . lookup_trait_def ( trait_def_id) ;
285
+
286
+ let has_ty_params =
287
+ trait_def. generics
288
+ . types
289
+ . len ( ) > 1 ;
290
+
291
+ // We use an if-else here, since the generics will also trigger
292
+ // an extraneous error message when we find predicates like
293
+ // `T : Sized` for a trait like: `trait Magic<T>`.
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
+ let mut err = None ;
300
+ if !items. is_empty ( ) {
301
+ error_380 ( self . ccx , span) ;
302
+ } else if has_ty_params {
303
+ err = Some ( struct_span_err ! ( self . tcx( ) . sess, span, E0566 ,
304
+ "traits with auto impls (`e.g. impl \
305
+ Trait for ..`) can not have type parameters") ) ;
306
+ } else if has_predicates {
307
+ err = Some ( struct_span_err ! ( self . tcx( ) . sess, span, E0565 ,
308
+ "traits with auto impls (`e.g. impl \
309
+ Trait for ..`) cannot have predicates") ) ;
310
+ }
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
+ match err {
315
+ None => { } ,
316
+ Some ( mut e) => {
317
+ e. note ( "the new auto trait rules are the result of a \
318
+ recent soundness fix; see #29859 for more details") ;
319
+ e. emit ( ) ;
320
+ }
321
+ }
322
+ }
323
+
254
324
fn check_trait ( & mut self ,
255
325
item : & hir:: Item ,
256
326
items : & [ hir:: TraitItem ] )
257
327
{
258
328
let trait_def_id = self . tcx ( ) . map . local_def_id ( item. id ) ;
259
329
260
330
if self . tcx ( ) . trait_has_default_impl ( trait_def_id) {
261
- if !items. is_empty ( ) {
262
- error_380 ( self . ccx , item. span ) ;
263
- }
331
+ self . check_auto_trait ( trait_def_id, items, item. span ) ;
264
332
}
265
333
266
334
self . for_item ( item) . with_fcx ( |fcx, this| {
@@ -618,7 +686,7 @@ fn error_192(ccx: &CrateCtxt, span: Span) {
618
686
619
687
fn error_380 ( ccx : & CrateCtxt , span : Span ) {
620
688
span_err ! ( ccx. tcx. sess, span, E0380 ,
621
- "traits with default impls (`e.g. unsafe impl \
689
+ "traits with default impls (`e.g. impl \
622
690
Trait for ..`) must have no methods or associated items")
623
691
}
624
692
0 commit comments