about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-03 17:04:52 +0000
committerbors <bors@rust-lang.org>2020-01-03 17:04:52 +0000
commitfddc9801dd3aceedef0bb5694a5f2a5a827efea8 (patch)
tree80e9716da192bc88bebe70f4f72ec53c9cf3bbb2
parent2e8c3c3e9eb81bc2be047b1d4b2f9f31b869b6f5 (diff)
parent47972cdf120f978aacefecc7bde2e68045f59af6 (diff)
downloadrust-fddc9801dd3aceedef0bb5694a5f2a5a827efea8.tar.gz
rust-fddc9801dd3aceedef0bb5694a5f2a5a827efea8.zip
Auto merge of #4989 - rust-lang:no-unmangled-must-use, r=flip1995
No #[no_mangle] must_use_candidate functions

This fixes #4984.

changelog: none
-rw-r--r--clippy_lints/src/functions.rs9
-rw-r--r--clippy_lints/src/utils/mod.rs15
-rw-r--r--tests/ui/must_use_candidates.fixed5
-rw-r--r--tests/ui/must_use_candidates.rs5
4 files changed, 25 insertions, 9 deletions
diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs
index 5b6d1d72fbe..81f199de5f9 100644
--- a/clippy_lints/src/functions.rs
+++ b/clippy_lints/src/functions.rs
@@ -1,6 +1,6 @@
 use crate::utils::{
-    attrs::is_proc_macro, is_must_use_ty, iter_input_pats, match_def_path, must_use_attr, qpath_res, return_ty,
-    snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then, trait_ref_of_method,
+    attr_by_name, attrs::is_proc_macro, is_must_use_ty, iter_input_pats, match_def_path, must_use_attr, qpath_res,
+    return_ty, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then, trait_ref_of_method,
     type_is_unsafe_function,
 };
 use matches::matches;
@@ -236,7 +236,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
                 check_needless_must_use(cx, &sig.decl, item.hir_id, item.span, fn_header_span, attr);
                 return;
             }
-            if cx.access_levels.is_exported(item.hir_id) && !is_proc_macro(&item.attrs) {
+            if cx.access_levels.is_exported(item.hir_id)
+                && !is_proc_macro(&item.attrs)
+                && attr_by_name(&item.attrs, "no_mangle").is_none()
+            {
                 check_must_use_candidate(
                     cx,
                     &sig.decl,
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 0680f627bbb..98ab844aeee 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -1253,13 +1253,16 @@ pub fn parent_node_is_if_expr<'a, 'b>(expr: &Expr<'_>, cx: &LateContext<'a, 'b>)
     }
 }
 
+// Finds the attribute with the given name, if any
+pub fn attr_by_name<'a>(attrs: &'a [Attribute], name: &'_ str) -> Option<&'a Attribute> {
+    attrs
+        .iter()
+        .find(|attr| attr.ident().map_or(false, |ident| ident.as_str() == name))
+}
+
+// Finds the `#[must_use]` attribute, if any
 pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> {
-    attrs.iter().find(|attr| {
-        attr.ident().map_or(false, |ident| {
-            let ident: &str = &ident.as_str();
-            "must_use" == ident
-        })
-    })
+    attr_by_name(attrs, "must_use")
 }
 
 // Returns whether the type has #[must_use] attribute
diff --git a/tests/ui/must_use_candidates.fixed b/tests/ui/must_use_candidates.fixed
index ff74857530f..e2ceb8baded 100644
--- a/tests/ui/must_use_candidates.fixed
+++ b/tests/ui/must_use_candidates.fixed
@@ -83,6 +83,11 @@ pub unsafe fn mutates_static() -> usize {
     COUNTER
 }
 
+#[no_mangle]
+pub fn unmangled(i: bool) -> bool {
+    !i
+}
+
 fn main() {
     assert_eq!(1, pure(1));
 }
diff --git a/tests/ui/must_use_candidates.rs b/tests/ui/must_use_candidates.rs
index 29c0752994a..29ef8d1ed9c 100644
--- a/tests/ui/must_use_candidates.rs
+++ b/tests/ui/must_use_candidates.rs
@@ -83,6 +83,11 @@ pub unsafe fn mutates_static() -> usize {
     COUNTER
 }
 
+#[no_mangle]
+pub fn unmangled(i: bool) -> bool {
+    !i
+}
+
 fn main() {
     assert_eq!(1, pure(1));
 }