diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 16d3115c233..79b3c0590b6 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -298,6 +298,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // call's arguments and we can provide a more explicit span. let sig = self.tcx.fn_sig(def_id).subst_identity(); let def_self_ty = sig.input(0).skip_binder(); + let param_tys = sig.inputs().skip_binder().iter().skip(1); + // If there's an arity mismatch, pointing out the call as the source of an inference + // can be misleading, so we skip it. + if param_tys.len() != args.len() { + continue; + } let rcvr_ty = self.node_ty(rcvr.hir_id); // Get the evaluated type *after* calling the method call, so that the influence // of the arguments can be reflected in the receiver type. The receiver @@ -323,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut param_found = FxHashMap::default(); if self.can_eq(self.param_env, ty, found).is_ok() { // We only point at the first place where the found type was inferred. - for (param_ty, arg) in sig.inputs().skip_binder().iter().skip(1).zip(args) { + for (param_ty, arg) in param_tys.zip(args) { if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { // We found an argument that references a type parameter in `Self`, // so we assume that this is the argument that caused the found diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index 647c7d622fa..7903e9e83cf 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -13,8 +13,6 @@ fn main() { //~^ ERROR this method takes 2 arguments but 1 argument was supplied //~| NOTE an argument is missing //~| HELP provide the argument - //~| NOTE this is of type `i32`, which causes `s` to be inferred as `S` - //~| HELP change the type of the numeric literal from `i32` to `u32` let t: S = s; //~^ ERROR mismatched types //~| NOTE expected `S`, found `S` diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 62e798e56f7..fac9701e4a1 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -15,11 +15,8 @@ LL | s.infer(0i32, /* b */); | ~~~~~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/point-at-inference-4.rs:18:24 + --> $DIR/point-at-inference-4.rs:16:24 | -LL | s.infer(0i32); - | ---- this is of type `i32`, which causes `s` to be inferred as `S` -... LL | let t: S = s; | --------- ^ expected `S`, found `S` | | @@ -27,10 +24,6 @@ LL | let t: S = s; | = note: expected struct `S` found struct `S` -help: change the type of the numeric literal from `i32` to `u32` - | -LL | s.infer(0u32); - | ~~~ error: aborting due to 2 previous errors