Skip to content

Commit

Permalink
Auto merge of rust-lang#12558 - y21:issue9150, r=xFrednet
Browse files Browse the repository at this point in the history
[`let_and_return`]: avoid linting when code between last stmt and return expr is cfg'd out

Fixes rust-lang#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
  • Loading branch information
bors committed Mar 25, 2024
2 parents c3948d1 + 9e82ad8 commit 4ef57d3
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 31 deletions.
32 changes: 3 additions & 29 deletions clippy_lints/src/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
3 changes: 2 additions & 1 deletion clippy_lints/src/returns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
32 changes: 31 additions & 1 deletion clippy_utils/src/attrs.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
7 changes: 7 additions & 0 deletions tests/ui/let_and_return.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
7 changes: 7 additions & 0 deletions tests/ui/let_and_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

0 comments on commit 4ef57d3

Please sign in to comment.