about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-01-24 21:42:46 +0000
committerbors <bors@rust-lang.org>2020-01-24 21:42:46 +0000
commit1ccd284ec645c65e487ae610d91c1943e2a17c6c (patch)
tree796f49a910b1f5ae481b5561723d45e29361b8c3
parentc48594c6945b37ecffb5608fca617c3a16d4715f (diff)
parent634774b89b446945d62572e86c6d29f2dacc8c76 (diff)
downloadrust-1ccd284ec645c65e487ae610d91c1943e2a17c6c.tar.gz
rust-1ccd284ec645c65e487ae610d91c1943e2a17c6c.zip
Auto merge of #5086 - Areredify:issue-3746, r=phansch
don't fire `empty_loop` in `no_std` crates

closes #3746.
changelog: move no_std detection to utils, don't fire empty_loop in no_std crates
-rw-r--r--clippy_lints/src/loops.rs8
-rw-r--r--clippy_lints/src/main_recursion.rs12
-rw-r--r--clippy_lints/src/utils/mod.rs12
-rw-r--r--tests/ui/issue-3746.rs22
4 files changed, 39 insertions, 15 deletions
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index b2d6c178b54..3f0fa6eebc6 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -4,9 +4,9 @@ use crate::utils::paths;
 use crate::utils::usage::{is_unused, mutated_variables};
 use crate::utils::{
     get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
-    is_integer_const, is_refutable, last_path_segment, match_trait_method, match_type, match_var, multispan_sugg,
-    snippet, snippet_opt, snippet_with_applicability, span_help_and_lint, span_lint, span_lint_and_sugg,
-    span_lint_and_then, SpanlessEq,
+    is_integer_const, is_no_std_crate, is_refutable, last_path_segment, match_trait_method, match_type, match_var,
+    multispan_sugg, snippet, snippet_opt, snippet_with_applicability, span_help_and_lint, span_lint,
+    span_lint_and_sugg, span_lint_and_then, SpanlessEq,
 };
 use crate::utils::{is_type_diagnostic_item, qpath_res, same_tys, sext, sugg};
 use if_chain::if_chain;
@@ -502,7 +502,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
         // (even if the "match" or "if let" is used for declaration)
         if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind {
             // also check for empty `loop {}` statements
-            if block.stmts.is_empty() && block.expr.is_none() {
+            if block.stmts.is_empty() && block.expr.is_none() && !is_no_std_crate(cx.tcx.hir().krate()) {
                 span_lint(
                     cx,
                     EMPTY_LOOP,
diff --git a/clippy_lints/src/main_recursion.rs b/clippy_lints/src/main_recursion.rs
index 3a7bd2fb3a2..2d21aeaeec4 100644
--- a/clippy_lints/src/main_recursion.rs
+++ b/clippy_lints/src/main_recursion.rs
@@ -1,10 +1,8 @@
 use rustc_hir::{Crate, Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::symbol::sym;
-use syntax::ast::AttrKind;
 
-use crate::utils::{is_entrypoint_fn, snippet, span_help_and_lint};
+use crate::utils::{is_entrypoint_fn, is_no_std_crate, snippet, span_help_and_lint};
 use if_chain::if_chain;
 
 declare_clippy_lint! {
@@ -35,13 +33,7 @@ impl_lint_pass!(MainRecursion => [MAIN_RECURSION]);
 
 impl LateLintPass<'_, '_> for MainRecursion {
     fn check_crate(&mut self, _: &LateContext<'_, '_>, krate: &Crate<'_>) {
-        self.has_no_std_attr = krate.attrs.iter().any(|attr| {
-            if let AttrKind::Normal(ref attr) = attr.kind {
-                attr.path == sym::no_std
-            } else {
-                false
-            }
-        });
+        self.has_no_std_attr = is_no_std_crate(krate);
     }
 
     fn check_expr_post(&mut self, cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 57eef077bdf..8918cbfa59b 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -43,7 +43,7 @@ use rustc_hir::Node;
 use rustc_hir::*;
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_span::hygiene::ExpnKind;
-use rustc_span::symbol::{kw, Symbol};
+use rustc_span::symbol::{self, kw, Symbol};
 use rustc_span::{BytePos, Pos, Span, DUMMY_SP};
 use smallvec::SmallVec;
 use syntax::ast::{self, Attribute, LitKind};
@@ -1344,3 +1344,13 @@ pub fn is_must_use_func_call(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool
         false
     }
 }
+
+pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
+    krate.attrs.iter().any(|attr| {
+        if let ast::AttrKind::Normal(ref attr) = attr.kind {
+            attr.path == symbol::sym::no_std
+        } else {
+            false
+        }
+    })
+}
diff --git a/tests/ui/issue-3746.rs b/tests/ui/issue-3746.rs
new file mode 100644
index 00000000000..879d1d5d916
--- /dev/null
+++ b/tests/ui/issue-3746.rs
@@ -0,0 +1,22 @@
+// ignore-macos
+// ignore-windows
+
+#![warn(clippy::empty_loop)]
+#![feature(lang_items, link_args, start, libc)]
+#![link_args = "-nostartfiles"]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[start]
+fn main(argc: isize, argv: *const *const u8) -> isize {
+    loop {}
+}
+
+#[panic_handler]
+fn panic(_info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}