@@ -55,7 +55,7 @@ use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
55
55
use rustc_span:: edition:: Edition ;
56
56
use rustc_span:: source_map:: Spanned ;
57
57
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
58
- use rustc_span:: { BytePos , InnerSpan , Span , SyntaxContext } ;
58
+ use rustc_span:: { BytePos , InnerSpan , Span } ;
59
59
use rustc_target:: abi:: { Abi , VariantIdx } ;
60
60
use rustc_trait_selection:: infer:: { InferCtxtExt , TyCtxtInferExt } ;
61
61
use rustc_trait_selection:: traits:: { self , misc:: can_type_implement_copy, EvaluationResult } ;
@@ -2184,7 +2184,7 @@ impl ExplicitOutlivesRequirements {
2184
2184
tcx : TyCtxt < ' tcx > ,
2185
2185
bounds : & hir:: GenericBounds < ' _ > ,
2186
2186
inferred_outlives : & [ ty:: Region < ' tcx > ] ,
2187
- span_cx : SyntaxContext ,
2187
+ predicate_span : Span ,
2188
2188
) -> Vec < ( usize , Span ) > {
2189
2189
use rustc_middle:: middle:: resolve_lifetime:: Region ;
2190
2190
@@ -2207,8 +2207,8 @@ impl ExplicitOutlivesRequirements {
2207
2207
return None ;
2208
2208
}
2209
2209
2210
- let span = bound. span ( ) ;
2211
- if span . ctxt ( ) != span_cx || in_external_macro ( tcx. sess , span) {
2210
+ let span = bound. span ( ) . find_ancestor_inside ( predicate_span ) ? ;
2211
+ if in_external_macro ( tcx. sess , span) {
2212
2212
return None ;
2213
2213
}
2214
2214
@@ -2279,9 +2279,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
2279
2279
use rustc_middle:: middle:: resolve_lifetime:: Region ;
2280
2280
2281
2281
let def_id = item. owner_id . def_id ;
2282
- if let hir:: ItemKind :: Struct ( _, ref hir_generics)
2283
- | hir:: ItemKind :: Enum ( _, ref hir_generics)
2284
- | hir:: ItemKind :: Union ( _, ref hir_generics) = item. kind
2282
+ if let hir:: ItemKind :: Struct ( _, hir_generics)
2283
+ | hir:: ItemKind :: Enum ( _, hir_generics)
2284
+ | hir:: ItemKind :: Union ( _, hir_generics) = item. kind
2285
2285
{
2286
2286
let inferred_outlives = cx. tcx . inferred_outlives_of ( def_id) ;
2287
2287
if inferred_outlives. is_empty ( ) {
@@ -2296,47 +2296,48 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
2296
2296
let mut dropped_predicate_count = 0 ;
2297
2297
let num_predicates = hir_generics. predicates . len ( ) ;
2298
2298
for ( i, where_predicate) in hir_generics. predicates . iter ( ) . enumerate ( ) {
2299
- let ( relevant_lifetimes, bounds, span, in_where_clause) = match where_predicate {
2300
- hir:: WherePredicate :: RegionPredicate ( predicate) => {
2301
- if let Some ( Region :: EarlyBound ( region_def_id) ) =
2302
- cx. tcx . named_region ( predicate. lifetime . hir_id )
2303
- {
2304
- (
2305
- Self :: lifetimes_outliving_lifetime (
2306
- inferred_outlives,
2307
- region_def_id,
2308
- ) ,
2309
- & predicate. bounds ,
2310
- predicate. span ,
2311
- predicate. in_where_clause ,
2312
- )
2313
- } else {
2314
- continue ;
2315
- }
2316
- }
2317
- hir:: WherePredicate :: BoundPredicate ( predicate) => {
2318
- // FIXME we can also infer bounds on associated types,
2319
- // and should check for them here.
2320
- match predicate. bounded_ty . kind {
2321
- hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , path) ) => {
2322
- let Res :: Def ( DefKind :: TyParam , def_id) = path. res else {
2323
- continue ;
2324
- } ;
2325
- let index = ty_generics. param_def_id_to_index [ & def_id] ;
2299
+ let ( relevant_lifetimes, bounds, predicate_span, in_where_clause) =
2300
+ match where_predicate {
2301
+ hir:: WherePredicate :: RegionPredicate ( predicate) => {
2302
+ if let Some ( Region :: EarlyBound ( region_def_id) ) =
2303
+ cx. tcx . named_region ( predicate. lifetime . hir_id )
2304
+ {
2326
2305
(
2327
- Self :: lifetimes_outliving_type ( inferred_outlives, index) ,
2306
+ Self :: lifetimes_outliving_lifetime (
2307
+ inferred_outlives,
2308
+ region_def_id,
2309
+ ) ,
2328
2310
& predicate. bounds ,
2329
2311
predicate. span ,
2330
- predicate. origin == PredicateOrigin :: WhereClause ,
2312
+ predicate. in_where_clause ,
2331
2313
)
2332
- }
2333
- _ => {
2314
+ } else {
2334
2315
continue ;
2335
2316
}
2336
2317
}
2337
- }
2338
- _ => continue ,
2339
- } ;
2318
+ hir:: WherePredicate :: BoundPredicate ( predicate) => {
2319
+ // FIXME we can also infer bounds on associated types,
2320
+ // and should check for them here.
2321
+ match predicate. bounded_ty . kind {
2322
+ hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , path) ) => {
2323
+ let Res :: Def ( DefKind :: TyParam , def_id) = path. res else {
2324
+ continue ;
2325
+ } ;
2326
+ let index = ty_generics. param_def_id_to_index [ & def_id] ;
2327
+ (
2328
+ Self :: lifetimes_outliving_type ( inferred_outlives, index) ,
2329
+ & predicate. bounds ,
2330
+ predicate. span ,
2331
+ predicate. origin == PredicateOrigin :: WhereClause ,
2332
+ )
2333
+ }
2334
+ _ => {
2335
+ continue ;
2336
+ }
2337
+ }
2338
+ }
2339
+ _ => continue ,
2340
+ } ;
2340
2341
if relevant_lifetimes. is_empty ( ) {
2341
2342
continue ;
2342
2343
}
@@ -2345,7 +2346,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
2345
2346
cx. tcx ,
2346
2347
bounds,
2347
2348
& relevant_lifetimes,
2348
- span . ctxt ( ) ,
2349
+ predicate_span ,
2349
2350
) ;
2350
2351
bound_count += bound_spans. len ( ) ;
2351
2352
@@ -2355,15 +2356,15 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
2355
2356
}
2356
2357
2357
2358
if drop_predicate && !in_where_clause {
2358
- lint_spans. push ( span ) ;
2359
+ lint_spans. push ( predicate_span ) ;
2359
2360
} else if drop_predicate && i + 1 < num_predicates {
2360
2361
// If all the bounds on a predicate were inferable and there are
2361
2362
// further predicates, we want to eat the trailing comma.
2362
2363
let next_predicate_span = hir_generics. predicates [ i + 1 ] . span ( ) ;
2363
- where_lint_spans. push ( span . to ( next_predicate_span. shrink_to_lo ( ) ) ) ;
2364
+ where_lint_spans. push ( predicate_span . to ( next_predicate_span. shrink_to_lo ( ) ) ) ;
2364
2365
} else {
2365
2366
where_lint_spans. extend ( self . consolidate_outlives_bound_spans (
2366
- span . shrink_to_lo ( ) ,
2367
+ predicate_span . shrink_to_lo ( ) ,
2367
2368
bounds,
2368
2369
bound_spans,
2369
2370
) ) ;
@@ -2384,24 +2385,35 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
2384
2385
} else {
2385
2386
hir_generics. span . shrink_to_hi ( ) . to ( where_span)
2386
2387
} ;
2387
- lint_spans. push ( full_where_span) ;
2388
+
2389
+ // Due to macro expansions, the `full_where_span` might not actually contain all predicates.
2390
+ if where_lint_spans. iter ( ) . all ( |& sp| full_where_span. contains ( sp) ) {
2391
+ lint_spans. push ( full_where_span) ;
2392
+ } else {
2393
+ lint_spans. extend ( where_lint_spans) ;
2394
+ }
2388
2395
} else {
2389
2396
lint_spans. extend ( where_lint_spans) ;
2390
2397
}
2391
2398
2392
2399
if !lint_spans. is_empty ( ) {
2400
+ // Do not automatically delete outlives requirements from macros.
2401
+ let applicability = if lint_spans. iter ( ) . all ( |sp| sp. can_be_used_for_suggestions ( ) )
2402
+ {
2403
+ Applicability :: MachineApplicable
2404
+ } else {
2405
+ Applicability :: MaybeIncorrect
2406
+ } ;
2407
+
2393
2408
cx. struct_span_lint (
2394
2409
EXPLICIT_OUTLIVES_REQUIREMENTS ,
2395
2410
lint_spans. clone ( ) ,
2396
2411
fluent:: lint_builtin_explicit_outlives,
2397
2412
|lint| {
2398
2413
lint. set_arg ( "count" , bound_count) . multipart_suggestion (
2399
2414
fluent:: suggestion,
2400
- lint_spans
2401
- . into_iter ( )
2402
- . map ( |span| ( span, String :: new ( ) ) )
2403
- . collect :: < Vec < _ > > ( ) ,
2404
- Applicability :: MachineApplicable ,
2415
+ lint_spans. into_iter ( ) . map ( |span| ( span, String :: new ( ) ) ) . collect ( ) ,
2416
+ applicability,
2405
2417
)
2406
2418
} ,
2407
2419
) ;
0 commit comments