Avoid linting for Regexes compiled in items defined in loops

This commit is contained in:
GnomedDev 2024-10-05 17:08:33 +01:00
parent 9f5bfe24eb
commit 196dbcf6d5
No known key found for this signature in database
3 changed files with 13 additions and 10 deletions

View file

@ -6,7 +6,7 @@ use clippy_utils::source::SpanRangeExt;
use clippy_utils::{def_path_def_ids, path_def_id, paths};
use rustc_ast::ast::{LitKind, StrStyle};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::{BorrowKind, Expr, ExprKind};
use rustc_hir::{BorrowKind, Expr, ExprKind, OwnerId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::{BytePos, Span};
@ -104,7 +104,7 @@ enum RegexKind {
#[derive(Default)]
pub struct Regex {
definitions: DefIdMap<RegexKind>,
loop_stack: Vec<Span>,
loop_stack: Vec<(OwnerId, Span)>,
}
impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX, REGEX_CREATION_IN_LOOPS]);
@ -135,7 +135,8 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
&& let Some(def_id) = path_def_id(cx, fun)
&& let Some(regex_kind) = self.definitions.get(&def_id)
{
if let Some(&loop_span) = self.loop_stack.last()
if let Some(&(loop_item_id, loop_span)) = self.loop_stack.last()
&& loop_item_id == fun.hir_id.owner
&& (matches!(arg.kind, ExprKind::Lit(_)) || const_str(cx, arg).is_some())
{
span_lint_and_help(
@ -154,8 +155,8 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
RegexKind::Bytes => check_regex(cx, arg, false),
RegexKind::BytesSet => check_set(cx, arg, false),
}
} else if let ExprKind::Loop(_, _, _, span) = expr.kind {
self.loop_stack.push(span);
} else if let ExprKind::Loop(block, _, _, span) = expr.kind {
self.loop_stack.push((block.hir_id.owner, span));
}
}

View file

@ -120,6 +120,8 @@ fn trivial_regex() {
fn regex_creation_in_loops() {
loop {
static STATIC_REGEX: std::sync::LazyLock<Regex> = std::sync::LazyLock::new(|| Regex::new("a.b").unwrap());
let regex = Regex::new("a.b");
//~^ ERROR: compiling a regex in a loop
let regex = BRegex::new("a.b");

View file

@ -196,7 +196,7 @@ LL | let binary_trivial_empty = BRegex::new("^$");
= help: consider using `str::is_empty`
error: compiling a regex in a loop
--> tests/ui/regex.rs:123:21
--> tests/ui/regex.rs:125:21
|
LL | let regex = Regex::new("a.b");
| ^^^^^^^^^^
@ -210,7 +210,7 @@ LL | loop {
= help: to override `-D warnings` add `#[allow(clippy::regex_creation_in_loops)]`
error: compiling a regex in a loop
--> tests/ui/regex.rs:125:21
--> tests/ui/regex.rs:127:21
|
LL | let regex = BRegex::new("a.b");
| ^^^^^^^^^^^
@ -222,7 +222,7 @@ LL | loop {
| ^^^^
error: compiling a regex in a loop
--> tests/ui/regex.rs:131:25
--> tests/ui/regex.rs:133:25
|
LL | let regex = Regex::new("a.b");
| ^^^^^^^^^^
@ -234,13 +234,13 @@ LL | loop {
| ^^^^
error: compiling a regex in a loop
--> tests/ui/regex.rs:136:32
--> tests/ui/regex.rs:138:32
|
LL | let nested_regex = Regex::new("a.b");
| ^^^^^^^^^^
|
help: move the regex construction outside this loop
--> tests/ui/regex.rs:135:9
--> tests/ui/regex.rs:137:9
|
LL | for _ in 0..10 {
| ^^^^^^^^^^^^^^