@@ -15,14 +15,17 @@ use clippy_utils::ty::is_must_use_ty;
1515use  clippy_utils:: visitors:: for_each_expr_without_closures; 
1616use  clippy_utils:: { return_ty,  trait_ref_of_method} ; 
1717use  rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ; 
18+ use  rustc_attr_data_structures:: AttributeKind ; 
19+ use  rustc_span:: Symbol ; 
20+ use  rustc_attr_data_structures:: find_attr; 
1821
1922use  core:: ops:: ControlFlow ; 
2023
2124use  super :: { DOUBLE_MUST_USE ,  MUST_USE_CANDIDATE ,  MUST_USE_UNIT } ; 
2225
2326pub ( super )  fn  check_item < ' tcx > ( cx :  & LateContext < ' tcx > ,  item :  & ' tcx  hir:: Item < ' _ > )  { 
2427    let  attrs = cx. tcx . hir_attrs ( item. hir_id ( ) ) ; 
25-     let  attr = cx. tcx . get_attr ( item. owner_id ,  sym :: must_use ) ; 
28+     let  attr = find_attr ! ( cx. tcx. hir_attrs ( item. hir_id ( ) ) ,   AttributeKind :: MustUse   {  span ,  reason  }  =>  ( span ,  reason ) ) ; 
2629    if  let  hir:: ItemKind :: Fn  { 
2730        ref  sig, 
2831        body :  ref  body_id, 
@@ -31,8 +34,8 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
3134    { 
3235        let  is_public = cx. effective_visibilities . is_exported ( item. owner_id . def_id ) ; 
3336        let  fn_header_span = item. span . with_hi ( sig. decl . output . span ( ) . hi ( ) ) ; 
34-         if  let  Some ( attr )  = attr { 
35-             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  attr ,  attrs,  sig) ; 
37+         if  let  Some ( ( attr_span ,  reason ) )  = attr { 
38+             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  * attr_span ,   * reason ,  attrs,  sig) ; 
3639        }  else  if  is_public && !is_proc_macro ( attrs)  && !attrs. iter ( ) . any ( |a| a. has_name ( sym:: no_mangle) )  { 
3740            check_must_use_candidate ( 
3841                cx, 
@@ -52,9 +55,9 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
5255        let  is_public = cx. effective_visibilities . is_exported ( item. owner_id . def_id ) ; 
5356        let  fn_header_span = item. span . with_hi ( sig. decl . output . span ( ) . hi ( ) ) ; 
5457        let  attrs = cx. tcx . hir_attrs ( item. hir_id ( ) ) ; 
55-         let  attr = cx. tcx . get_attr ( item. owner_id ,  sym :: must_use ) ; 
56-         if  let  Some ( attr )  = attr { 
57-             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  attr ,  attrs,  sig) ; 
58+         let  attr = find_attr ! ( cx. tcx. hir_attrs ( item. hir_id ( ) ) ,   AttributeKind :: MustUse   {  span ,  reason  }  =>  ( span ,  reason ) ) ; 
59+         if  let  Some ( ( attr_span ,  reason ) )  = attr { 
60+             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  * attr_span ,   * reason ,  attrs,  sig) ; 
5861        }  else  if  is_public && !is_proc_macro ( attrs)  && trait_ref_of_method ( cx,  item. owner_id ) . is_none ( )  { 
5962            check_must_use_candidate ( 
6063                cx, 
@@ -75,9 +78,9 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
7578        let  fn_header_span = item. span . with_hi ( sig. decl . output . span ( ) . hi ( ) ) ; 
7679
7780        let  attrs = cx. tcx . hir_attrs ( item. hir_id ( ) ) ; 
78-         let  attr = cx. tcx . get_attr ( item. owner_id ,  sym :: must_use ) ; 
79-         if  let  Some ( attr )  = attr { 
80-             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  attr ,  attrs,  sig) ; 
81+         let  attr = find_attr ! ( cx. tcx. hir_attrs ( item. hir_id ( ) ) ,   AttributeKind :: MustUse   {  span ,  reason  }  =>  ( span ,  reason ) ) ; 
82+         if  let  Some ( ( attr_span ,  reason ) )  = attr { 
83+             check_needless_must_use ( cx,  sig. decl ,  item. owner_id ,  item. span ,  fn_header_span,  * attr_span ,   * reason ,  attrs,  sig) ; 
8184        }  else  if  let  hir:: TraitFn :: Provided ( eid)  = * eid { 
8285            let  body = cx. tcx . hir_body ( eid) ; 
8386            if  attr. is_none ( )  && is_public && !is_proc_macro ( attrs)  { 
@@ -103,7 +106,8 @@ fn check_needless_must_use(
103106    item_id :  hir:: OwnerId , 
104107    item_span :  Span , 
105108    fn_header_span :  Span , 
106-     attr :  & Attribute , 
109+     attr_span :  Span , 
110+     reason :  Option < Symbol > , 
107111    attrs :  & [ Attribute ] , 
108112    sig :  & FnSig < ' _ > , 
109113)  { 
@@ -119,7 +123,7 @@ fn check_needless_must_use(
119123                "this unit-returning function has a `#[must_use]` attribute" , 
120124                |diag| { 
121125                    diag. span_suggestion ( 
122-                         attr . span ( ) , 
126+                         attr_span , 
123127                        "remove the attribute" , 
124128                        "" , 
125129                        Applicability :: MachineApplicable , 
@@ -137,11 +141,11 @@ fn check_needless_must_use(
137141                MUST_USE_UNIT , 
138142                fn_header_span, 
139143                "this unit-returning function has a `#[must_use]` attribute" , 
140-                 Some ( attr . span ( ) ) , 
144+                 Some ( attr_span ) , 
141145                "remove `must_use`" , 
142146            ) ; 
143147        } 
144-     }  else  if  attr . value_str ( ) . is_none ( )  && is_must_use_ty ( cx,  return_ty ( cx,  item_id) )  { 
148+     }  else  if  reason . is_none ( )  && is_must_use_ty ( cx,  return_ty ( cx,  item_id) )  { 
145149        // Ignore async functions unless Future::Output type is a must_use type 
146150        if  sig. header . is_async ( )  { 
147151            let  infcx = cx. tcx . infer_ctxt ( ) . build ( cx. typing_mode ( ) ) ; 
0 commit comments