about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-25 19:56:18 +0000
committerbors <bors@rust-lang.org>2024-03-25 19:56:18 +0000
commit4ef57d3a709d033fa0791ba20d2766a145f8cc03 (patch)
tree992372db608dbd6231471f0653a97bb6561c8b2f
parentc3948d16b928616407f1eac19bfea9ba9e2df16e (diff)
parent9e82ad87b9ae43bee6f06308631fbe0fb0a1c847 (diff)
downloadrust-4ef57d3a709d033fa0791ba20d2766a145f8cc03.tar.gz
rust-4ef57d3a709d033fa0791ba20d2766a145f8cc03.zip
Auto merge of #12558 - y21:issue9150, r=xFrednet
[`let_and_return`]: avoid linting when code between last stmt and return expr is cfg'd out

Fixes #9150

This moves `span_contains_cfg` to utils and starts using it in `let_and_return` as well.

changelog: [`let_and_return`]: avoid linting when code between the last statement and the final return expression is `#[cfg]`ed out
-rw-r--r--clippy_lints/src/matches/mod.rs32
-rw-r--r--clippy_lints/src/returns.rs3
-rw-r--r--clippy_utils/src/attrs.rs32
-rw-r--r--tests/ui/let_and_return.fixed7
-rw-r--r--tests/ui/let_and_return.rs7
5 files changed, 50 insertions, 31 deletions
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index 50494f4819f..dd83e32a943 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -25,14 +25,13 @@ mod try_err;
 mod wild_in_or_pats;
 
 use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::source::{snippet_opt, walk_span_to_context};
-use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text};
+use clippy_utils::source::walk_span_to_context;
+use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, span_contains_cfg};
 use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
-use rustc_lexer::TokenKind;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::{Span, SpanData, SyntaxContext};
+use rustc_span::{SpanData, SyntaxContext};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -1196,28 +1195,3 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar
         Err(()) => true,
     }
 }
-
-/// Checks if the given span contains a `#[cfg(..)]` attribute
-fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
-    let Some(snip) = snippet_opt(cx, s) else {
-        // Assume true. This would require either an invalid span, or one which crosses file boundaries.
-        return true;
-    };
-    let mut iter = tokenize_with_text(&snip);
-
-    // Search for the token sequence [`#`, `[`, `cfg`]
-    while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
-        let mut iter = iter.by_ref().skip_while(|(t, _)| {
-            matches!(
-                t,
-                TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
-            )
-        });
-        if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
-            && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
-        {
-            return true;
-        }
-    }
-    false
-}
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index 8bc24eda465..e8f9d438104 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::{snippet_opt, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
 use clippy_utils::{
-    fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id,
+    fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id, span_contains_cfg,
     span_find_starting_semi,
 };
 use core::ops::ControlFlow;
@@ -232,6 +232,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
             && !in_external_macro(cx.sess(), initexpr.span)
             && !in_external_macro(cx.sess(), retexpr.span)
             && !local.span.from_expansion()
+            && !span_contains_cfg(cx, stmt.span.between(retexpr.span))
         {
             span_lint_hir_and_then(
                 cx,
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index 2d0c2cf1253..d2200bcf710 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -1,10 +1,15 @@
 use rustc_ast::{ast, attr};
 use rustc_errors::Applicability;
+use rustc_lexer::TokenKind;
+use rustc_lint::LateContext;
 use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
-use rustc_span::sym;
+use rustc_span::{sym, Span};
 use std::str::FromStr;
 
+use crate::source::snippet_opt;
+use crate::tokenize_with_text;
+
 /// Deprecation status of attributes known by Clippy.
 pub enum DeprecationStatus {
     /// Attribute is deprecated
@@ -171,3 +176,28 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
             .all_fields()
             .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive))
 }
+
+/// Checks if the given span contains a `#[cfg(..)]` attribute
+pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
+    let Some(snip) = snippet_opt(cx, s) else {
+        // Assume true. This would require either an invalid span, or one which crosses file boundaries.
+        return true;
+    };
+    let mut iter = tokenize_with_text(&snip);
+
+    // Search for the token sequence [`#`, `[`, `cfg`]
+    while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
+        let mut iter = iter.by_ref().skip_while(|(t, _)| {
+            matches!(
+                t,
+                TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
+            )
+        });
+        if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
+            && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
+        {
+            return true;
+        }
+    }
+    false
+}
diff --git a/tests/ui/let_and_return.fixed b/tests/ui/let_and_return.fixed
index b5584fcde8c..4187019e589 100644
--- a/tests/ui/let_and_return.fixed
+++ b/tests/ui/let_and_return.fixed
@@ -203,4 +203,11 @@ fn_in_macro!({
     return 1;
 });
 
+fn issue9150() -> usize {
+    let x = 1;
+    #[cfg(any())]
+    panic!("can't see me");
+    x
+}
+
 fn main() {}
diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs
index f13c7c4e203..54444957b7d 100644
--- a/tests/ui/let_and_return.rs
+++ b/tests/ui/let_and_return.rs
@@ -203,4 +203,11 @@ fn_in_macro!({
     return 1;
 });
 
+fn issue9150() -> usize {
+    let x = 1;
+    #[cfg(any())]
+    panic!("can't see me");
+    x
+}
+
 fn main() {}