Don't leave a comma at the start of argument list when removing arguments

This commit is contained in:
Maybe Waffle 2023-03-30 17:11:06 +00:00
parent 6975b77e3b
commit b9d5a6b709
5 changed files with 73 additions and 19 deletions

View File

@ -21,7 +21,7 @@ use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
use rustc_hir_analysis::check::potentially_plural_count;
use rustc_hir_analysis::structured_errors::StructuredDiagnostic;
use rustc_index::vec::IndexVec;
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::TypeTrace;
@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, IsSuggestable, Ty};
use rustc_session::Session;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, sym, Span};
use rustc_span::{self, sym, BytePos, Span};
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
use std::iter;
@ -894,8 +894,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let mut errors = errors.into_iter().peekable();
let mut only_extras_so_far = errors
.peek()
.map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
let mut suggestions = vec![];
while let Some(error) = errors.next() {
only_extras_so_far &= matches!(error, Error::Extra(_));
match error {
Error::Invalid(provided_idx, expected_idx, compatibility) => {
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
@ -941,10 +946,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if arg_idx.index() > 0
&& let Some((_, prev)) = provided_arg_tys
.get(ProvidedIdx::from_usize(arg_idx.index() - 1)
) {
// Include previous comma
span = prev.shrink_to_hi().to(span);
}
) {
// Include previous comma
span = prev.shrink_to_hi().to(span);
}
// Is last argument for deletion in a row starting from the 0-th argument?
// Then delete the next comma, so we are not left with `f(, ...)`
//
// fn f() {}
// - f(0, 1,)
// + f()
if only_extras_so_far
&& errors
.peek()
.map_or(true, |next_error| !matches!(next_error, Error::Extra(_)))
{
let next = provided_arg_tys
.get(arg_idx.plus(1))
.map(|&(_, sp)| sp)
.unwrap_or_else(|| {
// Subtract one to move before `)`
call_expr
.span
.shrink_to_hi()
.with_lo(call_expr.span.hi() - BytePos(1))
});
// Include next comma
span = span.until(next);
}
suggestions.push((span, String::new()));
suggestion_text = match suggestion_text {

View File

@ -0,0 +1,20 @@
// run-rustfix
fn f() {}
fn i(_: u32) {}
fn is(_: u32, _: &str) {}
fn s(_: &str) {}
fn main() {
// code expected suggestion
f(); // f()
//~^ error: this function takes 0 arguments but 2 arguments were supplied
i(0,); // i(0,)
//~^ error: this function takes 1 argument but 3 arguments were supplied
i(0); // i(0)
//~^ error: this function takes 1 argument but 3 arguments were supplied
is(0, ""); // is(0, "")
//~^ error: this function takes 2 arguments but 4 arguments were supplied
s(""); // s("")
//~^ error: this function takes 1 argument but 3 arguments were supplied
}

View File

@ -1,3 +1,5 @@
// run-rustfix
fn f() {}
fn i(_: u32) {}
fn is(_: u32, _: &str) {}

View File

@ -1,5 +1,5 @@
error[E0061]: this function takes 0 arguments but 2 arguments were supplied
--> $DIR/issue-109425.rs:8:5
--> $DIR/issue-109425.rs:10:5
|
LL | f(0, 1,); // f()
| ^ - - unexpected argument of type `{integer}`
@ -7,18 +7,18 @@ LL | f(0, 1,); // f()
| unexpected argument of type `{integer}`
|
note: function defined here
--> $DIR/issue-109425.rs:1:4
--> $DIR/issue-109425.rs:3:4
|
LL | fn f() {}
| ^
help: remove the extra arguments
|
LL - f(0, 1,); // f()
LL + f(,); // f()
LL + f(); // f()
|
error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/issue-109425.rs:10:5
--> $DIR/issue-109425.rs:12:5
|
LL | i(0, 1, 2,); // i(0,)
| ^ - - unexpected argument of type `{integer}`
@ -26,7 +26,7 @@ LL | i(0, 1, 2,); // i(0,)
| unexpected argument of type `{integer}`
|
note: function defined here
--> $DIR/issue-109425.rs:2:4
--> $DIR/issue-109425.rs:4:4
|
LL | fn i(_: u32) {}
| ^ ------
@ -37,7 +37,7 @@ LL + i(0,); // i(0,)
|
error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/issue-109425.rs:12:5
--> $DIR/issue-109425.rs:14:5
|
LL | i(0, 1, 2); // i(0)
| ^ - - unexpected argument of type `{integer}`
@ -45,7 +45,7 @@ LL | i(0, 1, 2); // i(0)
| unexpected argument of type `{integer}`
|
note: function defined here
--> $DIR/issue-109425.rs:2:4
--> $DIR/issue-109425.rs:4:4
|
LL | fn i(_: u32) {}
| ^ ------
@ -56,7 +56,7 @@ LL + i(0); // i(0)
|
error[E0061]: this function takes 2 arguments but 4 arguments were supplied
--> $DIR/issue-109425.rs:14:5
--> $DIR/issue-109425.rs:16:5
|
LL | is(0, 1, 2, ""); // is(0, "")
| ^^ - - unexpected argument of type `{integer}`
@ -64,7 +64,7 @@ LL | is(0, 1, 2, ""); // is(0, "")
| unexpected argument of type `{integer}`
|
note: function defined here
--> $DIR/issue-109425.rs:3:4
--> $DIR/issue-109425.rs:5:4
|
LL | fn is(_: u32, _: &str) {}
| ^^ ------ -------
@ -75,7 +75,7 @@ LL + is(0, ""); // is(0, "")
|
error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/issue-109425.rs:16:5
--> $DIR/issue-109425.rs:18:5
|
LL | s(0, 1, ""); // s("")
| ^ - - unexpected argument of type `{integer}`
@ -83,14 +83,14 @@ LL | s(0, 1, ""); // s("")
| unexpected argument of type `{integer}`
|
note: function defined here
--> $DIR/issue-109425.rs:4:4
--> $DIR/issue-109425.rs:6:4
|
LL | fn s(_: &str) {}
| ^ -------
help: remove the extra arguments
|
LL - s(0, 1, ""); // s("")
LL + s(, ""); // s("")
LL + s(""); // s("")
|
error: aborting due to 5 previous errors

View File

@ -25,7 +25,7 @@ note: function defined here
help: remove the extra arguments
|
LL - file.as_raw_fd(),
LL + ,
LL + );
|
error: aborting due to 2 previous errors