Avoid linting for Regexes compiled in items defined in loops
This commit is contained in:
parent
9f5bfe24eb
commit
196dbcf6d5
3 changed files with 13 additions and 10 deletions
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue