@@ -2,9 +2,13 @@ use rustc_errors::DiagnosticBuilder;
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;
@@ -78,6 +82,15 @@ crate trait ToUniverseInfo<'tcx> {
78
82
fn to_universe_info ( self , base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > ;
79
83
}
80
84
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
+
81
94
impl < ' tcx > ToUniverseInfo < ' tcx >
82
95
for Canonical < ' tcx , ty:: ParamEnvAnd < ' tcx , type_op:: prove_predicate:: ProvePredicate < ' tcx > > >
83
96
{
@@ -118,6 +131,12 @@ impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::Custo
118
131
}
119
132
}
120
133
134
+ impl < ' tcx > ToUniverseInfo < ' tcx > for ! {
135
+ fn to_universe_info ( self , _base_universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
136
+ self
137
+ }
138
+ }
139
+
121
140
#[ allow( unused_lifetimes) ]
122
141
trait TypeOpInfo < ' tcx > {
123
142
/// Returns an error to be reported if rerunning the type op fails to
@@ -128,7 +147,7 @@ trait TypeOpInfo<'tcx> {
128
147
129
148
fn nice_error (
130
149
& self ,
131
- tcx : TyCtxt < ' tcx > ,
150
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
132
151
cause : ObligationCause < ' tcx > ,
133
152
placeholder_region : ty:: Region < ' tcx > ,
134
153
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
nice_error. buffer ( & mut mbcx. errors_buffer ) ;
@@ -204,16 +223,16 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
204
223
205
224
fn nice_error (
206
225
& self ,
207
- tcx : TyCtxt < ' tcx > ,
226
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
208
227
cause : ObligationCause < ' tcx > ,
209
228
placeholder_region : ty:: Region < ' tcx > ,
210
229
error_region : Option < ty:: Region < ' tcx > > ,
211
230
) -> Option < DiagnosticBuilder < ' tcx > > {
212
- tcx. infer_ctxt ( ) . enter_with_canonical (
231
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
213
232
cause. span ,
214
233
& self . canonical_query ,
215
234
|ref infcx, key, _| {
216
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
235
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
217
236
type_op_prove_predicate_with_cause ( infcx, & mut * fulfill_cx, key, cause) ;
218
237
try_extract_error_from_fulfill_cx (
219
238
fulfill_cx,
@@ -247,16 +266,16 @@ where
247
266
248
267
fn nice_error (
249
268
& self ,
250
- tcx : TyCtxt < ' tcx > ,
269
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
251
270
cause : ObligationCause < ' tcx > ,
252
271
placeholder_region : ty:: Region < ' tcx > ,
253
272
error_region : Option < ty:: Region < ' tcx > > ,
254
273
) -> Option < DiagnosticBuilder < ' tcx > > {
255
- tcx. infer_ctxt ( ) . enter_with_canonical (
274
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
256
275
cause. span ,
257
276
& self . canonical_query ,
258
277
|ref infcx, key, _| {
259
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
278
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
260
279
261
280
let mut selcx = SelectionContext :: new ( infcx) ;
262
281
@@ -304,16 +323,16 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
304
323
305
324
fn nice_error (
306
325
& self ,
307
- tcx : TyCtxt < ' tcx > ,
326
+ mbcx : & mut MirBorrowckCtxt < ' _ , ' tcx > ,
308
327
cause : ObligationCause < ' tcx > ,
309
328
placeholder_region : ty:: Region < ' tcx > ,
310
329
error_region : Option < ty:: Region < ' tcx > > ,
311
330
) -> Option < DiagnosticBuilder < ' tcx > > {
312
- tcx. infer_ctxt ( ) . enter_with_canonical (
331
+ mbcx . infcx . tcx . infer_ctxt ( ) . enter_with_canonical (
313
332
cause. span ,
314
333
& self . canonical_query ,
315
334
|ref infcx, key, _| {
316
- let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
335
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx . tcx ) ;
317
336
type_op_ascribe_user_type_with_span ( infcx, & mut * fulfill_cx, key, Some ( cause. span ) )
318
337
. ok ( ) ?;
319
338
try_extract_error_from_fulfill_cx (
@@ -327,43 +346,90 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
327
346
}
328
347
}
329
348
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
+
330
382
#[ instrument( skip( fulfill_cx, infcx) , level = "debug" ) ]
331
383
fn try_extract_error_from_fulfill_cx < ' tcx > (
332
384
mut fulfill_cx : Box < dyn TraitEngine < ' tcx > + ' tcx > ,
333
385
infcx : & InferCtxt < ' _ , ' tcx > ,
334
386
placeholder_region : ty:: Region < ' tcx > ,
335
387
error_region : Option < ty:: Region < ' tcx > > ,
336
388
) -> Option < DiagnosticBuilder < ' tcx > > {
337
- let tcx = infcx. tcx ;
338
-
339
389
// We generally shouldn't have errors here because the query was
340
390
// already run, but there's no point using `delay_span_bug`
341
391
// when we're going to emit an error here anyway.
342
392
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
+ }
343
403
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) =
346
413
region_constraints. constraints . iter ( ) . find_map ( |( constraint, cause) | {
347
414
match * constraint {
348
415
Constraint :: RegSubReg ( sub, sup) if sup == placeholder_region && sup != sub => {
349
416
Some ( ( sub, cause. clone ( ) ) )
350
417
}
351
418
// FIXME: Should this check the universe of the var?
352
419
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 ( ) ) )
354
421
}
355
422
_ => None ,
356
423
}
357
- } )
358
- } ) ?;
424
+ } ) ?;
359
425
360
426
debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
361
427
let nice_error = match ( error_region, sub_region) {
362
428
( Some ( error_region) , & ty:: ReVar ( vid) ) => NiceRegionError :: new (
363
429
infcx,
364
430
RegionResolutionError :: SubSupConflict (
365
431
vid,
366
- infcx . region_var_origin ( vid) ,
432
+ region_var_origin ( vid) ,
367
433
cause. clone ( ) ,
368
434
error_region,
369
435
cause. clone ( ) ,
@@ -380,8 +446,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
380
446
infcx,
381
447
RegionResolutionError :: UpperBoundUniverseConflict (
382
448
vid,
383
- infcx . region_var_origin ( vid) ,
384
- infcx . universe_of_region ( sub_region ) ,
449
+ region_var_origin ( vid) ,
450
+ universe_of_region ( vid ) ,
385
451
cause. clone ( ) ,
386
452
placeholder_region,
387
453
) ,
0 commit comments