Skip to content

Commit 196dbcf

Browse files
committed
Avoid linting for Regexes compiled in items defined in loops
1 parent 9f5bfe2 commit 196dbcf

File tree

3 files changed

+13
-10
lines changed

3 files changed

+13
-10
lines changed

clippy_lints/src/regex.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use clippy_utils::source::SpanRangeExt;
66
use clippy_utils::{def_path_def_ids, path_def_id, paths};
77
use rustc_ast::ast::{LitKind, StrStyle};
88
use rustc_hir::def_id::DefIdMap;
9-
use rustc_hir::{BorrowKind, Expr, ExprKind};
9+
use rustc_hir::{BorrowKind, Expr, ExprKind, OwnerId};
1010
use rustc_lint::{LateContext, LateLintPass};
1111
use rustc_session::impl_lint_pass;
1212
use rustc_span::{BytePos, Span};
@@ -104,7 +104,7 @@ enum RegexKind {
104104
#[derive(Default)]
105105
pub struct Regex {
106106
definitions: DefIdMap<RegexKind>,
107-
loop_stack: Vec<Span>,
107+
loop_stack: Vec<(OwnerId, Span)>,
108108
}
109109

110110
impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX, REGEX_CREATION_IN_LOOPS]);
@@ -135,7 +135,8 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
135135
&& let Some(def_id) = path_def_id(cx, fun)
136136
&& let Some(regex_kind) = self.definitions.get(&def_id)
137137
{
138-
if let Some(&loop_span) = self.loop_stack.last()
138+
if let Some(&(loop_item_id, loop_span)) = self.loop_stack.last()
139+
&& loop_item_id == fun.hir_id.owner
139140
&& (matches!(arg.kind, ExprKind::Lit(_)) || const_str(cx, arg).is_some())
140141
{
141142
span_lint_and_help(
@@ -154,8 +155,8 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
154155
RegexKind::Bytes => check_regex(cx, arg, false),
155156
RegexKind::BytesSet => check_set(cx, arg, false),
156157
}
157-
} else if let ExprKind::Loop(_, _, _, span) = expr.kind {
158-
self.loop_stack.push(span);
158+
} else if let ExprKind::Loop(block, _, _, span) = expr.kind {
159+
self.loop_stack.push((block.hir_id.owner, span));
159160
}
160161
}
161162

tests/ui/regex.rs

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ fn trivial_regex() {
120120

121121
fn regex_creation_in_loops() {
122122
loop {
123+
static STATIC_REGEX: std::sync::LazyLock<Regex> = std::sync::LazyLock::new(|| Regex::new("a.b").unwrap());
124+
123125
let regex = Regex::new("a.b");
124126
//~^ ERROR: compiling a regex in a loop
125127
let regex = BRegex::new("a.b");

tests/ui/regex.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ LL | let binary_trivial_empty = BRegex::new("^$");
196196
= help: consider using `str::is_empty`
197197

198198
error: compiling a regex in a loop
199-
--> tests/ui/regex.rs:123:21
199+
--> tests/ui/regex.rs:125:21
200200
|
201201
LL | let regex = Regex::new("a.b");
202202
| ^^^^^^^^^^
@@ -210,7 +210,7 @@ LL | loop {
210210
= help: to override `-D warnings` add `#[allow(clippy::regex_creation_in_loops)]`
211211

212212
error: compiling a regex in a loop
213-
--> tests/ui/regex.rs:125:21
213+
--> tests/ui/regex.rs:127:21
214214
|
215215
LL | let regex = BRegex::new("a.b");
216216
| ^^^^^^^^^^^
@@ -222,7 +222,7 @@ LL | loop {
222222
| ^^^^
223223

224224
error: compiling a regex in a loop
225-
--> tests/ui/regex.rs:131:25
225+
--> tests/ui/regex.rs:133:25
226226
|
227227
LL | let regex = Regex::new("a.b");
228228
| ^^^^^^^^^^
@@ -234,13 +234,13 @@ LL | loop {
234234
| ^^^^
235235

236236
error: compiling a regex in a loop
237-
--> tests/ui/regex.rs:136:32
237+
--> tests/ui/regex.rs:138:32
238238
|
239239
LL | let nested_regex = Regex::new("a.b");
240240
| ^^^^^^^^^^
241241
|
242242
help: move the regex construction outside this loop
243-
--> tests/ui/regex.rs:135:9
243+
--> tests/ui/regex.rs:137:9
244244
|
245245
LL | for _ in 0..10 {
246246
| ^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)