1
+ use std:: assert_matches:: assert_matches;
1
2
use std:: ops:: ControlFlow ;
2
3
3
4
use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
4
5
use rustc_errors:: codes:: * ;
5
6
use rustc_errors:: struct_span_code_err;
6
7
use rustc_hir as hir;
8
+ use rustc_hir:: PolyTraitRef ;
7
9
use rustc_hir:: def:: { DefKind , Res } ;
8
10
use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId } ;
9
- use rustc_hir:: { AmbigArg , PolyTraitRef } ;
10
11
use rustc_middle:: bug;
11
12
use rustc_middle:: ty:: {
12
13
self as ty, IsSuggestable , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
@@ -230,122 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230
231
}
231
232
}
232
233
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
+ /// Sets `experimental_default_bounds` to true on trait super bounds.
349
235
pub ( crate ) fn add_default_super_traits (
350
236
& self ,
351
237
trait_def_id : LocalDefId ,
@@ -354,21 +240,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
354
240
hir_generics : & ' tcx hir:: Generics < ' tcx > ,
355
241
span : Span ,
356
242
) {
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
+ if self . tcx ( ) . trait_is_auto ( trait_def_id. to_def_id ( ) ) {
358
246
return ;
359
247
}
360
248
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
- }
249
+ self . add_default_traits (
250
+ bounds,
251
+ self . tcx ( ) . types . self_param ,
252
+ hir_bounds,
253
+ Some ( ( trait_def_id, hir_generics. predicates ) ) ,
254
+ span,
255
+ ) ;
372
256
}
373
257
374
258
pub ( crate ) fn add_default_traits (
0 commit comments