@@ -23,9 +23,8 @@ use rustc_hir as hir;
2323use rustc_hir:: def_id:: LocalDefId ;
2424use rustc_index:: bit_set:: { BitSet , ChunkedBitSet } ;
2525use 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 } ;
2928use rustc_middle:: mir:: tcx:: PlaceTy ;
3029use rustc_middle:: mir:: * ;
3130use rustc_middle:: query:: Providers ;
@@ -123,9 +122,8 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
123122 return tcx. arena . alloc ( result) ;
124123 }
125124
126- let infcx = tcx. infer_ctxt ( ) . with_opaque_type_inference ( def) . build ( ) ;
127125 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 ;
129127 debug ! ( "mir_borrowck done" ) ;
130128
131129 tcx. arena . alloc ( opt_closure_req)
@@ -136,18 +134,15 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
136134/// Use `consumer_options: None` for the default behavior of returning
137135/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
138136/// 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" ) ]
140138fn do_mir_borrowck < ' tcx > (
141- infcx : & InferCtxt < ' tcx > ,
139+ tcx : TyCtxt < ' tcx > ,
142140 input_body : & Body < ' tcx > ,
143141 input_promoted : & IndexSlice < Promoted , Body < ' tcx > > ,
144142 consumer_options : Option < ConsumerOptions > ,
145143) -> ( BorrowCheckResult < ' tcx > , Option < Box < BodyWithBorrowckFacts < ' tcx > > > ) {
146144 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) ;
151146 let param_env = tcx. param_env ( def) ;
152147
153148 let mut local_names = IndexVec :: from_elem ( None , & input_body. local_decls ) ;
@@ -187,6 +182,12 @@ fn do_mir_borrowck<'tcx>(
187182 nll:: replace_regions_in_mir ( & infcx, param_env, & mut body_owned, & mut promoted) ;
188183 let body = & body_owned; // no further changes
189184
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+
190191 let location_table = LocationTable :: new ( body) ;
191192
192193 let move_data = MoveData :: gather_moves ( body, tcx, param_env, |_| true ) ;
@@ -440,13 +441,14 @@ fn do_mir_borrowck<'tcx>(
440441 ( result, body_with_facts)
441442}
442443
443- pub struct BorrowckInferCtxt < ' cx , ' tcx > {
444- pub ( crate ) infcx : & ' cx InferCtxt < ' tcx > ,
444+ pub struct BorrowckInferCtxt < ' tcx > {
445+ pub ( crate ) infcx : InferCtxt < ' tcx > ,
445446 pub ( crate ) reg_var_to_origin : RefCell < FxIndexMap < ty:: RegionVid , RegionCtxt > > ,
446447}
447448
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 ( ) ;
450452 BorrowckInferCtxt { infcx, reg_var_to_origin : RefCell :: new ( Default :: default ( ) ) }
451453 }
452454
@@ -492,18 +494,40 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
492494
493495 next_region
494496 }
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+ }
495519}
496520
497- impl < ' cx , ' tcx > Deref for BorrowckInferCtxt < ' cx , ' tcx > {
521+ impl < ' tcx > Deref for BorrowckInferCtxt < ' tcx > {
498522 type Target = InferCtxt < ' tcx > ;
499523
500- fn deref ( & self ) -> & ' cx Self :: Target {
501- self . infcx
524+ fn deref ( & self ) -> & Self :: Target {
525+ & self . infcx
502526 }
503527}
504528
505529struct MirBorrowckCtxt < ' cx , ' tcx > {
506- infcx : & ' cx BorrowckInferCtxt < ' cx , ' tcx > ,
530+ infcx : & ' cx BorrowckInferCtxt < ' tcx > ,
507531 param_env : ParamEnv < ' tcx > ,
508532 body : & ' cx Body < ' tcx > ,
509533 move_data : & ' cx MoveData < ' tcx > ,
0 commit comments