@@ -2,9 +2,13 @@ use rustc_errors::DiagnosticBuilder;
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;
@@ -78,6 +82,15 @@ crate trait ToUniverseInfo<'tcx> {
7882 fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > ;
7983}
8084
85+ impl < ' tcx > ToUniverseInfo < ' tcx > for crate :: type_check:: InstantiateOpaqueType < ' tcx > {
86+ fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
87+ UniverseInfo ( UniverseInfoInner :: TypeOp ( Rc :: new ( crate :: type_check:: InstantiateOpaqueType {
88+ base_universe : Some ( base_universe) ,
89+ ..self
90+ } ) ) )
91+ }
92+ }
93+
8194impl < ' tcx > ToUniverseInfo < ' tcx >
8295 for Canonical < ' tcx , ty:: ParamEnvAnd < ' tcx , type_op:: prove_predicate:: ProvePredicate < ' tcx > > >
8396{
@@ -118,6 +131,12 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo
118131 }
119132}
120133
134+ impl < ' tcx > ToUniverseInfo < ' tcx > for ! {
135+ fn to_universe_info ( self , _base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
136+ self
137+ }
138+ }
139+
121140#[ allow( unused_lifetimes) ]
122141trait TypeOpInfo < ' tcx > {
123142 /// Returns an error to be reported if rerunning the type op fails to
@@ -128,7 +147,7 @@ trait TypeOpInfo<'tcx> {
128147
129148 fn nice_error (
130149 & self ,
131- tcx : TyCtxt < ' tcx > ,
150+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
132151 cause : ObligationCause < ' tcx > ,
133152 placeholder_region : ty:: Region < ' tcx > ,
134153 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 nice_error. buffer ( & mut mbcx. errors_buffer ) ;
@@ -204,16 +223,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
204223
205224 fn nice_error (
206225 & self ,
207- tcx : TyCtxt < ' tcx > ,
226+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
208227 cause : ObligationCause < ' tcx > ,
209228 placeholder_region : ty:: Region < ' tcx > ,
210229 error_region : Option < ty:: Region < ' tcx > > ,
211230 ) -> Option < DiagnosticBuilder < ' tcx > > {
212- tcx. infer_ctxt ( ) . enter_with_canonical (
231+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
213232 cause. span ,
214233 & self . canonical_query ,
215234 |ref infcx, key, _| {
216- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
235+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
217236 type_op_prove_predicate_with_cause ( infcx, & mut * fulfill_cx, key, cause) ;
218237 try_extract_error_from_fulfill_cx (
219238 fulfill_cx,
@@ -247,16 +266,16 @@ where
247266
248267 fn nice_error (
249268 & self ,
250- tcx : TyCtxt < ' tcx > ,
269+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
251270 cause : ObligationCause < ' tcx > ,
252271 placeholder_region : ty:: Region < ' tcx > ,
253272 error_region : Option < ty:: Region < ' tcx > > ,
254273 ) -> Option < DiagnosticBuilder < ' tcx > > {
255- tcx. infer_ctxt ( ) . enter_with_canonical (
274+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
256275 cause. span ,
257276 & self . canonical_query ,
258277 |ref infcx, key, _| {
259- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
278+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
260279
261280 let mut selcx = SelectionContext :: new ( infcx) ;
262281
@@ -304,16 +323,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
304323
305324 fn nice_error (
306325 & self ,
307- tcx : TyCtxt < ' tcx > ,
326+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
308327 cause : ObligationCause < ' tcx > ,
309328 placeholder_region : ty:: Region < ' tcx > ,
310329 error_region : Option < ty:: Region < ' tcx > > ,
311330 ) -> Option < DiagnosticBuilder < ' tcx > > {
312- tcx. infer_ctxt ( ) . enter_with_canonical (
331+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
313332 cause. span ,
314333 & self . canonical_query ,
315334 |ref infcx, key, _| {
316- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
335+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
317336 type_op_ascribe_user_type_with_span ( infcx, & mut * fulfill_cx, key, Some ( cause. span ) )
318337 . ok ( ) ?;
319338 try_extract_error_from_fulfill_cx (
@@ -327,43 +346,90 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
327346 }
328347}
329348
349+ impl < ' tcx > TypeOpInfo < ' tcx > for crate :: type_check:: InstantiateOpaqueType < ' tcx > {
350+ fn fallback_error ( & self , tcx : TyCtxt < ' tcx > , span : Span ) -> DiagnosticBuilder < ' tcx > {
351+ // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
352+ // and is only the fallback when the nice error fails. Consider improving this some more.
353+ tcx. sess . struct_span_err ( span, "higher-ranked lifetime error for opaque type!" )
354+ }
355+
356+ fn base_universe ( & self ) -> ty:: UniverseIndex {
357+ self . base_universe . unwrap ( )
358+ }
359+
360+ fn nice_error (
361+ & self ,
362+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
363+ _cause : ObligationCause < ' tcx > ,
364+ placeholder_region : ty:: Region < ' tcx > ,
365+ error_region : Option < ty:: Region < ' tcx > > ,
366+ ) -> Option < DiagnosticBuilder < ' tcx > > {
367+ try_extract_error_from_region_constraints (
368+ mbcx. infcx ,
369+ placeholder_region,
370+ error_region,
371+ self . region_constraints . as_ref ( ) . unwrap ( ) ,
372+ // We're using the original `InferCtxt` that we
373+ // started MIR borrowchecking with, so the region
374+ // constraints have already been taken. Use the data from
375+ // our `mbcx` instead.
376+ |vid| mbcx. regioncx . var_infos [ vid] . origin ,
377+ |vid| mbcx. regioncx . var_infos [ vid] . universe ,
378+ )
379+ }
380+ }
381+
330382#[ instrument( skip( fulfill_cx, infcx) , level = "debug" ) ]
331383fn try_extract_error_from_fulfill_cx < ' tcx > (
332384 mut fulfill_cx : Box < dyn TraitEngine < ' tcx > + ' tcx > ,
333385 infcx : & InferCtxt < ' _ , ' tcx > ,
334386 placeholder_region : ty:: Region < ' tcx > ,
335387 error_region : Option < ty:: Region < ' tcx > > ,
336388) -> Option < DiagnosticBuilder < ' tcx > > {
337- let tcx = infcx. tcx ;
338-
339389 // We generally shouldn't have errors here because the query was
340390 // already run, but there's no point using `delay_span_bug`
341391 // when we're going to emit an error here anyway.
342392 let _errors = fulfill_cx. select_all_or_error ( infcx) ;
393+ let region_constraints = infcx. with_region_constraints ( |r| r. clone ( ) ) ;
394+ try_extract_error_from_region_constraints (
395+ infcx,
396+ placeholder_region,
397+ error_region,
398+ & region_constraints,
399+ |vid| infcx. region_var_origin ( vid) ,
400+ |vid| infcx. universe_of_region ( infcx. tcx . mk_region ( ty:: ReVar ( vid) ) ) ,
401+ )
402+ }
343403
344- let ( sub_region, cause) = infcx. with_region_constraints ( |region_constraints| {
345- debug ! ( "{:#?}" , region_constraints) ;
404+ fn try_extract_error_from_region_constraints < ' tcx > (
405+ infcx : & InferCtxt < ' _ , ' tcx > ,
406+ placeholder_region : ty:: Region < ' tcx > ,
407+ error_region : Option < ty:: Region < ' tcx > > ,
408+ region_constraints : & RegionConstraintData < ' tcx > ,
409+ mut region_var_origin : impl FnMut ( RegionVid ) -> RegionVariableOrigin ,
410+ mut universe_of_region : impl FnMut ( RegionVid ) -> UniverseIndex ,
411+ ) -> Option < DiagnosticBuilder < ' tcx > > {
412+ let ( sub_region, cause) =
346413 region_constraints. constraints . iter ( ) . find_map ( |( constraint, cause) | {
347414 match * constraint {
348415 Constraint :: RegSubReg ( sub, sup) if sup == placeholder_region && sup != sub => {
349416 Some ( ( sub, cause. clone ( ) ) )
350417 }
351418 // FIXME: Should this check the universe of the var?
352419 Constraint :: VarSubReg ( vid, sup) if sup == placeholder_region => {
353- Some ( ( tcx. mk_region ( ty:: ReVar ( vid) ) , cause. clone ( ) ) )
420+ Some ( ( infcx . tcx . mk_region ( ty:: ReVar ( vid) ) , cause. clone ( ) ) )
354421 }
355422 _ => None ,
356423 }
357- } )
358- } ) ?;
424+ } ) ?;
359425
360426 debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
361427 let nice_error = match ( error_region, sub_region) {
362428 ( Some ( error_region) , & ty:: ReVar ( vid) ) => NiceRegionError :: new (
363429 infcx,
364430 RegionResolutionError :: SubSupConflict (
365431 vid,
366- infcx . region_var_origin ( vid) ,
432+ region_var_origin ( vid) ,
367433 cause. clone ( ) ,
368434 error_region,
369435 cause. clone ( ) ,
@@ -380,8 +446,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
380446 infcx,
381447 RegionResolutionError :: UpperBoundUniverseConflict (
382448 vid,
383- infcx . region_var_origin ( vid) ,
384- infcx . universe_of_region ( sub_region ) ,
449+ region_var_origin ( vid) ,
450+ universe_of_region ( vid ) ,
385451 cause. clone ( ) ,
386452 placeholder_region,
387453 ) ,
0 commit comments