@@ -326,9 +326,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
326
326
let mut user_computed_preds: FxHashSet < _ > =
327
327
user_env. caller_bounds . iter ( ) . cloned ( ) . collect ( ) ;
328
328
329
-
330
-
331
-
332
329
let mut new_env = param_env. clone ( ) ;
333
330
let dummy_cause = ObligationCause :: misc ( DUMMY_SP , ast:: DUMMY_NODE_ID ) ;
334
331
@@ -362,7 +359,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
362
359
if self . is_of_param ( pred. skip_binder ( ) . trait_ref . substs ) {
363
360
already_visited. remove ( & pred) ;
364
361
self . add_user_pred ( & mut user_computed_preds, ty:: Predicate :: Trait ( pred. clone ( ) ) ) ;
365
- //user_computed_preds.insert(ty::Predicate::Trait(pred.clone()));
366
362
predicates. push_back ( pred) ;
367
363
} else {
368
364
debug ! (
@@ -397,6 +393,29 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
397
393
return Some ( ( new_env, final_user_env) ) ;
398
394
}
399
395
396
+ // This method is designed to work around the following issue:
397
+ // When we compute auto trait bounds, we repeatedly call SelectionContext.select,
398
+ // progressively building a ParamEnv based on the results we get.
399
+ // However, our usage of SelectionContext differs from its normal use within the compiler,
400
+ // in that we capture and re-reprocess predicates from Unimplemented errors.
401
+ //
402
+ // This can lead to a corner case when dealing with region parameters.
403
+ // During our selection loop in evaluate_predicates, we might end up with
404
+ // two trait predicates that differ only in their region parameters:
405
+ // one containing a HRTB lifetime parameter, and one containing a 'normal'
406
+ // lifetime parameter. For example:
407
+ //
408
+ // T as MyTrait<'a>
409
+ // T as MyTrait<'static>
410
+ //
411
+ // If we put both of these predicates in our computed ParamEnv, we'll
412
+ // confuse SelectionContext, since it will (correctly) view both as being applicable.
413
+ //
414
+ // To solve this, we pick the 'more strict' lifetime bound - i.e. the HRTB
415
+ // Our end goal is to generate a user-visible description of the conditions
416
+ // under which a type implements an auto trait. A trait predicate involving
417
+ // a HRTB means that the type needs to work with any choice of lifetime,
418
+ // not just one specific lifetime (e.g. 'static).
400
419
fn add_user_pred < ' c > ( & self , user_computed_preds : & mut FxHashSet < ty:: Predicate < ' c > > , new_pred : ty:: Predicate < ' c > ) {
401
420
let mut should_add_new = true ;
402
421
user_computed_preds. retain ( |& old_pred| {
0 commit comments