@@ -2062,7 +2062,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2062
2062
// most likely to be the point where the value escapes -- but
2063
2063
// we still want to screen for an "interesting" point to
2064
2064
// highlight (e.g., a call site or something).
2065
- let target_scc = self . constraint_sccs . scc ( target_region) ;
2065
+ // As a special case, if the target region is 'static, it will always outlive the source,
2066
+ // so they'll be in the same SCC. To get better diagnostics, we pretend those `'static: R`
2067
+ // edges don't exist and use the resulting graph's SCCs.
2068
+ let target_is_static = target_region == self . universal_regions ( ) . fr_static ;
2069
+ let sccs_without_static = target_is_static
2070
+ . then ( || self . constraints . compute_sccs ( RegionVid :: MAX , & self . definitions ) ) ;
2071
+ let constraint_sccs = sccs_without_static. as_ref ( ) . unwrap_or ( & self . constraint_sccs ) ;
2072
+ let target_scc = constraint_sccs. scc ( target_region) ;
2066
2073
let mut range = 0 ..path. len ( ) ;
2067
2074
2068
2075
// As noted above, when reporting an error, there is typically a chain of constraints
@@ -2110,7 +2117,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2110
2117
let find_region = |i : & usize | {
2111
2118
let constraint = & path[ * i] ;
2112
2119
2113
- let constraint_sup_scc = self . constraint_sccs . scc ( constraint. sup ) ;
2120
+ let constraint_sup_scc = constraint_sccs. scc ( constraint. sup ) ;
2114
2121
2115
2122
if blame_source {
2116
2123
match categorized_path[ * i] . category {
@@ -2168,17 +2175,38 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2168
2175
}
2169
2176
}
2170
2177
2178
+ // If an "outlives 'static" constraint was from use as a const or static, blame that.
2179
+ if target_is_static
2180
+ && blame_source
2181
+ && let Some ( old_best) = categorized_path. iter ( ) . min_by_key ( |p| p. category )
2182
+ && matches ! (
2183
+ old_best. category,
2184
+ ConstraintCategory :: UseAsConst
2185
+ | ConstraintCategory :: UseAsStatic
2186
+ | ConstraintCategory :: Cast {
2187
+ is_implicit_coercion: true ,
2188
+ unsize_to: Some ( _)
2189
+ }
2190
+ )
2191
+ {
2192
+ // FIXME(dianne): `BorrowExplanation::add_object_lifetime_default_note` depends on a
2193
+ // coercion being blamed, so revert to the old blaming logic to prioritize that.
2194
+ // The note's logic should be reworked, though; it's flaky (#131008 doesn't have a
2195
+ // coercion, and even with this hack, one isn't always blamed when present).
2196
+ // Only checking for a coercion also makes the note appear where it shouldn't
2197
+ // shouldn't (e.g. `tests/ui/borrowck/two-phase-surprise-no-conflict.stderr`).
2198
+ return ( old_best. clone ( ) , extra_info) ;
2199
+ }
2200
+
2171
2201
return ( categorized_path[ i] . clone ( ) , extra_info) ;
2172
2202
}
2173
2203
2174
- // If that search fails, that is.. unusual. Maybe everything
2175
- // is in the same SCC or something. In that case, find what
2176
- // appears to be the most interesting point to report to the
2177
- // user via an even more ad-hoc guess.
2178
- categorized_path. sort_by_key ( |p| p. category ) ;
2179
- debug ! ( "sorted_path={:#?}" , categorized_path) ;
2204
+ // If that search fails, everything may be in the same SCC. In particular, this will be the
2205
+ // case when dealing with invariant lifetimes. Find what appears to be the most interesting
2206
+ // point to report to the user via an even more ad-hoc guess.
2207
+ let best_choice = categorized_path. into_iter ( ) . min_by_key ( |p| p. category ) . unwrap ( ) ;
2180
2208
2181
- ( categorized_path . remove ( 0 ) , extra_info)
2209
+ ( best_choice , extra_info)
2182
2210
}
2183
2211
2184
2212
pub ( crate ) fn universe_info ( & self , universe : ty:: UniverseIndex ) -> UniverseInfo < ' tcx > {
0 commit comments