@@ -10,6 +10,8 @@ use rustc_infer::infer::RegionVariableOrigin;
1010use rustc_infer:: infer:: { InferCtxt , RegionResolutionError , SubregionOrigin , TyCtxtInferExt as _} ;
1111use rustc_infer:: traits:: ObligationCause ;
1212use rustc_middle:: ty:: error:: TypeError ;
13+ use rustc_middle:: ty:: RePlaceholder ;
14+ use rustc_middle:: ty:: Region ;
1315use rustc_middle:: ty:: RegionVid ;
1416use rustc_middle:: ty:: UniverseIndex ;
1517use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
@@ -205,6 +207,8 @@ trait TypeOpInfo<'tcx> {
205207 let span = cause. span ;
206208 let nice_error = self . nice_error ( mbcx, cause, placeholder_region, error_region) ;
207209
210+ debug ! ( ?nice_error) ;
211+
208212 if let Some ( nice_error) = nice_error {
209213 mbcx. buffer_error ( nice_error) ;
210214 } else {
@@ -404,19 +408,41 @@ fn try_extract_error_from_region_constraints<'tcx>(
404408 mut region_var_origin : impl FnMut ( RegionVid ) -> RegionVariableOrigin ,
405409 mut universe_of_region : impl FnMut ( RegionVid ) -> UniverseIndex ,
406410) -> 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 ( ) ) )
418431 }
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?;
420446
421447 debug ! ( ?sub_region, "cause = {:#?}" , cause) ;
422448 let error = match ( error_region, * sub_region) {
0 commit comments