Allow function argument mismatch suggestion to be multiline

This commit is contained in:
Sasha Pourcelot 2025-08-05 00:11:01 +02:00
parent bdaabc17b6
commit 1e271d6ed1
3 changed files with 58 additions and 20 deletions

View file

@ -1589,26 +1589,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// e.g. `reuse HasSelf::method;` should suggest `reuse HasSelf::method($args);`.
full_call_span.shrink_to_hi()
};
// Controls how the arguments should be listed in the suggestion.
enum ArgumentsFormatting {
SingleLine,
Multiline { fallback_indent: String, brace_indent: String },
}
let arguments_formatting = {
let mut provided_inputs = matched_inputs.iter().filter_map(|a| *a);
if let Some(brace_indent) = source_map.indentation_before(suggestion_span)
&& let Some(first_idx) = provided_inputs.by_ref().next()
&& let Some(last_idx) = provided_inputs.by_ref().next()
&& let (_, first_span) = provided_arg_tys[first_idx]
&& let (_, last_span) = provided_arg_tys[last_idx]
&& source_map.is_multiline(first_span.to(last_span))
&& let Some(fallback_indent) = source_map.indentation_before(first_span)
{
ArgumentsFormatting::Multiline { fallback_indent, brace_indent }
} else {
ArgumentsFormatting::SingleLine
}
};
let mut suggestion = "(".to_owned();
let mut needs_comma = false;
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
if needs_comma {
suggestion += ", ";
} else {
needs_comma = true;
suggestion += ",";
}
let suggestion_text = if let Some(provided_idx) = provided_idx
match &arguments_formatting {
ArgumentsFormatting::SingleLine if needs_comma => suggestion += " ",
ArgumentsFormatting::SingleLine => {}
ArgumentsFormatting::Multiline { .. } => suggestion += "\n",
}
needs_comma = true;
let (suggestion_span, suggestion_text) = if let Some(provided_idx) = provided_idx
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
&& let Ok(arg_text) = source_map.span_to_snippet(provided_span)
{
arg_text
(Some(provided_span), arg_text)
} else {
// Propose a placeholder of the correct type
let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
ty_to_snippet(expected_ty, expected_idx)
(None, ty_to_snippet(expected_ty, expected_idx))
};
if let ArgumentsFormatting::Multiline { fallback_indent, .. } =
&arguments_formatting
{
let indent = suggestion_span
.and_then(|span| source_map.indentation_before(span))
.unwrap_or_else(|| fallback_indent.clone());
suggestion += &indent;
}
suggestion += &suggestion_text;
}
if let ArgumentsFormatting::Multiline { brace_indent, .. } = arguments_formatting {
suggestion += ",\n";
suggestion += &brace_indent;
}
suggestion += ")";
err.span_suggestion_verbose(
suggestion_span,

View file

@ -75,12 +75,16 @@ LL | fn foo(p1: T1, p2: Arc<T2>, p3: T3, p4: Arc<T4>, p5: T5, p6: T6, p7: T7, p8
| ^^^ -----------
help: provide the argument
|
LL - foo(
LL -
LL - p1, //p2,
LL - p3, p4, p5, p6, p7, p8,
LL - );
LL + foo(p1, /* Arc<T2> */, p3, p4, p5, p6, p7, p8);
LL ~ foo(
LL + p1,
LL + /* Arc<T2> */,
LL + p3,
LL + p4,
LL + p5,
LL + p6,
LL + p7,
LL + p8,
LL ~ );
|
error: aborting due to 4 previous errors

View file

@ -99,14 +99,10 @@ LL | fn function_with_lots_of_arguments(a: i32, b: char, c: i32, d: i32, e: i32,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -------
help: provide the argument
|
LL - function_with_lots_of_arguments(
LL - variable_name,
LL - variable_name,
LL - variable_name,
LL - variable_name,
LL - variable_name,
LL - );
LL + function_with_lots_of_arguments(variable_name, /* char */, variable_name, variable_name, variable_name, variable_name);
LL | function_with_lots_of_arguments(
LL | variable_name,
LL ~ /* char */,
LL ~ variable_name,
|
error: aborting due to 6 previous errors