@@ -10,6 +10,8 @@ use rustc_infer::infer::RegionVariableOrigin;
10
10
use rustc_infer:: infer:: { InferCtxt , RegionResolutionError , SubregionOrigin , TyCtxtInferExt as _} ;
11
11
use rustc_infer:: traits:: ObligationCause ;
12
12
use rustc_middle:: ty:: error:: TypeError ;
13
+ use rustc_middle:: ty:: RePlaceholder ;
14
+ use rustc_middle:: ty:: Region ;
13
15
use rustc_middle:: ty:: RegionVid ;
14
16
use rustc_middle:: ty:: UniverseIndex ;
15
17
use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
@@ -205,6 +207,8 @@ trait TypeOpInfo<'tcx> {
205
207
let span = cause. span ;
206
208
let nice_error = self . nice_error ( mbcx, cause, placeholder_region, error_region) ;
207
209
210
+ debug ! ( ?nice_error) ;
211
+
208
212
if let Some ( nice_error) = nice_error {
209
213
mbcx. buffer_error ( nice_error) ;
210
214
} else {
@@ -404,19 +408,41 @@ fn try_extract_error_from_region_constraints<'tcx>(
404
408
mut region_var_origin : impl FnMut ( RegionVid ) -> RegionVariableOrigin ,
405
409
mut universe_of_region : impl FnMut ( RegionVid ) -> UniverseIndex ,
406
410
) -> Option < DiagnosticBuilder < ' tcx , ErrorGuaranteed > > {
407
- let ( sub_region, cause) =
408
- region_constraints. constraints . iter ( ) . find_map ( |( constraint, cause) | {
409
- match * constraint {
410
- Constraint :: RegSubReg ( sub, sup) if sup == placeholder_region && sup != sub => {
411
- Some ( ( sub, cause. clone ( ) ) )
412
- }
413
- // FIXME: Should this check the universe of the var?
414
- Constraint :: VarSubReg ( vid, sup) if sup == placeholder_region => {
415
- Some ( ( ty:: Region :: new_var ( infcx. tcx , vid) , cause. clone ( ) ) )
416
- }
417
- _ => None ,
411
+ let matches =
412
+ |a_region : Region < ' tcx > , b_region : Region < ' tcx > | match ( a_region. kind ( ) , b_region. kind ( ) ) {
413
+ ( RePlaceholder ( a_p) , RePlaceholder ( b_p) ) => a_p. bound == b_p. bound ,
414
+ _ => a_region == b_region,
415
+ } ;
416
+ let check = |constraint : & Constraint < ' tcx > , cause : & SubregionOrigin < ' tcx > , exact| {
417
+ match * constraint {
418
+ Constraint :: RegSubReg ( sub, sup)
419
+ if ( ( exact && sup == placeholder_region)
420
+ || ( !exact && matches ( sup, placeholder_region) ) )
421
+ && sup != sub =>
422
+ {
423
+ Some ( ( sub, cause. clone ( ) ) )
424
+ }
425
+ // FIXME: Should this check the universe of the var?
426
+ Constraint :: VarSubReg ( vid, sup)
427
+ if ( ( exact && sup == placeholder_region)
428
+ || ( !exact && matches ( sup, placeholder_region) ) ) =>
429
+ {
430
+ Some ( ( ty:: Region :: new_var ( infcx. tcx , vid) , cause. clone ( ) ) )
418
431
}
419
- } ) ?;
432
+ _ => None ,
433
+ }
434
+ } ;
435
+ let mut info = region_constraints
436
+ . constraints
437
+ . iter ( )
438
+ . find_map ( |( constraint, cause) | check ( constraint, cause, true ) ) ;
439
+ if info. is_none ( ) {
440
+ info = region_constraints
441
+ . constraints
442
+ . iter ( )
443
+ . find_map ( |( constraint, cause) | check ( constraint, cause, false ) ) ;
444
+ }
445
+ let ( sub_region, cause) = info?;
420
446
421
447
debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
422
448
let error = match ( error_region, * sub_region) {
0 commit comments