1+ use  std:: assert_matches:: assert_matches; 
12use  std:: ops:: ControlFlow ; 
23
34use  rustc_data_structures:: fx:: { FxIndexMap ,  FxIndexSet } ; 
45use  rustc_errors:: codes:: * ; 
56use  rustc_errors:: struct_span_code_err; 
67use  rustc_hir as  hir; 
8+ use  rustc_hir:: PolyTraitRef ; 
79use  rustc_hir:: def:: { DefKind ,  Res } ; 
810use  rustc_hir:: def_id:: { CRATE_DEF_ID ,  DefId ,  LocalDefId } ; 
9- use  rustc_hir:: { AmbigArg ,  PolyTraitRef } ; 
1011use  rustc_middle:: bug; 
1112use  rustc_middle:: ty:: { 
1213    self  as  ty,  IsSuggestable ,  Ty ,  TyCtxt ,  TypeSuperVisitable ,  TypeVisitable ,  TypeVisitableExt , 
@@ -230,122 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230231        } 
231232    } 
232233
233-     /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds 
234- /// or associated items. 
235- /// 
236- /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds 
237- /// should be added everywhere, including super bounds. However this causes a huge performance 
238- /// costs. For optimization purposes instead of adding default supertraits, bounds 
239- /// are added to the associated items: 
240- /// 
241- /// ```ignore(illustrative) 
242- /// // Default bounds are generated in the following way: 
243- /// trait Trait { 
244- ///     fn foo(&self) where Self: Leak {} 
245- /// } 
246- /// 
247- /// // instead of this: 
248- /// trait Trait: Leak { 
249- ///     fn foo(&self) {} 
250- /// } 
251- /// ``` 
252- /// It is not always possible to do this because of backward compatibility: 
253- /// 
254- /// ```ignore(illustrative) 
255- /// pub trait Trait<Rhs = Self> {} 
256- /// pub trait Trait1 : Trait {} 
257- /// //~^ ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait` 
258- /// ``` 
259- /// 
260- /// or: 
261- /// 
262- /// ```ignore(illustrative) 
263- /// trait Trait { 
264- ///     type Type where Self: Sized; 
265- /// } 
266- /// trait Trait2<T> : Trait<Type = T> {} 
267- /// //~^ ERROR: `DefaultAutoTrait` required for `Trait2`, by implicit  `Self: DefaultAutoTrait` in `Trait::Type` 
268- /// ``` 
269- /// 
270- /// Therefore, `experimental_default_bounds` are still being added to supertraits if 
271- /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header. 
272- fn  requires_default_supertraits ( 
273-         & self , 
274-         hir_bounds :  & ' tcx  [ hir:: GenericBound < ' tcx > ] , 
275-         hir_generics :  & ' tcx  hir:: Generics < ' tcx > , 
276-     )  -> bool  { 
277-         struct  TraitInfoCollector ; 
278- 
279-         impl < ' tcx >  hir:: intravisit:: Visitor < ' tcx >  for  TraitInfoCollector  { 
280-             type  Result  = ControlFlow < ( ) > ; 
281- 
282-             fn  visit_assoc_item_constraint ( 
283-                 & mut  self , 
284-                 _constraint :  & ' tcx  hir:: AssocItemConstraint < ' tcx > , 
285-             )  -> Self :: Result  { 
286-                 ControlFlow :: Break ( ( ) ) 
287-             } 
288- 
289-             fn  visit_ty ( & mut  self ,  t :  & ' tcx  hir:: Ty < ' tcx ,  AmbigArg > )  -> Self :: Result  { 
290-                 if  matches ! ( 
291-                     & t. kind, 
292-                     hir:: TyKind :: Path ( hir:: QPath :: Resolved ( 
293-                         _, 
294-                         hir:: Path  {  res:  hir:: def:: Res :: SelfTyParam  {  .. } ,  .. } , 
295-                     ) ) 
296-                 )  { 
297-                     return  ControlFlow :: Break ( ( ) ) ; 
298-                 } 
299-                 hir:: intravisit:: walk_ty ( self ,  t) 
300-             } 
301-         } 
302- 
303-         let  mut  found = false ; 
304-         for  bound in  hir_bounds { 
305-             found |= hir:: intravisit:: walk_param_bound ( & mut  TraitInfoCollector ,  bound) . is_break ( ) ; 
306-         } 
307-         found |= hir:: intravisit:: walk_generics ( & mut  TraitInfoCollector ,  hir_generics) . is_break ( ) ; 
308-         found
309-     } 
310- 
311-     /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if 
312- /// they are not added as super trait bounds to the trait itself. See 
313- /// `requires_default_supertraits` for more information. 
314- pub ( crate )  fn  add_default_trait_item_bounds ( 
315-         & self , 
316-         trait_item :  & hir:: TraitItem < ' tcx > , 
317-         bounds :  & mut  Vec < ( ty:: Clause < ' tcx > ,  Span ) > , 
318-     )  { 
319-         let  tcx = self . tcx ( ) ; 
320-         if  !tcx. sess . opts . unstable_opts . experimental_default_bounds  { 
321-             return ; 
322-         } 
323- 
324-         let  parent = tcx. local_parent ( trait_item. hir_id ( ) . owner . def_id ) ; 
325-         let  hir:: Node :: Item ( parent_trait)  = tcx. hir_node_by_def_id ( parent)  else  { 
326-             unreachable ! ( ) ; 
327-         } ; 
328- 
329-         let  ( trait_generics,  trait_bounds)  = match  parent_trait. kind  { 
330-             hir:: ItemKind :: Trait ( _,  _,  _,  _,  generics,  supertraits,  _)  => ( generics,  supertraits) , 
331-             hir:: ItemKind :: TraitAlias ( _,  generics,  supertraits)  => ( generics,  supertraits) , 
332-             _ => unreachable ! ( ) , 
333-         } ; 
334- 
335-         if  !self . requires_default_supertraits ( trait_bounds,  trait_generics)  { 
336-             let  self_ty_where_predicates = ( parent,  trait_item. generics . predicates ) ; 
337-             self . add_default_traits ( 
338-                 bounds, 
339-                 tcx. types . self_param , 
340-                 & [ ] , 
341-                 Some ( self_ty_where_predicates) , 
342-                 trait_item. span , 
343-             ) ; 
344-         } 
345-     } 
346- 
347-     /// Lazily sets `experimental_default_bounds` to true on trait super bounds. 
348- /// See `requires_default_supertraits` for more information. 
234+     /// Adds `experimental_default_bounds` bounds to the supertrait bounds. 
349235pub ( crate )  fn  add_default_super_traits ( 
350236        & self , 
351237        trait_def_id :  LocalDefId , 
@@ -354,21 +240,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
354240        hir_generics :  & ' tcx  hir:: Generics < ' tcx > , 
355241        span :  Span , 
356242    )  { 
357-         if  !self . tcx ( ) . sess . opts . unstable_opts . experimental_default_bounds  { 
243+         assert_matches ! ( self . tcx( ) . def_kind( trait_def_id) ,  DefKind :: Trait  | DefKind :: TraitAlias ) ; 
244+ 
245+         // Supertraits for auto trait are unsound according to the unstable book: 
246+         // https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits 
247+         if  self . tcx ( ) . trait_is_auto ( trait_def_id. to_def_id ( ) )  { 
358248            return ; 
359249        } 
360250
361-         assert ! ( matches!( self . tcx( ) . def_kind( trait_def_id) ,  DefKind :: Trait  | DefKind :: TraitAlias ) ) ; 
362-         if  self . requires_default_supertraits ( hir_bounds,  hir_generics)  { 
363-             let  self_ty_where_predicates = ( trait_def_id,  hir_generics. predicates ) ; 
364-             self . add_default_traits ( 
365-                 bounds, 
366-                 self . tcx ( ) . types . self_param , 
367-                 hir_bounds, 
368-                 Some ( self_ty_where_predicates) , 
369-                 span, 
370-             ) ; 
371-         } 
251+         self . add_default_traits ( 
252+             bounds, 
253+             self . tcx ( ) . types . self_param , 
254+             hir_bounds, 
255+             Some ( ( trait_def_id,  hir_generics. predicates ) ) , 
256+             span, 
257+         ) ; 
372258    } 
373259
374260    pub ( crate )  fn  add_default_traits ( 
0 commit comments