Skip to content

Commit 5a91715

Browse files
committed
Separate report_redundant_placeholders() into its own function
1 parent 12ff6f2 commit 5a91715

File tree

1 file changed

+62
-52
lines changed

1 file changed

+62
-52
lines changed

compiler/rustc_builtin_macros/src/format.rs

+62-52
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use rustc_ast::{
88
FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait,
99
};
1010
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
11-
use rustc_errors::{Applicability, MultiSpan, PResult, SingleLabelManySpans};
11+
use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan, PResult, SingleLabelManySpans};
1212
use rustc_expand::base::{self, *};
1313
use rustc_parse_format as parse;
1414
use rustc_span::symbol::{Ident, Symbol};
15-
use rustc_span::{BytePos, InnerSpan, Span};
15+
use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
1616

1717
use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
1818
use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
@@ -606,56 +606,8 @@ fn report_missing_placeholders(
606606
})
607607
.collect::<Vec<_>>();
608608

609-
let mut args_spans = vec![];
610-
let mut fmt_spans = FxIndexSet::default();
611-
612-
for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() {
613-
let Some(ty) = unnamed_arg.expr.to_ty() else { continue };
614-
let Some(argument_binding) = ty.kind.is_simple_path() else { continue };
615-
let argument_binding = argument_binding.as_str();
616-
617-
if used[i] {
618-
continue;
619-
}
620-
621-
let matching_placeholders = placeholders
622-
.iter()
623-
.filter(|(_, inline_binding)| argument_binding == *inline_binding)
624-
.collect::<Vec<_>>();
625-
626-
if !matching_placeholders.is_empty() {
627-
args_spans.push(unnamed_arg.expr.span);
628-
for placeholder in &matching_placeholders {
629-
fmt_spans.insert(*placeholder);
630-
}
631-
}
632-
}
633-
634-
if !args_spans.is_empty() {
635-
let mut multispan = MultiSpan::from(args_spans.clone());
636-
637-
let msg = if fmt_spans.len() > 1 {
638-
"the formatting strings already captures the bindings \
639-
directly, they don't need to be included in the argument list"
640-
} else {
641-
"the formatting string already captures the binding \
642-
directly, it doesn't need to be included in the argument list"
643-
};
644-
645-
for (span, binding) in fmt_spans {
646-
multispan.push_span_label(
647-
*span,
648-
format!("this formatting specifier is referencing the `{binding}` binding"),
649-
);
650-
}
651-
652-
for span in &args_spans {
653-
multispan.push_span_label(*span, "this can be removed");
654-
}
655-
656-
diag.span_help(multispan, msg);
657-
diag.emit();
658-
return;
609+
if !placeholders.is_empty() {
610+
report_redundant_placeholders(&mut diag, &args, used, placeholders);
659611
}
660612

661613
// Used to ensure we only report translations for *one* kind of foreign format.
@@ -745,6 +697,64 @@ fn report_missing_placeholders(
745697
diag.emit();
746698
}
747699

700+
fn report_redundant_placeholders(
701+
diag: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
702+
args: &FormatArguments,
703+
used: &[bool],
704+
placeholders: Vec<(Span, &str)>,
705+
) {
706+
let mut args_spans = vec![];
707+
let mut fmt_spans = FxIndexSet::default();
708+
709+
for (i, unnamed_arg) in args.unnamed_args().iter().enumerate().rev() {
710+
let Some(ty) = unnamed_arg.expr.to_ty() else { continue };
711+
let Some(argument_binding) = ty.kind.is_simple_path() else { continue };
712+
let argument_binding = argument_binding.as_str();
713+
714+
if used[i] {
715+
continue;
716+
}
717+
718+
let matching_placeholders = placeholders
719+
.iter()
720+
.filter(|(_, inline_binding)| argument_binding == *inline_binding)
721+
.collect::<Vec<_>>();
722+
723+
if !matching_placeholders.is_empty() {
724+
args_spans.push(unnamed_arg.expr.span);
725+
for placeholder in &matching_placeholders {
726+
fmt_spans.insert(*placeholder);
727+
}
728+
}
729+
}
730+
731+
if !args_spans.is_empty() {
732+
let mut multispan = MultiSpan::from(args_spans.clone());
733+
734+
let msg = if fmt_spans.len() > 1 {
735+
"the formatting strings already captures the bindings \
736+
directly, they don't need to be included in the argument list"
737+
} else {
738+
"the formatting string already captures the binding \
739+
directly, it doesn't need to be included in the argument list"
740+
};
741+
742+
for (span, binding) in fmt_spans {
743+
multispan.push_span_label(
744+
*span,
745+
format!("this formatting specifier is referencing the `{binding}` binding"),
746+
);
747+
}
748+
749+
for span in &args_spans {
750+
multispan.push_span_label(*span, "this can be removed");
751+
}
752+
753+
diag.span_help(multispan, msg);
754+
diag.emit();
755+
}
756+
}
757+
748758
/// Handle invalid references to positional arguments. Output different
749759
/// errors for the case where all arguments are positional and for when
750760
/// there are named arguments or numbered positional arguments in the

0 commit comments

Comments
 (0)