@@ -23,9 +23,8 @@ use rustc_hir as hir;
23
23
use rustc_hir:: def_id:: LocalDefId ;
24
24
use rustc_index:: bit_set:: { BitSet , ChunkedBitSet } ;
25
25
use rustc_index:: { IndexSlice , IndexVec } ;
26
- use rustc_infer:: infer:: {
27
- InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin , TyCtxtInferExt ,
28
- } ;
26
+ use rustc_infer:: infer:: TyCtxtInferExt ;
27
+ use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin , RegionVariableOrigin } ;
29
28
use rustc_middle:: mir:: tcx:: PlaceTy ;
30
29
use rustc_middle:: mir:: * ;
31
30
use rustc_middle:: query:: Providers ;
@@ -123,9 +122,8 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
123
122
return tcx. arena . alloc ( result) ;
124
123
}
125
124
126
- let infcx = tcx. infer_ctxt ( ) . with_opaque_type_inference ( def) . build ( ) ;
127
125
let promoted: & IndexSlice < _ , _ > = & promoted. borrow ( ) ;
128
- let opt_closure_req = do_mir_borrowck ( & infcx , input_body, promoted, None ) . 0 ;
126
+ let opt_closure_req = do_mir_borrowck ( tcx , input_body, promoted, None ) . 0 ;
129
127
debug ! ( "mir_borrowck done" ) ;
130
128
131
129
tcx. arena . alloc ( opt_closure_req)
@@ -136,18 +134,15 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
136
134
/// Use `consumer_options: None` for the default behavior of returning
137
135
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
138
136
/// to the given [`ConsumerOptions`].
139
- #[ instrument( skip( infcx , input_body, input_promoted) , fields( id=?input_body. source. def_id( ) ) , level = "debug" ) ]
137
+ #[ instrument( skip( tcx , input_body, input_promoted) , fields( id=?input_body. source. def_id( ) ) , level = "debug" ) ]
140
138
fn do_mir_borrowck < ' tcx > (
141
- infcx : & InferCtxt < ' tcx > ,
139
+ tcx : TyCtxt < ' tcx > ,
142
140
input_body : & Body < ' tcx > ,
143
141
input_promoted : & IndexSlice < Promoted , Body < ' tcx > > ,
144
142
consumer_options : Option < ConsumerOptions > ,
145
143
) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
146
144
let def = input_body. source . def_id ( ) . expect_local ( ) ;
147
- debug ! ( ?def) ;
148
-
149
- let tcx = infcx. tcx ;
150
- let infcx = BorrowckInferCtxt :: new ( infcx) ;
145
+ let infcx = BorrowckInferCtxt :: new ( tcx, def) ;
151
146
let param_env = tcx. param_env ( def) ;
152
147
153
148
let mut local_names = IndexVec :: from_elem ( None , & input_body. local_decls ) ;
@@ -187,6 +182,12 @@ fn do_mir_borrowck<'tcx>(
187
182
nll:: replace_regions_in_mir ( & infcx, param_env, & mut body_owned, & mut promoted) ;
188
183
let body = & body_owned; // no further changes
189
184
185
+ // FIXME(-Znext-solver): A bit dubious that we're only registering
186
+ // predefined opaques in the typeck root.
187
+ if infcx. next_trait_solver ( ) && !infcx. tcx . is_typeck_child ( body. source . def_id ( ) ) {
188
+ infcx. register_predefined_opaques_for_next_solver ( def) ;
189
+ }
190
+
190
191
let location_table = LocationTable :: new ( body) ;
191
192
192
193
let move_data = MoveData :: gather_moves ( body, tcx, param_env, |_| true ) ;
@@ -440,13 +441,14 @@ fn do_mir_borrowck<'tcx>(
440
441
( result, body_with_facts)
441
442
}
442
443
443
- pub struct BorrowckInferCtxt < ' cx , ' tcx > {
444
- pub ( crate ) infcx : & ' cx InferCtxt < ' tcx > ,
444
+ pub struct BorrowckInferCtxt < ' tcx > {
445
+ pub ( crate ) infcx : InferCtxt < ' tcx > ,
445
446
pub ( crate ) reg_var_to_origin : RefCell < FxIndexMap < ty:: RegionVid , RegionCtxt > > ,
446
447
}
447
448
448
- impl < ' cx , ' tcx > BorrowckInferCtxt < ' cx , ' tcx > {
449
- pub ( crate ) fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> Self {
449
+ impl < ' tcx > BorrowckInferCtxt < ' tcx > {
450
+ pub ( crate ) fn new ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> Self {
451
+ let infcx = tcx. infer_ctxt ( ) . with_opaque_type_inference ( def_id) . build ( ) ;
450
452
BorrowckInferCtxt { infcx, reg_var_to_origin : RefCell :: new ( Default :: default ( ) ) }
451
453
}
452
454
@@ -492,18 +494,40 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
492
494
493
495
next_region
494
496
}
497
+
498
+ /// With the new solver we prepopulate the opaque type storage during
499
+ /// MIR borrowck with the hidden types from HIR typeck. This is necessary
500
+ /// to avoid ambiguities as earlier goals can rely on the hidden type
501
+ /// of an opaque which is only constrained by a later goal.
502
+ fn register_predefined_opaques_for_next_solver ( & self , def_id : LocalDefId ) {
503
+ let tcx = self . tcx ;
504
+ // OK to use the identity arguments for each opaque type key, since
505
+ // we remap opaques from HIR typeck back to their definition params.
506
+ for data in tcx. typeck ( def_id) . concrete_opaque_types . iter ( ) . map ( |( k, v) | ( * k, * v) ) {
507
+ // HIR typeck did not infer the regions of the opaque, so we instantiate
508
+ // them with fresh inference variables.
509
+ let ( key, hidden_ty) = tcx. fold_regions ( data, |_, _| {
510
+ self . next_nll_region_var_in_universe (
511
+ NllRegionVariableOrigin :: Existential { from_forall : false } ,
512
+ ty:: UniverseIndex :: ROOT ,
513
+ )
514
+ } ) ;
515
+
516
+ self . inject_new_hidden_type_unchecked ( key, hidden_ty) ;
517
+ }
518
+ }
495
519
}
496
520
497
- impl < ' cx , ' tcx > Deref for BorrowckInferCtxt < ' cx , ' tcx > {
521
+ impl < ' tcx > Deref for BorrowckInferCtxt < ' tcx > {
498
522
type Target = InferCtxt < ' tcx > ;
499
523
500
- fn deref ( & self ) -> & ' cx Self :: Target {
501
- self . infcx
524
+ fn deref ( & self ) -> & Self :: Target {
525
+ & self . infcx
502
526
}
503
527
}
504
528
505
529
struct MirBorrowckCtxt < ' cx , ' tcx > {
506
- infcx : & ' cx BorrowckInferCtxt < ' cx , ' tcx > ,
530
+ infcx : & ' cx BorrowckInferCtxt < ' tcx > ,
507
531
param_env : ParamEnv < ' tcx > ,
508
532
body : & ' cx Body < ' tcx > ,
509
533
move_data : & ' cx MoveData < ' tcx > ,
0 commit comments