Skip to content

Commit dcc2b5c

Browse files
committed
Fix FormatArgs storage when -Zthreads > 1
1 parent b8b9b27 commit dcc2b5c

File tree

10 files changed

+149
-94
lines changed

10 files changed

+149
-94
lines changed

clippy_lints/src/explicit_write.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::macros::{find_format_args, format_args_inputs_span};
2+
use clippy_utils::macros::{format_args_inputs_span, FormatArgsStorage};
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::{is_expn_of, path_def_id};
55
use rustc_errors::Applicability;
66
use rustc_hir::def::Res;
77
use rustc_hir::{BindingAnnotation, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind};
88
use rustc_lint::{LateContext, LateLintPass};
9-
use rustc_session::declare_lint_pass;
9+
use rustc_session::impl_lint_pass;
1010
use rustc_span::{sym, ExpnId};
1111

1212
declare_clippy_lint! {
@@ -38,7 +38,17 @@ declare_clippy_lint! {
3838
"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work"
3939
}
4040

41-
declare_lint_pass!(ExplicitWrite => [EXPLICIT_WRITE]);
41+
pub struct ExplicitWrite {
42+
format_args: FormatArgsStorage,
43+
}
44+
45+
impl ExplicitWrite {
46+
pub fn new(format_args: FormatArgsStorage) -> Self {
47+
Self { format_args }
48+
}
49+
}
50+
51+
impl_lint_pass!(ExplicitWrite => [EXPLICIT_WRITE]);
4252

4353
impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
4454
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
@@ -57,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
5767
Some(sym::io_stderr) => ("stderr", "e"),
5868
_ => return,
5969
};
60-
let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root()) else {
70+
let Some(format_args) = self.format_args.get(cx, write_arg, ExpnId::root()) else {
6171
return;
6272
};
6373

@@ -83,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
8393
};
8494
let mut applicability = Applicability::MachineApplicable;
8595
let inputs_snippet =
86-
snippet_with_applicability(cx, format_args_inputs_span(&format_args), "..", &mut applicability);
96+
snippet_with_applicability(cx, format_args_inputs_span(format_args), "..", &mut applicability);
8797
span_lint_and_sugg(
8898
cx,
8999
EXPLICIT_WRITE,

clippy_lints/src/format.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::macros::{find_format_arg_expr, find_format_args, root_macro_call_first_node};
2+
use clippy_utils::macros::{find_format_arg_expr, root_macro_call_first_node, FormatArgsStorage};
33
use clippy_utils::source::{snippet_opt, snippet_with_context};
44
use clippy_utils::sugg::Sugg;
55
use rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};
66
use rustc_errors::Applicability;
77
use rustc_hir::{Expr, ExprKind};
88
use rustc_lint::{LateContext, LateLintPass};
99
use rustc_middle::ty;
10-
use rustc_session::declare_lint_pass;
10+
use rustc_session::impl_lint_pass;
1111
use rustc_span::{sym, Span};
1212

1313
declare_clippy_lint! {
@@ -39,13 +39,24 @@ declare_clippy_lint! {
3939
"useless use of `format!`"
4040
}
4141

42-
declare_lint_pass!(UselessFormat => [USELESS_FORMAT]);
42+
#[allow(clippy::module_name_repetitions)]
43+
pub struct UselessFormat {
44+
format_args: FormatArgsStorage,
45+
}
46+
47+
impl UselessFormat {
48+
pub fn new(format_args: FormatArgsStorage) -> Self {
49+
Self { format_args }
50+
}
51+
}
52+
53+
impl_lint_pass!(UselessFormat => [USELESS_FORMAT]);
4354

4455
impl<'tcx> LateLintPass<'tcx> for UselessFormat {
4556
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
4657
if let Some(macro_call) = root_macro_call_first_node(cx, expr)
4758
&& cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
48-
&& let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
59+
&& let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn)
4960
{
5061
let mut applicability = Applicability::MachineApplicable;
5162
let call_site = macro_call.span;

clippy_lints/src/format_args.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use clippy_config::msrvs::{self, Msrv};
33
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
44
use clippy_utils::is_diag_trait_item;
55
use clippy_utils::macros::{
6-
find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro,
7-
is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage, MacroCall,
6+
find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro,
7+
is_panic, root_macro_call, root_macro_call_first_node, FormatArgsStorage, FormatParamUsage, MacroCall,
88
};
99
use clippy_utils::source::snippet_opt;
1010
use clippy_utils::ty::{implements_trait, is_type_lang_item};
@@ -167,15 +167,18 @@ impl_lint_pass!(FormatArgs => [
167167
UNUSED_FORMAT_SPECS,
168168
]);
169169

170+
#[allow(clippy::struct_field_names)]
170171
pub struct FormatArgs {
172+
format_args: FormatArgsStorage,
171173
msrv: Msrv,
172174
ignore_mixed: bool,
173175
}
174176

175177
impl FormatArgs {
176178
#[must_use]
177-
pub fn new(msrv: Msrv, allow_mixed_uninlined_format_args: bool) -> Self {
179+
pub fn new(format_args: FormatArgsStorage, msrv: Msrv, allow_mixed_uninlined_format_args: bool) -> Self {
178180
Self {
181+
format_args,
179182
msrv,
180183
ignore_mixed: allow_mixed_uninlined_format_args,
181184
}
@@ -186,13 +189,13 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
186189
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
187190
if let Some(macro_call) = root_macro_call_first_node(cx, expr)
188191
&& is_format_macro(cx, macro_call.def_id)
189-
&& let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
192+
&& let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn)
190193
{
191194
let linter = FormatArgsExpr {
192195
cx,
193196
expr,
194197
macro_call: &macro_call,
195-
format_args: &format_args,
198+
format_args,
196199
ignore_mixed: self.ignore_mixed,
197200
};
198201

clippy_lints/src/format_impl.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
2-
use clippy_utils::macros::{find_format_arg_expr, find_format_args, is_format_macro, root_macro_call_first_node};
2+
use clippy_utils::macros::{find_format_arg_expr, is_format_macro, root_macro_call_first_node, FormatArgsStorage};
33
use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators};
44
use rustc_ast::{FormatArgsPiece, FormatTrait};
55
use rustc_errors::Applicability;
@@ -99,13 +99,15 @@ struct FormatTraitNames {
9999

100100
#[derive(Default)]
101101
pub struct FormatImpl {
102+
format_args: FormatArgsStorage,
102103
// Whether we are inside Display or Debug trait impl - None for neither
103104
format_trait_impl: Option<FormatTraitNames>,
104105
}
105106

106107
impl FormatImpl {
107-
pub fn new() -> Self {
108+
pub fn new(format_args: FormatArgsStorage) -> Self {
108109
Self {
110+
format_args,
109111
format_trait_impl: None,
110112
}
111113
}
@@ -129,6 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatImpl {
129131
if let Some(format_trait_impl) = self.format_trait_impl {
130132
let linter = FormatImplExpr {
131133
cx,
134+
format_args: &self.format_args,
132135
expr,
133136
format_trait_impl,
134137
};
@@ -141,6 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatImpl {
141144

142145
struct FormatImplExpr<'a, 'tcx> {
143146
cx: &'a LateContext<'tcx>,
147+
format_args: &'a FormatArgsStorage,
144148
expr: &'tcx Expr<'tcx>,
145149
format_trait_impl: FormatTraitNames,
146150
}
@@ -175,7 +179,7 @@ impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
175179
if let Some(outer_macro) = root_macro_call_first_node(self.cx, self.expr)
176180
&& let macro_def_id = outer_macro.def_id
177181
&& is_format_macro(self.cx, macro_def_id)
178-
&& let Some(format_args) = find_format_args(self.cx, self.expr, outer_macro.expn)
182+
&& let Some(format_args) = self.format_args.get(self.cx, self.expr, outer_macro.expn)
179183
{
180184
for piece in &format_args.template {
181185
if let FormatArgsPiece::Placeholder(placeholder) = piece

clippy_lints/src/lib.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ extern crate clippy_utils;
6060
#[macro_use]
6161
extern crate declare_clippy_lint;
6262

63-
use std::collections::BTreeMap;
64-
65-
use rustc_data_structures::fx::FxHashSet;
66-
use rustc_lint::{Lint, LintId};
67-
6863
#[cfg(feature = "internal")]
6964
pub mod deprecated_lints;
7065
#[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
@@ -383,6 +378,10 @@ mod zero_sized_map_values;
383378
// end lints modules, do not remove this comment, it’s used in `update_lints`
384379

385380
use clippy_config::{get_configuration_metadata, Conf};
381+
use clippy_utils::macros::FormatArgsStorage;
382+
use rustc_data_structures::fx::FxHashSet;
383+
use rustc_lint::{Lint, LintId};
384+
use std::collections::BTreeMap;
386385

387386
/// Register all pre expansion lints
388387
///
@@ -652,7 +651,13 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
652651
.collect(),
653652
))
654653
});
655-
store.register_early_pass(|| Box::<utils::format_args_collector::FormatArgsCollector>::default());
654+
let format_args_storage = FormatArgsStorage::default();
655+
let format_args = format_args_storage.clone();
656+
store.register_early_pass(move || {
657+
Box::new(utils::format_args_collector::FormatArgsCollector::new(
658+
format_args.clone(),
659+
))
660+
});
656661
store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
657662
store.register_late_pass(|_| Box::new(utils::author::Author));
658663
store.register_late_pass(move |_| {
@@ -694,13 +699,15 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
694699
store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
695700
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
696701
store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
702+
let format_args = format_args_storage.clone();
697703
store.register_late_pass(move |_| {
698704
Box::new(methods::Methods::new(
699705
avoid_breaking_exported_api,
700706
msrv(),
701707
allow_expect_in_tests,
702708
allow_unwrap_in_tests,
703709
allowed_dotfiles.clone(),
710+
format_args.clone(),
704711
))
705712
});
706713
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
@@ -764,7 +771,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
764771
store.register_late_pass(|_| Box::<regex::Regex>::default());
765772
store.register_late_pass(move |_| Box::new(copies::CopyAndPaste::new(ignore_interior_mutability.clone())));
766773
store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator));
767-
store.register_late_pass(|_| Box::new(format::UselessFormat));
774+
let format_args = format_args_storage.clone();
775+
store.register_late_pass(move |_| Box::new(format::UselessFormat::new(format_args.clone())));
768776
store.register_late_pass(|_| Box::new(swap::Swap));
769777
store.register_late_pass(|_| Box::new(overflow_check_conditional::OverflowCheckConditional));
770778
store.register_late_pass(|_| Box::<new_without_default::NewWithoutDefault>::default());
@@ -788,7 +796,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
788796
store.register_late_pass(|_| Box::new(partialeq_ne_impl::PartialEqNeImpl));
789797
store.register_late_pass(|_| Box::new(unused_io_amount::UnusedIoAmount));
790798
store.register_late_pass(move |_| Box::new(large_enum_variant::LargeEnumVariant::new(enum_variant_size_threshold)));
791-
store.register_late_pass(|_| Box::new(explicit_write::ExplicitWrite));
799+
let format_args = format_args_storage.clone();
800+
store.register_late_pass(move |_| Box::new(explicit_write::ExplicitWrite::new(format_args.clone())));
792801
store.register_late_pass(|_| Box::new(needless_pass_by_value::NeedlessPassByValue));
793802
store.register_late_pass(move |tcx| {
794803
Box::new(pass_by_ref_or_value::PassByRefOrValue::new(
@@ -830,7 +839,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
830839
store.register_late_pass(move |_| Box::new(mut_key::MutableKeyType::new(ignore_interior_mutability.clone())));
831840
store.register_early_pass(|| Box::new(reference::DerefAddrOf));
832841
store.register_early_pass(|| Box::new(double_parens::DoubleParens));
833-
store.register_late_pass(|_| Box::new(format_impl::FormatImpl::new()));
842+
let format_args = format_args_storage.clone();
843+
store.register_late_pass(move |_| Box::new(format_impl::FormatImpl::new(format_args.clone())));
834844
store.register_early_pass(|| Box::new(unsafe_removed_from_name::UnsafeNameRemoval));
835845
store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));
836846
store.register_early_pass(|| Box::new(int_plus_one::IntPlusOne));
@@ -955,8 +965,14 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
955965
accept_comment_above_attributes,
956966
))
957967
});
958-
store
959-
.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv(), allow_mixed_uninlined_format_args)));
968+
let format_args = format_args_storage.clone();
969+
store.register_late_pass(move |_| {
970+
Box::new(format_args::FormatArgs::new(
971+
format_args.clone(),
972+
msrv(),
973+
allow_mixed_uninlined_format_args,
974+
))
975+
});
960976
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
961977
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
962978
store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit));
@@ -967,7 +983,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
967983
store.register_late_pass(|_| Box::new(default_union_representation::DefaultUnionRepresentation));
968984
store.register_late_pass(|_| Box::<only_used_in_recursion::OnlyUsedInRecursion>::default());
969985
store.register_late_pass(move |_| Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
970-
store.register_late_pass(move |_| Box::new(write::Write::new(allow_print_in_tests)));
986+
let format_args = format_args_storage.clone();
987+
store.register_late_pass(move |_| Box::new(write::Write::new(format_args.clone(), allow_print_in_tests)));
971988
store.register_late_pass(move |_| {
972989
Box::new(cargo::Cargo {
973990
ignore_publish: cargo_ignore_publish,

clippy_lints/src/methods/expect_fun_call.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::macros::{find_format_args, format_args_inputs_span, root_macro_call_first_node};
2+
use clippy_utils::macros::{format_args_inputs_span, root_macro_call_first_node, FormatArgsStorage};
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
55
use rustc_errors::Applicability;
@@ -16,6 +16,7 @@ use super::EXPECT_FUN_CALL;
1616
#[allow(clippy::too_many_lines)]
1717
pub(super) fn check<'tcx>(
1818
cx: &LateContext<'tcx>,
19+
format_args_storage: &FormatArgsStorage,
1920
expr: &hir::Expr<'_>,
2021
method_span: Span,
2122
name: &str,
@@ -134,9 +135,9 @@ pub(super) fn check<'tcx>(
134135
// Special handling for `format!` as arg_root
135136
if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
136137
if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
137-
&& let Some(format_args) = find_format_args(cx, arg_root, macro_call.expn)
138+
&& let Some(format_args) = format_args_storage.get(cx, arg_root, macro_call.expn)
138139
{
139-
let span = format_args_inputs_span(&format_args);
140+
let span = format_args_inputs_span(format_args);
140141
let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
141142
span_lint_and_sugg(
142143
cx,

clippy_lints/src/methods/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ use bind_instead_of_map::BindInsteadOfMap;
133133
use clippy_config::msrvs::{self, Msrv};
134134
use clippy_utils::consts::{constant, Constant};
135135
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
136+
use clippy_utils::macros::FormatArgsStorage;
136137
use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
137138
use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
138139
pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
@@ -4074,12 +4075,14 @@ declare_clippy_lint! {
40744075
suspicious,
40754076
"is_empty() called on strings known at compile time"
40764077
}
4078+
40774079
pub struct Methods {
40784080
avoid_breaking_exported_api: bool,
40794081
msrv: Msrv,
40804082
allow_expect_in_tests: bool,
40814083
allow_unwrap_in_tests: bool,
40824084
allowed_dotfiles: FxHashSet<String>,
4085+
format_args: FormatArgsStorage,
40834086
}
40844087

40854088
impl Methods {
@@ -4090,6 +4093,7 @@ impl Methods {
40904093
allow_expect_in_tests: bool,
40914094
allow_unwrap_in_tests: bool,
40924095
mut allowed_dotfiles: FxHashSet<String>,
4096+
format_args: FormatArgsStorage,
40934097
) -> Self {
40944098
allowed_dotfiles.extend(DEFAULT_ALLOWED_DOTFILES.iter().map(ToString::to_string));
40954099

@@ -4099,6 +4103,7 @@ impl Methods {
40994103
allow_expect_in_tests,
41004104
allow_unwrap_in_tests,
41014105
allowed_dotfiles,
4106+
format_args,
41024107
}
41034108
}
41044109
}
@@ -4268,7 +4273,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
42684273
ExprKind::MethodCall(method_call, receiver, args, _) => {
42694274
let method_span = method_call.ident.span;
42704275
or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
4271-
expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
4276+
expect_fun_call::check(
4277+
cx,
4278+
&self.format_args,
4279+
expr,
4280+
method_span,
4281+
method_call.ident.as_str(),
4282+
receiver,
4283+
args,
4284+
);
42724285
clone_on_copy::check(cx, expr, method_call.ident.name, receiver, args);
42734286
clone_on_ref_ptr::check(cx, expr, method_call.ident.name, receiver, args);
42744287
inefficient_to_string::check(cx, expr, method_call.ident.name, receiver, args);

0 commit comments

Comments
 (0)