@@ -1557,14 +1557,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
15571557 if ident. name == kw:: StaticLifetime {
15581558 self . record_lifetime_res (
15591559 lifetime. id ,
1560- LifetimeRes :: Static ,
1560+ LifetimeRes :: Static { suppress_elision_warning : false } ,
15611561 LifetimeElisionCandidate :: Named ,
15621562 ) ;
15631563 return ;
15641564 }
15651565
15661566 if ident. name == kw:: UnderscoreLifetime {
1567- return self . resolve_anonymous_lifetime ( lifetime, false ) ;
1567+ return self . resolve_anonymous_lifetime ( lifetime, lifetime . id , false ) ;
15681568 }
15691569
15701570 let mut lifetime_rib_iter = self . lifetime_ribs . iter ( ) . rev ( ) ;
@@ -1667,13 +1667,23 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
16671667 }
16681668
16691669 #[ instrument( level = "debug" , skip( self ) ) ]
1670- fn resolve_anonymous_lifetime ( & mut self , lifetime : & Lifetime , elided : bool ) {
1670+ fn resolve_anonymous_lifetime (
1671+ & mut self ,
1672+ lifetime : & Lifetime ,
1673+ id_for_lint : NodeId ,
1674+ elided : bool ,
1675+ ) {
16711676 debug_assert_eq ! ( lifetime. ident. name, kw:: UnderscoreLifetime ) ;
16721677
16731678 let kind =
16741679 if elided { MissingLifetimeKind :: Ampersand } else { MissingLifetimeKind :: Underscore } ;
1675- let missing_lifetime =
1676- MissingLifetime { id : lifetime. id , span : lifetime. ident . span , kind, count : 1 } ;
1680+ let missing_lifetime = MissingLifetime {
1681+ id : lifetime. id ,
1682+ span : lifetime. ident . span ,
1683+ kind,
1684+ count : 1 ,
1685+ id_for_lint,
1686+ } ;
16771687 let elision_candidate = LifetimeElisionCandidate :: Missing ( missing_lifetime) ;
16781688 for ( i, rib) in self . lifetime_ribs . iter ( ) . enumerate ( ) . rev ( ) {
16791689 debug ! ( ?rib. kind) ;
@@ -1697,7 +1707,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
16971707 if lifetimes_in_scope. is_empty ( ) {
16981708 self . record_lifetime_res (
16991709 lifetime. id ,
1700- LifetimeRes :: Static ,
1710+ // We are inside a const item, so do not warn.
1711+ LifetimeRes :: Static { suppress_elision_warning : true } ,
17011712 elision_candidate,
17021713 ) ;
17031714 return ;
@@ -1800,7 +1811,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
18001811 LifetimeRes :: ElidedAnchor { start : id, end : NodeId :: from_u32 ( id. as_u32 ( ) + 1 ) } ,
18011812 LifetimeElisionCandidate :: Ignore ,
18021813 ) ;
1803- self . resolve_anonymous_lifetime ( & lt, true ) ;
1814+ self . resolve_anonymous_lifetime ( & lt, anchor_id , true ) ;
18041815 }
18051816
18061817 #[ instrument( level = "debug" , skip( self ) ) ]
@@ -1916,6 +1927,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
19161927 } ;
19171928 let missing_lifetime = MissingLifetime {
19181929 id : node_ids. start ,
1930+ id_for_lint : segment_id,
19191931 span : elided_lifetime_span,
19201932 kind,
19211933 count : expected_lifetimes,
@@ -2039,8 +2051,44 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
20392051 if let Some ( prev_res) = self . r . lifetimes_res_map . insert ( id, res) {
20402052 panic ! ( "lifetime {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)" )
20412053 }
2054+
2055+ match candidate {
2056+ LifetimeElisionCandidate :: Missing ( missing @ MissingLifetime { .. } ) => {
2057+ debug_assert_eq ! ( id, missing. id) ;
2058+ match res {
2059+ LifetimeRes :: Static { suppress_elision_warning } => {
2060+ if !suppress_elision_warning {
2061+ self . r . lint_buffer . buffer_lint (
2062+ lint:: builtin:: ELIDED_NAMED_LIFETIMES ,
2063+ missing. id_for_lint ,
2064+ missing. span ,
2065+ BuiltinLintDiag :: ElidedIsStatic { elided : missing. span } ,
2066+ ) ;
2067+ }
2068+ }
2069+ LifetimeRes :: Param { param, binder : _ } => {
2070+ let tcx = self . r . tcx ( ) ;
2071+ self . r . lint_buffer . buffer_lint (
2072+ lint:: builtin:: ELIDED_NAMED_LIFETIMES ,
2073+ missing. id_for_lint ,
2074+ missing. span ,
2075+ BuiltinLintDiag :: ElidedIsParam {
2076+ elided : missing. span ,
2077+ param : ( tcx. item_name ( param. into ( ) ) , tcx. source_span ( param) ) ,
2078+ } ,
2079+ ) ;
2080+ }
2081+ LifetimeRes :: Fresh { .. }
2082+ | LifetimeRes :: Infer
2083+ | LifetimeRes :: Error
2084+ | LifetimeRes :: ElidedAnchor { .. } => { }
2085+ }
2086+ }
2087+ LifetimeElisionCandidate :: Ignore | LifetimeElisionCandidate :: Named => { }
2088+ }
2089+
20422090 match res {
2043- LifetimeRes :: Param { .. } | LifetimeRes :: Fresh { .. } | LifetimeRes :: Static => {
2091+ LifetimeRes :: Param { .. } | LifetimeRes :: Fresh { .. } | LifetimeRes :: Static { .. } => {
20442092 if let Some ( ref mut candidates) = self . lifetime_elision_candidates {
20452093 candidates. push ( ( res, candidate) ) ;
20462094 }
@@ -2558,9 +2606,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25582606
25592607 ItemKind :: Static ( box ast:: StaticItem { ref ty, ref expr, .. } ) => {
25602608 self . with_static_rib ( def_kind, |this| {
2561- this. with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Static ) , |this| {
2562- this. visit_ty ( ty) ;
2563- } ) ;
2609+ this. with_lifetime_rib (
2610+ LifetimeRibKind :: Elided ( LifetimeRes :: Static {
2611+ suppress_elision_warning : true ,
2612+ } ) ,
2613+ |this| {
2614+ this. visit_ty ( ty) ;
2615+ } ,
2616+ ) ;
25642617 if let Some ( expr) = expr {
25652618 // We already forbid generic params because of the above item rib,
25662619 // so it doesn't matter whether this is a trivial constant.
@@ -2589,7 +2642,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
25892642 this. visit_generics ( generics) ;
25902643
25912644 this. with_lifetime_rib (
2592- LifetimeRibKind :: Elided ( LifetimeRes :: Static ) ,
2645+ LifetimeRibKind :: Elided ( LifetimeRes :: Static {
2646+ suppress_elision_warning : true ,
2647+ } ) ,
25932648 |this| this. visit_ty ( ty) ,
25942649 ) ;
25952650
0 commit comments