about summary refs log tree commit diff
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2021-10-08 16:16:56 +0200
committerflip1995 <philipp.krones@embecosm.com>2021-10-08 16:16:56 +0200
commitb423b85ca99c2a085797e228ec405038bbd3308f (patch)
treeb7adcb3469429666e4d9dbb72271a889d272cd59
parent78e73129baf65f4095002422303157d5e64e9479 (diff)
downloadrust-b423b85ca99c2a085797e228ec405038bbd3308f.tar.gz
rust-b423b85ca99c2a085797e228ec405038bbd3308f.zip
Don't trigger semicolon_if_nothing_returned in expanded code
Before this lint didn't trigger on macros. With rust-lang/rust#88175
this isn't enough anymore. In this PR a `WhileLoop` desugaring kind was
introduced. This overrides the span of expanded expressions when
lowering the while loop. So if a while loop is in a macro, the
expressions that it expands to are no longer marked with
`ExpnKind::Macro`, but with `ExpnKind::Desugaring`. In general, this is
the correct behavior and the same that is done for `ForLoop`s. It just
tripped up this lint.
-rw-r--r--clippy_lints/src/semicolon_if_nothing_returned.rs4
-rw-r--r--tests/ui/semicolon_if_nothing_returned.rs12
2 files changed, 14 insertions, 2 deletions
diff --git a/clippy_lints/src/semicolon_if_nothing_returned.rs b/clippy_lints/src/semicolon_if_nothing_returned.rs
index 6966230156c..c0e4914efe0 100644
--- a/clippy_lints/src/semicolon_if_nothing_returned.rs
+++ b/clippy_lints/src/semicolon_if_nothing_returned.rs
@@ -1,7 +1,7 @@
 use crate::rustc_lint::LintContext;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_macro_callsite;
-use clippy_utils::{in_macro, sugg};
+use clippy_utils::sugg;
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, ExprKind};
@@ -39,7 +39,7 @@ declare_lint_pass!(SemicolonIfNothingReturned => [SEMICOLON_IF_NOTHING_RETURNED]
 impl LateLintPass<'_> for SemicolonIfNothingReturned {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if_chain! {
-            if !in_macro(block.span);
+            if !block.span.from_expansion();
             if let Some(expr) = block.expr;
             let t_expr = cx.typeck_results().expr_ty(expr);
             if t_expr.is_unit();
diff --git a/tests/ui/semicolon_if_nothing_returned.rs b/tests/ui/semicolon_if_nothing_returned.rs
index 9644a232968..7a45f1b18d4 100644
--- a/tests/ui/semicolon_if_nothing_returned.rs
+++ b/tests/ui/semicolon_if_nothing_returned.rs
@@ -98,3 +98,15 @@ fn unsafe_checks() {
     let mut s = MaybeUninit::<String>::uninit();
     let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };
 }
+
+// Issue #7768
+#[rustfmt::skip]
+fn macro_with_semicolon() {
+    macro_rules! repro {
+        () => {
+            while false {
+            }
+        };
+    }
+    repro!();
+}