@@ -1972,18 +1972,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19721972 } )
19731973 . unwrap_or_else ( || ObligationCauseCode :: Misc ) ;
19741974
1975- // Classify each of the constraints along the path.
1976- let mut categorized_path: Vec < BlameConstraint < ' tcx > > = path
1977- . iter ( )
1978- . map ( |constraint| BlameConstraint {
1979- category : constraint. category ,
1980- from_closure : constraint. from_closure ,
1981- cause : ObligationCause :: new ( constraint. span , CRATE_DEF_ID , cause_code. clone ( ) ) ,
1982- variance_info : constraint. variance_info ,
1983- } )
1984- . collect ( ) ;
1985- debug ! ( "categorized_path={:#?}" , categorized_path) ;
1986-
19871975 // To find the best span to cite, we first try to look for the
19881976 // final constraint that is interesting and where the `sup` is
19891977 // not unified with the ultimate target region. The reason
@@ -2004,7 +1992,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20041992 // we still want to screen for an "interesting" point to
20051993 // highlight (e.g., a call site or something).
20061994 let target_scc = self . constraint_sccs . scc ( target_region) ;
2007- let mut range = 0 ..path. len ( ) ;
20081995
20091996 // As noted above, when reporting an error, there is typically a chain of constraints
20101997 // leading from some "source" region which must outlive some "target" region.
@@ -2048,13 +2035,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20482035 | NllRegionVariableOrigin :: Existential { from_forall : true } => false ,
20492036 } ;
20502037
2051- let find_region = |i : & usize | {
2052- let constraint = & path[ * i] ;
2053-
2038+ let interesting_to_blame = |constraint : & OutlivesConstraint < ' tcx > | {
20542039 let constraint_sup_scc = self . constraint_sccs . scc ( constraint. sup ) ;
20552040
20562041 if blame_source {
2057- match categorized_path [ * i ] . category {
2042+ match constraint . category {
20582043 ConstraintCategory :: OpaqueType
20592044 | ConstraintCategory :: Boring
20602045 | ConstraintCategory :: BoringNoLocation
@@ -2067,7 +2052,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20672052 }
20682053 } else {
20692054 !matches ! (
2070- categorized_path [ * i ] . category,
2055+ constraint . category,
20712056 ConstraintCategory :: OpaqueType
20722057 | ConstraintCategory :: Boring
20732058 | ConstraintCategory :: BoringNoLocation
@@ -2077,49 +2062,59 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20772062 }
20782063 } ;
20792064
2080- let best_choice =
2081- if blame_source { range. rev ( ) . find ( find_region) } else { range. find ( find_region) } ;
2065+ let best_choice = if blame_source {
2066+ path. iter ( ) . rposition ( interesting_to_blame)
2067+ } else {
2068+ path. iter ( ) . position ( interesting_to_blame)
2069+ } ;
20822070
20832071 debug ! ( ?best_choice, ?blame_source) ;
20842072
2085- if let Some ( i ) = best_choice {
2086- if let Some ( next ) = categorized_path . get ( i + 1 ) {
2087- if matches ! ( categorized_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- return ( next . clone ( ) , path ) ;
2093- }
2073+ let best_constraint = match best_choice {
2074+ Some ( i )
2075+ if let Some ( next ) = path . get ( i + 1 )
2076+ && matches ! ( path [ i ] . category, ConstraintCategory :: Return ( _ ) )
2077+ && next . category == ConstraintCategory :: OpaqueType =>
2078+ {
2079+ // The return expression is being influenced by the return type being
2080+ // impl Trait, point at the return type and not the return expr.
2081+ * next
20942082 }
20952083
2096- if categorized_path[ i] . category == ConstraintCategory :: Return ( ReturnConstraint :: Normal )
2084+ Some ( i)
2085+ if path[ i] . category == ConstraintCategory :: Return ( ReturnConstraint :: Normal )
2086+ && let Some ( field) = path. iter ( ) . find_map ( |p| {
2087+ if let ConstraintCategory :: ClosureUpvar ( f) = p. category {
2088+ Some ( f)
2089+ } else {
2090+ None
2091+ }
2092+ } ) =>
20972093 {
2098- let field = categorized_path. iter ( ) . find_map ( |p| {
2099- if let ConstraintCategory :: ClosureUpvar ( f) = p. category {
2100- Some ( f)
2101- } else {
2102- None
2103- }
2104- } ) ;
2105-
2106- if let Some ( field) = field {
2107- categorized_path[ i] . category =
2108- ConstraintCategory :: Return ( ReturnConstraint :: ClosureUpvar ( field) ) ;
2094+ OutlivesConstraint {
2095+ category : ConstraintCategory :: Return ( ReturnConstraint :: ClosureUpvar ( field) ) ,
2096+ ..path[ i]
21092097 }
21102098 }
21112099
2112- return ( categorized_path[ i] . clone ( ) , path) ;
2113- }
2100+ Some ( i) => path[ i] ,
21142101
2115- // If that search fails, that is.. unusual. Maybe everything
2116- // is in the same SCC or something. In that case, find what
2117- // appears to be the most interesting point to report to the
2118- // user via an even more ad-hoc guess.
2119- categorized_path. sort_by_key ( |p| p. category ) ;
2120- debug ! ( "sorted_path={:#?}" , categorized_path) ;
2102+ None => {
2103+ // If that search fails, that is.. unusual. Maybe everything
2104+ // is in the same SCC or something. In that case, find what
2105+ // appears to be the most interesting point to report to the
2106+ // user via an even more ad-hoc guess.
2107+ * path. iter ( ) . min_by_key ( |p| p. category ) . unwrap ( )
2108+ }
2109+ } ;
21212110
2122- ( categorized_path. remove ( 0 ) , path)
2111+ let blame_constraint = BlameConstraint {
2112+ category : best_constraint. category ,
2113+ from_closure : best_constraint. from_closure ,
2114+ cause : ObligationCause :: new ( best_constraint. span , CRATE_DEF_ID , cause_code. clone ( ) ) ,
2115+ variance_info : best_constraint. variance_info ,
2116+ } ;
2117+ ( blame_constraint, path)
21232118 }
21242119
21252120 pub ( crate ) fn universe_info ( & self , universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
0 commit comments