@@ -2,9 +2,13 @@ use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
2
2
use rustc_infer:: infer:: canonical:: Canonical ;
3
3
use rustc_infer:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
4
4
use rustc_infer:: infer:: region_constraints:: Constraint ;
5
+ use rustc_infer:: infer:: region_constraints:: RegionConstraintData ;
6
+ use rustc_infer:: infer:: RegionVariableOrigin ;
5
7
use rustc_infer:: infer:: { InferCtxt , RegionResolutionError , SubregionOrigin , TyCtxtInferExt as _} ;
6
8
use rustc_infer:: traits:: { Normalized , ObligationCause , TraitEngine , TraitEngineExt } ;
7
9
use rustc_middle:: ty:: error:: TypeError ;
10
+ use rustc_middle:: ty:: RegionVid ;
11
+ use rustc_middle:: ty:: UniverseIndex ;
8
12
use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
9
13
use rustc_span:: Span ;
10
14
use rustc_trait_selection:: traits:: query:: type_op;
@@ -76,6 +80,15 @@ crate trait ToUniverseInfo<'tcx> {
76
80
fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > ;
77
81
}
78
82
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
+
79
92
impl < ' tcx > ToUniverseInfo < ' tcx >
80
93
for Canonical < ' tcx , ty:: ParamEnvAnd < ' tcx , type_op:: prove_predicate:: ProvePredicate < ' tcx > > >
81
94
{
@@ -116,6 +129,12 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo
116
129
}
117
130
}
118
131
132
+ impl < ' tcx > ToUniverseInfo < ' tcx > for ! {
133
+ fn to_universe_info ( self , _base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
134
+ self
135
+ }
136
+ }
137
+
119
138
#[ allow( unused_lifetimes) ]
120
139
trait TypeOpInfo < ' tcx > {
121
140
/// Returns an error to be reported if rerunning the type op fails to
@@ -130,7 +149,7 @@ trait TypeOpInfo<'tcx> {
130
149
131
150
fn nice_error (
132
151
& self ,
133
- tcx : TyCtxt < ' tcx > ,
152
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
134
153
cause : ObligationCause < ' tcx > ,
135
154
placeholder_region : ty:: Region < ' tcx > ,
136
155
error_region : Option < ty:: Region < ' tcx > > ,
@@ -175,7 +194,7 @@ trait TypeOpInfo<'tcx> {
175
194
debug ! ( ?placeholder_region) ;
176
195
177
196
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) ;
179
198
180
199
if let Some ( nice_error) = nice_error {
181
200
mbcx. buffer_error ( nice_error) ;
@@ -208,16 +227,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
208
227
209
228
fn nice_error (
210
229
& self ,
211
- tcx : TyCtxt < ' tcx > ,
230
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
212
231
cause : ObligationCause < ' tcx > ,
213
232
placeholder_region : ty:: Region < ' tcx > ,
214
233
error_region : Option < ty:: Region < ' tcx > > ,
215
234
) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
216
- tcx. infer_ctxt ( ) . enter_with_canonical (
235
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
217
236
cause. span ,
218
237
& self . canonical_query ,
219
238
|ref infcx, key, _| {
220
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
239
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
221
240
type_op_prove_predicate_with_cause ( infcx, & mut * fulfill_cx, key, cause) ;
222
241
try_extract_error_from_fulfill_cx (
223
242
fulfill_cx,
@@ -255,16 +274,16 @@ where
255
274
256
275
fn nice_error (
257
276
& self ,
258
- tcx : TyCtxt < ' tcx > ,
277
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
259
278
cause : ObligationCause < ' tcx > ,
260
279
placeholder_region : ty:: Region < ' tcx > ,
261
280
error_region : Option < ty:: Region < ' tcx > > ,
262
281
) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
263
- tcx. infer_ctxt ( ) . enter_with_canonical (
282
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
264
283
cause. span ,
265
284
& self . canonical_query ,
266
285
|ref infcx, key, _| {
267
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
286
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
268
287
269
288
let mut selcx = SelectionContext :: new ( infcx) ;
270
289
@@ -316,16 +335,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
316
335
317
336
fn nice_error (
318
337
& self ,
319
- tcx : TyCtxt < ' tcx > ,
338
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
320
339
cause : ObligationCause < ' tcx > ,
321
340
placeholder_region : ty:: Region < ' tcx > ,
322
341
error_region : Option < ty:: Region < ' tcx > > ,
323
342
) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
324
- tcx. infer_ctxt ( ) . enter_with_canonical (
343
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
325
344
cause. span ,
326
345
& self . canonical_query ,
327
346
|ref infcx, key, _| {
328
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
347
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
329
348
type_op_ascribe_user_type_with_span ( infcx, & mut * fulfill_cx, key, Some ( cause. span ) )
330
349
. ok ( ) ?;
331
350
try_extract_error_from_fulfill_cx (
@@ -339,43 +358,94 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
339
358
}
340
359
}
341
360
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
+
342
398
#[ instrument( skip( fulfill_cx, infcx) , level = "debug" ) ]
343
399
fn try_extract_error_from_fulfill_cx < ' tcx > (
344
400
mut fulfill_cx : Box < dyn TraitEngine < ' tcx > + ' tcx > ,
345
401
infcx : & InferCtxt < ' _ , ' tcx > ,
346
402
placeholder_region : ty:: Region < ' tcx > ,
347
403
error_region : Option < ty:: Region < ' tcx > > ,
348
404
) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
349
- let tcx = infcx. tcx ;
350
-
351
405
// We generally shouldn't have errors here because the query was
352
406
// already run, but there's no point using `delay_span_bug`
353
407
// when we're going to emit an error here anyway.
354
408
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
+ }
355
419
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) =
358
429
region_constraints. constraints . iter ( ) . find_map ( |( constraint, cause) | {
359
430
match * constraint {
360
431
Constraint :: RegSubReg ( sub, sup) if sup == placeholder_region && sup != sub => {
361
432
Some ( ( sub, cause. clone ( ) ) )
362
433
}
363
434
// FIXME: Should this check the universe of the var?
364
435
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 ( ) ) )
366
437
}
367
438
_ => None ,
368
439
}
369
- } )
370
- } ) ?;
440
+ } ) ?;
371
441
372
442
debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
373
443
let nice_error = match ( error_region, * sub_region) {
374
444
( Some ( error_region) , ty:: ReVar ( vid) ) => NiceRegionError :: new (
375
445
infcx,
376
446
RegionResolutionError :: SubSupConflict (
377
447
vid,
378
- infcx . region_var_origin ( vid) ,
448
+ region_var_origin ( vid) ,
379
449
cause. clone ( ) ,
380
450
error_region,
381
451
cause. clone ( ) ,
@@ -392,8 +462,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
392
462
infcx,
393
463
RegionResolutionError :: UpperBoundUniverseConflict (
394
464
vid,
395
- infcx . region_var_origin ( vid) ,
396
- infcx . universe_of_region ( sub_region ) ,
465
+ region_var_origin ( vid) ,
466
+ universe_of_region ( vid ) ,
397
467
cause. clone ( ) ,
398
468
placeholder_region,
399
469
) ,
0 commit comments