@@ -580,7 +580,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
580
580
obligation : & PredicateObligation < ' tcx > ,
581
581
) -> Result < EvaluationResult , OverflowError > {
582
582
debug_assert ! ( !self . infcx. next_trait_solver( ) ) ;
583
- self . evaluation_probe ( |this| {
583
+ self . evaluation_probe ( |this, _outer_universe | {
584
584
let goal =
585
585
this. infcx . resolve_vars_if_possible ( ( obligation. predicate , obligation. param_env ) ) ;
586
586
let mut result = this. evaluate_predicate_recursively (
@@ -596,13 +596,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
596
596
} )
597
597
}
598
598
599
+ /// Computes the evaluation result of `op`, discarding any constraints.
600
+ ///
601
+ /// This also runs for leak check to allow higher ranked region errors to impact
602
+ /// selection. By default it checks for leaks from all universes created inside of
603
+ /// `op`, but this can be overwritten if necessary.
599
604
fn evaluation_probe (
600
605
& mut self ,
601
- op : impl FnOnce ( & mut Self ) -> Result < EvaluationResult , OverflowError > ,
606
+ op : impl FnOnce ( & mut Self , & mut ty :: UniverseIndex ) -> Result < EvaluationResult , OverflowError > ,
602
607
) -> Result < EvaluationResult , OverflowError > {
603
608
self . infcx . probe ( |snapshot| -> Result < EvaluationResult , OverflowError > {
604
- let outer_universe = self . infcx . universe ( ) ;
605
- let result = op ( self ) ?;
609
+ let mut outer_universe = self . infcx . universe ( ) ;
610
+ let result = op ( self , & mut outer_universe ) ?;
606
611
607
612
match self . infcx . leak_check ( outer_universe, Some ( snapshot) ) {
608
613
Ok ( ( ) ) => { }
@@ -1265,9 +1270,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1265
1270
stack : & TraitObligationStack < ' o , ' tcx > ,
1266
1271
candidate : & SelectionCandidate < ' tcx > ,
1267
1272
) -> Result < EvaluationResult , OverflowError > {
1268
- let mut result = self . evaluation_probe ( |this| {
1269
- let candidate = ( * candidate) . clone ( ) ;
1270
- match this. confirm_candidate ( stack. obligation , candidate) {
1273
+ let mut result = self . evaluation_probe ( |this, outer_universe| {
1274
+ // We eagerly instantiate higher ranked goals to prevent universe errors
1275
+ // from impacting candidate selection. This matches the behavior of the new
1276
+ // solver. This slightly weakens type inference.
1277
+ //
1278
+ // In case there are no unresolved type or const variables this
1279
+ // should still not be necessary to select a unique impl as any overlap
1280
+ // relying on a universe error from higher ranked goals should have resulted
1281
+ // in an overlap error in coherence.
1282
+ let p = self . infcx . instantiate_binder_with_placeholders ( stack. obligation . predicate ) ;
1283
+ let obligation = stack. obligation . with ( this. tcx ( ) , ty:: Binder :: dummy ( p) ) ;
1284
+ * outer_universe = self . infcx . universe ( ) ;
1285
+ match this. confirm_candidate ( & obligation, candidate. clone ( ) ) {
1271
1286
Ok ( selection) => {
1272
1287
debug ! ( ?selection) ;
1273
1288
this. evaluate_predicates_recursively (
@@ -1704,8 +1719,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1704
1719
stack : & TraitObligationStack < ' o , ' tcx > ,
1705
1720
where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1706
1721
) -> Result < EvaluationResult , OverflowError > {
1707
- self . evaluation_probe ( |this| {
1708
- match this. match_where_clause_trait_ref ( stack. obligation , where_clause_trait_ref) {
1722
+ self . evaluation_probe ( |this, outer_universe| {
1723
+ // Eagerly instantiate higher ranked goals.
1724
+ //
1725
+ // See the comment in `evaluate_candidate` to see why.
1726
+ let p = self . infcx . instantiate_binder_with_placeholders ( stack. obligation . predicate ) ;
1727
+ let obligation = stack. obligation . with ( this. tcx ( ) , ty:: Binder :: dummy ( p) ) ;
1728
+ * outer_universe = self . infcx . universe ( ) ;
1729
+ match this. match_where_clause_trait_ref ( & obligation, where_clause_trait_ref) {
1709
1730
Ok ( obligations) => this. evaluate_predicates_recursively ( stack. list ( ) , obligations) ,
1710
1731
Err ( ( ) ) => Ok ( EvaluatedToErr ) ,
1711
1732
}
0 commit comments