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
This commit is contained in:
commit
4ef57d3a70
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -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() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user