@@ -55,7 +55,7 @@ use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
5555use rustc_span:: edition:: Edition ;
5656use rustc_span:: source_map:: Spanned ;
5757use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
58- use rustc_span:: { BytePos , InnerSpan , Span , SyntaxContext } ;
58+ use rustc_span:: { BytePos , InnerSpan , Span } ;
5959use rustc_target:: abi:: { Abi , VariantIdx } ;
6060use rustc_trait_selection:: infer:: { InferCtxtExt , TyCtxtInferExt } ;
6161use rustc_trait_selection:: traits:: { self , misc:: can_type_implement_copy, EvaluationResult } ;
@@ -2184,7 +2184,7 @@ impl ExplicitOutlivesRequirements {
21842184 tcx : TyCtxt < ' tcx > ,
21852185 bounds : & hir:: GenericBounds < ' _ > ,
21862186 inferred_outlives : & [ ty:: Region < ' tcx > ] ,
2187- span_cx : SyntaxContext ,
2187+ predicate_span : Span ,
21882188 ) -> Vec < ( usize , Span ) > {
21892189 use rustc_middle:: middle:: resolve_lifetime:: Region ;
21902190
@@ -2207,8 +2207,8 @@ impl ExplicitOutlivesRequirements {
22072207 return None ;
22082208 }
22092209
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) {
22122212 return None ;
22132213 }
22142214
@@ -2279,9 +2279,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
22792279 use rustc_middle:: middle:: resolve_lifetime:: Region ;
22802280
22812281 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
22852285 {
22862286 let inferred_outlives = cx. tcx . inferred_outlives_of ( def_id) ;
22872287 if inferred_outlives. is_empty ( ) {
@@ -2296,47 +2296,48 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
22962296 let mut dropped_predicate_count = 0 ;
22972297 let num_predicates = hir_generics. predicates . len ( ) ;
22982298 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+ {
23262305 (
2327- Self :: lifetimes_outliving_type ( inferred_outlives, index) ,
2306+ Self :: lifetimes_outliving_lifetime (
2307+ inferred_outlives,
2308+ region_def_id,
2309+ ) ,
23282310 & predicate. bounds ,
23292311 predicate. span ,
2330- predicate. origin == PredicateOrigin :: WhereClause ,
2312+ predicate. in_where_clause ,
23312313 )
2332- }
2333- _ => {
2314+ } else {
23342315 continue ;
23352316 }
23362317 }
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+ } ;
23402341 if relevant_lifetimes. is_empty ( ) {
23412342 continue ;
23422343 }
@@ -2345,7 +2346,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
23452346 cx. tcx ,
23462347 bounds,
23472348 & relevant_lifetimes,
2348- span . ctxt ( ) ,
2349+ predicate_span ,
23492350 ) ;
23502351 bound_count += bound_spans. len ( ) ;
23512352
@@ -2355,15 +2356,15 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
23552356 }
23562357
23572358 if drop_predicate && !in_where_clause {
2358- lint_spans. push ( span ) ;
2359+ lint_spans. push ( predicate_span ) ;
23592360 } else if drop_predicate && i + 1 < num_predicates {
23602361 // If all the bounds on a predicate were inferable and there are
23612362 // further predicates, we want to eat the trailing comma.
23622363 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 ( ) ) ) ;
23642365 } else {
23652366 where_lint_spans. extend ( self . consolidate_outlives_bound_spans (
2366- span . shrink_to_lo ( ) ,
2367+ predicate_span . shrink_to_lo ( ) ,
23672368 bounds,
23682369 bound_spans,
23692370 ) ) ;
@@ -2384,24 +2385,35 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
23842385 } else {
23852386 hir_generics. span . shrink_to_hi ( ) . to ( where_span)
23862387 } ;
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+ }
23882395 } else {
23892396 lint_spans. extend ( where_lint_spans) ;
23902397 }
23912398
23922399 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+
23932408 cx. struct_span_lint (
23942409 EXPLICIT_OUTLIVES_REQUIREMENTS ,
23952410 lint_spans. clone ( ) ,
23962411 fluent:: lint_builtin_explicit_outlives,
23972412 |lint| {
23982413 lint. set_arg ( "count" , bound_count) . multipart_suggestion (
23992414 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,
24052417 )
24062418 } ,
24072419 ) ;
0 commit comments