Omit proc macros from must_use_candidate

This commit is contained in:
Andre Bogus 2019-10-18 15:54:25 +02:00
parent c0b2411f06
commit d723b35aee
4 changed files with 38 additions and 7 deletions

View file

@ -1,6 +1,6 @@
use crate::utils::{ use crate::utils::{
iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt, span_help_and_lint, span_lint, attrs::is_proc_macro, iter_input_pats, match_def_path, qpath_res, return_ty, snippet, snippet_opt,
span_lint_and_then, type_is_unsafe_function, span_help_and_lint, span_lint, span_lint_and_then, type_is_unsafe_function,
}; };
use matches::matches; use matches::matches;
use rustc::hir::{self, def::Res, def_id::DefId, intravisit}; 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); check_needless_must_use(cx, decl, item.hir_id, item.span, fn_header_span, attr);
return; 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( check_must_use_candidate(
cx, cx,
decl, decl,
@ -254,7 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
if let Some(attr) = attr { if let Some(attr) = attr {
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); 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); 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( check_must_use_candidate(
cx, cx,
&sig.decl, &sig.decl,
@ -284,7 +284,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
let body = cx.tcx.hir().body(eid); let body = cx.tcx.hir().body(eid);
Self::check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.hir_id); 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( check_must_use_candidate(
cx, cx,
&sig.decl, &sig.decl,

View file

@ -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)))
}

View file

@ -1,8 +1,26 @@
//! Check that we correctly lint procedural macros. //! Check that we correctly lint procedural macros.
#![crate_type = "proc-macro"] #![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::TokenStream;
#[allow(dead_code)] #[allow(dead_code)]
fn f() { fn f() {
let _x = 3.14; 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
}

View file

@ -1,5 +1,5 @@
error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly 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; LL | let _x = 3.14;
| ^^^^ | ^^^^