Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -323,13 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut param_found = FxHashMap::default();
if self.can_eq(self.param_env, ty, found) {
// We only point at the first place where the found type was inferred.
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
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
// type, which we know already because of `can_eq` above was first
// inferred in this method call.
let arg = &args[i];
let arg_ty = self.node_ty(arg.hir_id);
if !arg.span.overlaps(mismatch_span) {
err.span_label(
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/type/type-check/point-at-inference-4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
struct S<A, B>(Option<(A, B)>);

impl<A, B> S<A, B> {
fn infer(&self, a: A, b: B) {}
//~^ NOTE associated function defined here
//~| NOTE
//~| NOTE
}

fn main() {
let s = S(None);
s.infer(0i32);
//~^ ERROR this method takes 2 arguments but 1 argument was supplied
//~| NOTE an argument is missing
//~| HELP provide the argument
let t: S<u32, _> = s;
//~^ ERROR mismatched types
//~| NOTE expected `S<u32, _>`, found `S<i32, _>`
//~| NOTE expected due to this
//~| NOTE expected struct `S<u32, _>`
}
31 changes: 31 additions & 0 deletions tests/ui/type/type-check/point-at-inference-4.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
error[E0061]: this method takes 2 arguments but 1 argument was supplied
--> $DIR/point-at-inference-4.rs:12:7
|
LL | s.infer(0i32);
| ^^^^^------ an argument is missing
|
note: associated function defined here
--> $DIR/point-at-inference-4.rs:4:8
|
LL | fn infer(&self, a: A, b: B) {}
| ^^^^^ ---- ----
help: provide the argument
|
LL | s.infer(0i32, /* b */);
| ~~~~~~~~~~~~~~~

error[E0308]: mismatched types
--> $DIR/point-at-inference-4.rs:16:24
|
LL | let t: S<u32, _> = s;
| --------- ^ expected `S<u32, _>`, found `S<i32, _>`
| |
| expected due to this
|
= note: expected struct `S<u32, _>`
found struct `S<i32, _>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0061, E0308.
For more information about an error, try `rustc --explain E0061`.