From 634774b89b446945d62572e86c6d29f2dacc8c76 Mon Sep 17 00:00:00 2001 From: Mikhail Babenko Date: Fri, 24 Jan 2020 13:50:03 +0300 Subject: [PATCH] don't fire empty_loop in no_std crates --- clippy_lints/src/loops.rs | 8 ++++---- clippy_lints/src/main_recursion.rs | 12 ++---------- clippy_lints/src/utils/mod.rs | 12 +++++++++++- tests/ui/issue-3746.rs | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 tests/ui/issue-3746.rs diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index b2d6c178b..3f0fa6eeb 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 3a7bd2fb3..2d21aeaee 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 57eef077b..8918cbfa5 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 000000000..879d1d5d9 --- /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() {}