Skip to content

Commit 4cc2d0b

Browse files
committed
Separate report_redundant_placeholders() into its own function
1 parent 93df9e6 commit 4cc2d0b

File tree

1 file changed

+62
-52
lines changed

1 file changed

+62
-52
lines changed

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 62 additions & 52 deletions
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};
@@ -615,56 +615,8 @@ fn report_missing_placeholders(
615615
})
616616
.collect::<Vec<_>>();
617617

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

670622
// Used to ensure we only report translations for *one* kind of foreign format.
@@ -754,6 +706,64 @@ fn report_missing_placeholders(
754706
diag.emit();
755707
}
756708

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

0 commit comments

Comments
 (0)