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.
349235 pub ( 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