@@ -2,9 +2,13 @@ use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
22use rustc_infer:: infer:: canonical:: Canonical ;
33use rustc_infer:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
44use rustc_infer:: infer:: region_constraints:: Constraint ;
5+ use rustc_infer:: infer:: region_constraints:: RegionConstraintData ;
6+ use rustc_infer:: infer:: RegionVariableOrigin ;
57use rustc_infer:: infer:: { InferCtxt , RegionResolutionError , SubregionOrigin , TyCtxtInferExt as _} ;
68use rustc_infer:: traits:: { Normalized , ObligationCause , TraitEngine , TraitEngineExt } ;
79use rustc_middle:: ty:: error:: TypeError ;
10+ use rustc_middle:: ty:: RegionVid ;
11+ use rustc_middle:: ty:: UniverseIndex ;
812use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
913use rustc_span:: Span ;
1014use rustc_trait_selection:: traits:: query:: type_op;
@@ -76,6 +80,15 @@ crate trait ToUniverseInfo<'tcx> {
7680 fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > ;
7781}
7882
83+ impl < ' tcx > ToUniverseInfo < ' tcx > for crate :: type_check:: InstantiateOpaqueType < ' tcx > {
84+ fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
85+ UniverseInfo ( UniverseInfoInner :: TypeOp ( Rc :: new ( crate :: type_check:: InstantiateOpaqueType {
86+ base_universe : Some ( base_universe) ,
87+ ..self
88+ } ) ) )
89+ }
90+ }
91+
7992impl < ' tcx > ToUniverseInfo < ' tcx >
8093 for Canonical < ' tcx , ty:: ParamEnvAnd < ' tcx , type_op:: prove_predicate:: ProvePredicate < ' tcx > > >
8194{
@@ -116,6 +129,12 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo
116129 }
117130}
118131
132+ impl < ' tcx > ToUniverseInfo < ' tcx > for ! {
133+ fn to_universe_info ( self , _base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
134+ self
135+ }
136+ }
137+
119138#[ allow( unused_lifetimes) ]
120139trait TypeOpInfo < ' tcx > {
121140 /// Returns an error to be reported if rerunning the type op fails to
@@ -130,7 +149,7 @@ trait TypeOpInfo<'tcx> {
130149
131150 fn nice_error (
132151 & self ,
133- tcx : TyCtxt < ' tcx > ,
152+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
134153 cause : ObligationCause < ' tcx > ,
135154 placeholder_region : ty:: Region < ' tcx > ,
136155 error_region : Option < ty:: Region < ' tcx > > ,
@@ -175,7 +194,7 @@ trait TypeOpInfo<'tcx> {
175194 debug ! ( ?placeholder_region) ;
176195
177196 let span = cause. span ;
178- let nice_error = self . nice_error ( tcx , cause, placeholder_region, error_region) ;
197+ let nice_error = self . nice_error ( mbcx , cause, placeholder_region, error_region) ;
179198
180199 if let Some ( nice_error) = nice_error {
181200 mbcx. buffer_error ( nice_error) ;
@@ -208,16 +227,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
208227
209228 fn nice_error (
210229 & self ,
211- tcx : TyCtxt < ' tcx > ,
230+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
212231 cause : ObligationCause < ' tcx > ,
213232 placeholder_region : ty:: Region < ' tcx > ,
214233 error_region : Option < ty:: Region < ' tcx > > ,
215234 ) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
216- tcx. infer_ctxt ( ) . enter_with_canonical (
235+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
217236 cause. span ,
218237 & self . canonical_query ,
219238 |ref infcx, key, _| {
220- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
239+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
221240 type_op_prove_predicate_with_cause ( infcx, & mut * fulfill_cx, key, cause) ;
222241 try_extract_error_from_fulfill_cx (
223242 fulfill_cx,
@@ -255,16 +274,16 @@ where
255274
256275 fn nice_error (
257276 & self ,
258- tcx : TyCtxt < ' tcx > ,
277+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
259278 cause : ObligationCause < ' tcx > ,
260279 placeholder_region : ty:: Region < ' tcx > ,
261280 error_region : Option < ty:: Region < ' tcx > > ,
262281 ) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
263- tcx. infer_ctxt ( ) . enter_with_canonical (
282+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
264283 cause. span ,
265284 & self . canonical_query ,
266285 |ref infcx, key, _| {
267- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
286+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
268287
269288 let mut selcx = SelectionContext :: new ( infcx) ;
270289
@@ -316,16 +335,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
316335
317336 fn nice_error (
318337 & self ,
319- tcx : TyCtxt < ' tcx > ,
338+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
320339 cause : ObligationCause < ' tcx > ,
321340 placeholder_region : ty:: Region < ' tcx > ,
322341 error_region : Option < ty:: Region < ' tcx > > ,
323342 ) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
324- tcx. infer_ctxt ( ) . enter_with_canonical (
343+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
325344 cause. span ,
326345 & self . canonical_query ,
327346 |ref infcx, key, _| {
328- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
347+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
329348 type_op_ascribe_user_type_with_span ( infcx, & mut * fulfill_cx, key, Some ( cause. span ) )
330349 . ok ( ) ?;
331350 try_extract_error_from_fulfill_cx (
@@ -339,43 +358,94 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
339358 }
340359}
341360
361+ impl < ' tcx > TypeOpInfo < ' tcx > for crate :: type_check:: InstantiateOpaqueType < ' tcx > {
362+ fn fallback_error (
363+ & self ,
364+ tcx : TyCtxt < ' tcx > ,
365+ span : Span ,
366+ ) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > {
367+ // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
368+ // and is only the fallback when the nice error fails. Consider improving this some more.
369+ tcx. sess . struct_span_err ( span, "higher-ranked lifetime error for opaque type!" )
370+ }
371+
372+ fn base_universe ( & self ) -> ty:: UniverseIndex {
373+ self . base_universe . unwrap ( )
374+ }
375+
376+ fn nice_error (
377+ & self ,
378+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
379+ _cause : ObligationCause < ' tcx > ,
380+ placeholder_region : ty:: Region < ' tcx > ,
381+ error_region : Option < ty:: Region < ' tcx > > ,
382+ ) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
383+ try_extract_error_from_region_constraints (
384+ mbcx. infcx ,
385+ placeholder_region,
386+ error_region,
387+ self . region_constraints . as_ref ( ) . unwrap ( ) ,
388+ // We're using the original `InferCtxt` that we
389+ // started MIR borrowchecking with, so the region
390+ // constraints have already been taken. Use the data from
391+ // our `mbcx` instead.
392+ |vid| mbcx. regioncx . var_infos [ vid] . origin ,
393+ |vid| mbcx. regioncx . var_infos [ vid] . universe ,
394+ )
395+ }
396+ }
397+
342398#[ instrument( skip( fulfill_cx, infcx) , level = "debug" ) ]
343399fn try_extract_error_from_fulfill_cx < ' tcx > (
344400 mut fulfill_cx : Box < dyn TraitEngine < ' tcx > + ' tcx > ,
345401 infcx : & InferCtxt < ' _ , ' tcx > ,
346402 placeholder_region : ty:: Region < ' tcx > ,
347403 error_region : Option < ty:: Region < ' tcx > > ,
348404) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
349- let tcx = infcx. tcx ;
350-
351405 // We generally shouldn't have errors here because the query was
352406 // already run, but there's no point using `delay_span_bug`
353407 // when we're going to emit an error here anyway.
354408 let _errors = fulfill_cx. select_all_or_error ( infcx) ;
409+ let region_constraints = infcx. with_region_constraints ( |r| r. clone ( ) ) ;
410+ try_extract_error_from_region_constraints (
411+ infcx,
412+ placeholder_region,
413+ error_region,
414+ & region_constraints,
415+ |vid| infcx. region_var_origin ( vid) ,
416+ |vid| infcx. universe_of_region ( infcx. tcx . mk_region ( ty:: ReVar ( vid) ) ) ,
417+ )
418+ }
355419
356- let ( sub_region, cause) = infcx. with_region_constraints ( |region_constraints| {
357- debug ! ( "{:#?}" , region_constraints) ;
420+ fn try_extract_error_from_region_constraints < ' tcx > (
421+ infcx : & InferCtxt < ' _ , ' tcx > ,
422+ placeholder_region : ty:: Region < ' tcx > ,
423+ error_region : Option < ty:: Region < ' tcx > > ,
424+ region_constraints : & RegionConstraintData < ' tcx > ,
425+ mut region_var_origin : impl FnMut ( RegionVid ) -> RegionVariableOrigin ,
426+ mut universe_of_region : impl FnMut ( RegionVid ) -> UniverseIndex ,
427+ ) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
428+ let ( sub_region, cause) =
358429 region_constraints. constraints . iter ( ) . find_map ( |( constraint, cause) | {
359430 match * constraint {
360431 Constraint :: RegSubReg ( sub, sup) if sup == placeholder_region && sup != sub => {
361432 Some ( ( sub, cause. clone ( ) ) )
362433 }
363434 // FIXME: Should this check the universe of the var?
364435 Constraint :: VarSubReg ( vid, sup) if sup == placeholder_region => {
365- Some ( ( tcx. mk_region ( ty:: ReVar ( vid) ) , cause. clone ( ) ) )
436+ Some ( ( infcx . tcx . mk_region ( ty:: ReVar ( vid) ) , cause. clone ( ) ) )
366437 }
367438 _ => None ,
368439 }
369- } )
370- } ) ?;
440+ } ) ?;
371441
372442 debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
373443 let nice_error = match ( error_region, * sub_region) {
374444 ( Some ( error_region) , ty:: ReVar ( vid) ) => NiceRegionError :: new (
375445 infcx,
376446 RegionResolutionError :: SubSupConflict (
377447 vid,
378- infcx . region_var_origin ( vid) ,
448+ region_var_origin ( vid) ,
379449 cause. clone ( ) ,
380450 error_region,
381451 cause. clone ( ) ,
@@ -392,8 +462,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
392462 infcx,
393463 RegionResolutionError :: UpperBoundUniverseConflict (
394464 vid,
395- infcx . region_var_origin ( vid) ,
396- infcx . universe_of_region ( sub_region ) ,
465+ region_var_origin ( vid) ,
466+ universe_of_region ( vid ) ,
397467 cause. clone ( ) ,
398468 placeholder_region,
399469 ) ,
0 commit comments