about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndre Bogus <bogusandre@gmail.com>2019-10-18 15:54:25 +0200
committerAndre Bogus <bogusandre@gmail.com>2019-10-18 15:54:25 +0200
commitd723b35aee3b0854f87efb00eb18c6cf3a065004 (patch)
tree29a2e9bfcd11e8fbdc4c67fb528a3fef7e6522ce
parentc0b2411f06a417266baaac2f0ea431138da33bf3 (diff)
downloadrust-d723b35aee3b0854f87efb00eb18c6cf3a065004.tar.gz
rust-d723b35aee3b0854f87efb00eb18c6cf3a065004.zip
Omit proc macros from `must_use_candidate`
-rw-r--r--clippy_lints/src/functions.rs10
-rw-r--r--clippy_lints/src/utils/attrs.rs13
-rw-r--r--tests/ui/proc_macro.rs20
-rw-r--r--tests/ui/proc_macro.stderr2
4 files changed, 38 insertions, 7 deletions
diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs
index 9844df3c650..8e295af234c 100644
--- a/clippy_lints/src/functions.rs
+++ b/clippy_lints/src/functions.rs
@@ -1,6 +1,6 @@
 use crate::utils::{
-    iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt, span_help_and_lint, span_lint,
-    span_lint_and_then, type_is_unsafe_function,
+    attrs::is_proc_macro, iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt,
+    span_help_and_lint, span_lint, span_lint_and_then, type_is_unsafe_function,
 };
 use matches::matches;
 use rustc::hir::{self, def::Res, def_id::DefId, intravisit};
@@ -234,7 +234,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
                 check_needless_must_use(cx, decl, item.hir_id, item.span, fn_header_span, attr);
                 return;
             }
-            if cx.access_levels.is_exported(item.hir_id) {
+            if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
                 check_must_use_candidate(
                     cx,
                     decl,
@@ -254,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
             if let Some(attr) = attr {
                 let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
                 check_needless_must_use(cx, &sig.decl, item.hir_id, item.span, fn_header_span, attr);
-            } else if cx.access_levels.is_exported(item.hir_id) {
+            } else if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
                 check_must_use_candidate(
                     cx,
                     &sig.decl,
@@ -284,7 +284,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
                 let body = cx.tcx.hir().body(eid);
                 Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id);
 
-                if attr.is_none() && cx.access_levels.is_exported(item.hir_id) {
+                if attr.is_none() && cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
                     check_must_use_candidate(
                         cx,
                         &sig.decl,
diff --git a/clippy_lints/src/utils/attrs.rs b/clippy_lints/src/utils/attrs.rs
index eaad932cb67..2520f366b32 100644
--- a/clippy_lints/src/utils/attrs.rs
+++ b/clippy_lints/src/utils/attrs.rs
@@ -114,3 +114,16 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
         }
     }
 }
+
+/// Return true if the attributes contain any of `proc_macro`,
+/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
+pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
+    use syntax_pos::Symbol;
+
+    let syms = [
+        Symbol::intern("proc_macro"),
+        Symbol::intern("proc_macro_derive"),
+        Symbol::intern("proc_macro_attribute"),
+    ];
+    attrs.iter().any(|attr| syms.iter().any(move |&s| attr.check_name(s)))
+}
diff --git a/tests/ui/proc_macro.rs b/tests/ui/proc_macro.rs
index dd8bd58c015..59914b8b8f6 100644
--- a/tests/ui/proc_macro.rs
+++ b/tests/ui/proc_macro.rs
@@ -1,8 +1,26 @@
 //! Check that we correctly lint procedural macros.
-
 #![crate_type = "proc-macro"]
 
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
 #[allow(dead_code)]
 fn f() {
     let _x = 3.14;
 }
+
+#[proc_macro]
+pub fn mybangmacro(t: TokenStream) -> TokenStream {
+    t
+}
+
+#[proc_macro_derive(MyDerivedTrait)]
+pub fn myderive(t: TokenStream) -> TokenStream {
+    t
+}
+
+#[proc_macro_attribute]
+pub fn myattribute(t: TokenStream, a: TokenStream) -> TokenStream {
+    t
+}
diff --git a/tests/ui/proc_macro.stderr b/tests/ui/proc_macro.stderr
index 78c3880db49..872cbc66af6 100644
--- a/tests/ui/proc_macro.stderr
+++ b/tests/ui/proc_macro.stderr
@@ -1,5 +1,5 @@
 error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly
-  --> $DIR/proc_macro.rs:7:14
+  --> $DIR/proc_macro.rs:10:14
    |
 LL |     let _x = 3.14;
    |              ^^^^