Skip to content

Commit

Permalink
Rollup merge of rust-lang#96646 - estebank:issue-96638, r=jackh726
Browse files Browse the repository at this point in the history
Mitigate impact of subtle invalid call suggestion logic

There's some subtle interaction between inferred expressions being
passed as an argument to fn calls with fewer than expected arguments. To
avoid the ICE, I'm changing indexing operations with `.get(idx)`, but
the underlying logic still needs to be audited as it was written with
the assumption that `final_arg_types` and `provided_args` have the right
length.

Address rust-lang#96638.
  • Loading branch information
JohnTitor authored May 3, 2022
2 parents 1e6b880 + 7790b6e commit 279d801
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
32 changes: 20 additions & 12 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
errors.drain_filter(|error| {
let Error::Invalid(input_idx, Compatibility::Incompatible(error)) = error else { return false };
let expected_ty = expected_input_tys[*input_idx];
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
let Some(Some((provided_ty, _))) = final_arg_types.get(*input_idx) else { return false };
let cause = &self.misc(provided_args[*input_idx].span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
let trace = TypeTrace::types(cause, true, expected_ty, *provided_ty);
if let Some(e) = error {
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
self.report_and_explain_type_error(trace, e).emit();
Expand Down Expand Up @@ -679,8 +679,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Error::Invalid(input_idx, compatibility) => {
let expected_ty = expected_input_tys[input_idx];
if let Compatibility::Incompatible(error) = &compatibility {
let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap();
let cause = &self.misc(provided_args[input_idx].span);
let provided_ty = final_arg_types
.get(input_idx)
.and_then(|x| x.as_ref())
.map(|ty| ty.0)
.unwrap_or(tcx.ty_error());
let cause = &self.misc(
provided_args.get(input_idx).map(|i| i.span).unwrap_or(call_span),
);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
if let Some(e) = error {
self.note_type_err(
Expand All @@ -695,14 +701,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

self.emit_coerce_suggestions(
&mut err,
&provided_args[input_idx],
final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
None,
None,
);
if let Some(expr) = provided_args.get(input_idx) {
self.emit_coerce_suggestions(
&mut err,
&expr,
final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
None,
None,
);
}
}
Error::Extra(arg_idx) => {
let arg_type = if let Some((_, ty)) = final_arg_types[arg_idx] {
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/argument-suggestions/issue-96638.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn f(_: usize, _: &usize, _: usize) {}

fn arg<T>() -> T { todo!() }

fn main() {
let x = arg(); // `x` must be inferred
// The reference on `&x` is important to reproduce the ICE
f(&x, ""); //~ ERROR this function takes 3 arguments but 2 arguments were supplied
}
19 changes: 19 additions & 0 deletions src/test/ui/argument-suggestions/issue-96638.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> $DIR/issue-96638.rs:8:5
|
LL | f(&x, "");
| ^ -- an argument of type `usize` is missing
|
note: function defined here
--> $DIR/issue-96638.rs:1:4
|
LL | fn f(_: usize, _: &usize, _: usize) {}
| ^ -------- --------- --------
help: provide the argument
|
LL | f({usize}, &x, {usize});
| ~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to previous error

For more information about this error, try `rustc --explain E0061`.

0 comments on commit 279d801

Please sign in to comment.