@@ -1983,18 +1983,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19831983 } )
19841984 . unwrap_or_else ( || ObligationCauseCode :: Misc ) ;
19851985
1986- // Classify each of the constraints along the path.
1987- let mut categorized_path: Vec < BlameConstraint < ' tcx > > = path
1988- . iter ( )
1989- . map ( |constraint| BlameConstraint {
1990- category : constraint. category ,
1991- from_closure : constraint. from_closure ,
1992- cause : ObligationCause :: new ( constraint. span , CRATE_DEF_ID , cause_code. clone ( ) ) ,
1993- variance_info : constraint. variance_info ,
1994- } )
1995- . collect ( ) ;
1996- debug ! ( "categorized_path={:#?}" , categorized_path) ;
1997-
19981986 // To find the best span to cite, we first try to look for the
19991987 // final constraint that is interesting and where the `sup` is
20001988 // not unified with the ultimate target region. The reason
@@ -2015,7 +2003,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20152003 // we still want to screen for an "interesting" point to
20162004 // highlight (e.g., a call site or something).
20172005 let target_scc = self . constraint_sccs . scc ( target_region) ;
2018- let mut range = 0 ..path. len ( ) ;
20192006
20202007 // As noted above, when reporting an error, there is typically a chain of constraints
20212008 // leading from some "source" region which must outlive some "target" region.
@@ -2059,13 +2046,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20592046 | NllRegionVariableOrigin :: Existential { from_forall : true } => false ,
20602047 } ;
20612048
2062- let find_region = |i : & usize | {
2063- let constraint = & path[ * i] ;
2064-
2049+ let interesting_to_blame = |constraint : & OutlivesConstraint < ' tcx > | {
20652050 let constraint_sup_scc = self . constraint_sccs . scc ( constraint. sup ) ;
20662051
20672052 if blame_source {
2068- match categorized_path [ * i ] . category {
2053+ match constraint . category {
20692054 ConstraintCategory :: OpaqueType
20702055 | ConstraintCategory :: Boring
20712056 | ConstraintCategory :: BoringNoLocation
@@ -2078,7 +2063,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20782063 }
20792064 } else {
20802065 !matches ! (
2081- categorized_path [ * i ] . category,
2066+ constraint . category,
20822067 ConstraintCategory :: OpaqueType
20832068 | ConstraintCategory :: Boring
20842069 | ConstraintCategory :: BoringNoLocation
@@ -2088,49 +2073,59 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20882073 }
20892074 } ;
20902075
2091- let best_choice =
2092- if blame_source { range. rev ( ) . find ( find_region) } else { range. find ( find_region) } ;
2076+ let best_choice = if blame_source {
2077+ path. iter ( ) . rposition ( interesting_to_blame)
2078+ } else {
2079+ path. iter ( ) . position ( interesting_to_blame)
2080+ } ;
20932081
20942082 debug ! ( ?best_choice, ?blame_source) ;
20952083
2096- if let Some ( i ) = best_choice {
2097- if let Some ( next ) = categorized_path . get ( i + 1 ) {
2098- if matches ! ( categorized_path [ i ] . category , ConstraintCategory :: Return ( _ ) )
2099- && next . category == ConstraintCategory :: OpaqueType
2100- {
2101- // The return expression is being influenced by the return type being
2102- // impl Trait, point at the return type and not the return expr.
2103- return ( next . clone ( ) , path ) ;
2104- }
2084+ let best_constraint = match best_choice {
2085+ Some ( i )
2086+ if let Some ( next ) = path . get ( i + 1 )
2087+ && matches ! ( path [ i ] . category, ConstraintCategory :: Return ( _ ) )
2088+ && next . category == ConstraintCategory :: OpaqueType =>
2089+ {
2090+ // The return expression is being influenced by the return type being
2091+ // impl Trait, point at the return type and not the return expr.
2092+ * next
21052093 }
21062094
2107- if categorized_path[ i] . category == ConstraintCategory :: Return ( ReturnConstraint :: Normal )
2095+ Some ( i)
2096+ if path[ i] . category == ConstraintCategory :: Return ( ReturnConstraint :: Normal )
2097+ && let Some ( field) = path. iter ( ) . find_map ( |p| {
2098+ if let ConstraintCategory :: ClosureUpvar ( f) = p. category {
2099+ Some ( f)
2100+ } else {
2101+ None
2102+ }
2103+ } ) =>
21082104 {
2109- let field = categorized_path. iter ( ) . find_map ( |p| {
2110- if let ConstraintCategory :: ClosureUpvar ( f) = p. category {
2111- Some ( f)
2112- } else {
2113- None
2114- }
2115- } ) ;
2116-
2117- if let Some ( field) = field {
2118- categorized_path[ i] . category =
2119- ConstraintCategory :: Return ( ReturnConstraint :: ClosureUpvar ( field) ) ;
2105+ OutlivesConstraint {
2106+ category : ConstraintCategory :: Return ( ReturnConstraint :: ClosureUpvar ( field) ) ,
2107+ ..path[ i]
21202108 }
21212109 }
21222110
2123- return ( categorized_path[ i] . clone ( ) , path) ;
2124- }
2111+ Some ( i) => path[ i] ,
21252112
2126- // If that search fails, that is.. unusual. Maybe everything
2127- // is in the same SCC or something. In that case, find what
2128- // appears to be the most interesting point to report to the
2129- // user via an even more ad-hoc guess.
2130- categorized_path. sort_by_key ( |p| p. category ) ;
2131- debug ! ( "sorted_path={:#?}" , categorized_path) ;
2113+ None => {
2114+ // If that search fails, that is.. unusual. Maybe everything
2115+ // is in the same SCC or something. In that case, find what
2116+ // appears to be the most interesting point to report to the
2117+ // user via an even more ad-hoc guess.
2118+ * path. iter ( ) . min_by_key ( |p| p. category ) . unwrap ( )
2119+ }
2120+ } ;
21322121
2133- ( categorized_path. remove ( 0 ) , path)
2122+ let blame_constraint = BlameConstraint {
2123+ category : best_constraint. category ,
2124+ from_closure : best_constraint. from_closure ,
2125+ cause : ObligationCause :: new ( best_constraint. span , CRATE_DEF_ID , cause_code. clone ( ) ) ,
2126+ variance_info : best_constraint. variance_info ,
2127+ } ;
2128+ ( blame_constraint, path)
21342129 }
21352130
21362131 pub ( crate ) fn universe_info ( & self , universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
0 commit comments