Skip to content

Commit

Permalink
Rollup merge of #108687 - compiler-errors:reformulate-point_at_expr_s…
Browse files Browse the repository at this point in the history
…ource_of_inferred_type, r=oli-obk

Reformulate `point_at_expr_source_of_inferred_type` to be more accurate

Be more accurate when deducing where along the several usages of a binding it is constrained to be some type that is incompatible with an expectation.

This also renames the method to `note_source_of_type_mismatch_constraint` because I prefer that name, though I guess I can revert that. (Also drive-by rename `note_result_coercion` -> `suggest_coercing_result_via_try_operator`, because it's suggesting, not noting!)

This PR is (probably?) best reviewed per commit, but it does regress a bit only to fix it later on, so it could also be reviewed as a whole if that makes the final results more clear.

r? `@estebank`
  • Loading branch information
matthiaskrgr committed Apr 14, 2023
2 parents 660c966 + 5cc4757 commit 7bfccb3
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 221 deletions.
406 changes: 220 additions & 186 deletions compiler/rustc_hir_typeck/src/demand.rs

Large diffs are not rendered by default.

24 changes: 10 additions & 14 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err_code: &str,
fn_def_id: Option<DefId>,
call_span: Span,
call_expr: &hir::Expr<'tcx>,
call_expr: &'tcx hir::Expr<'tcx>,
) {
// Next, let's construct the error
let (error_span, full_call_span, call_name, is_method) = match &call_expr.kind {
Expand Down Expand Up @@ -807,24 +807,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
full_call_span,
format!("arguments to this {} are incorrect", call_name),
);
if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) =
(callee_ty, &call_expr.kind)

if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind
&& provided_idx.as_usize() == expected_idx.as_usize()
{
// Type that would have accepted this argument if it hadn't been inferred earlier.
// FIXME: We leave an inference variable for now, but it'd be nice to get a more
// specific type to increase the accuracy of the diagnostic.
let expected = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span: full_call_span,
});
self.point_at_expr_source_of_inferred_type(
self.note_source_of_type_mismatch_constraint(
&mut err,
rcvr,
expected,
callee_ty,
provided_arg_span,
crate::demand::TypeMismatchSource::Arg {
call_expr,
incompatible_arg: provided_idx.as_usize(),
},
);
}

// Call out where the function is defined
self.label_fn_like(
&mut err,
Expand Down
9 changes: 0 additions & 9 deletions tests/ui/type/type-check/assignment-in-if.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ LL | x == 5
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:44:18
|
LL | if y = (Foo { foo: x }) {
| - here the type of `x` is inferred to be `usize`
...
LL | if x == x && x = x && x == x {
| ------ ^ expected `bool`, found `usize`
| |
Expand All @@ -78,9 +75,6 @@ LL | if x == x && x = x && x == x {
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:44:22
|
LL | if y = (Foo { foo: x }) {
| - here the type of `x` is inferred to be `usize`
...
LL | if x == x && x = x && x == x {
| ^ expected `bool`, found `usize`

Expand All @@ -98,9 +92,6 @@ LL | if x == x && x == x && x == x {
error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:51:28
|
LL | if y = (Foo { foo: x }) {
| - here the type of `x` is inferred to be `usize`
...
LL | if x == x && x == x && x = x {
| ---------------- ^ expected `bool`, found `usize`
| |
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/type/type-check/point-at-inference-3.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
fn main() {
let mut v = Vec::new();
v.push(0i32);
//~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
//~^ NOTE this argument has type `i32`...
//~| NOTE ... which causes `v` to have type `Vec<i32>`
v.push(0);
v.push(1i32); //~ ERROR mismatched types
//~^ NOTE expected `i32`, found `u32`
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/type/type-check/point-at-inference-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
fn main() {
let mut v = Vec::new();
v.push(0i32);
//~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
//~^ NOTE this argument has type `i32`...
//~| NOTE ... which causes `v` to have type `Vec<i32>`
v.push(0);
v.push(1u32); //~ ERROR mismatched types
//~^ NOTE expected `i32`, found `u32`
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/type/type-check/point-at-inference-3.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0308]: mismatched types
--> $DIR/point-at-inference-3.rs:7:12
--> $DIR/point-at-inference-3.rs:8:12
|
LL | v.push(0i32);
| ---- this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
| - ---- this argument has type `i32`...
| |
| ... which causes `v` to have type `Vec<i32>`
...
LL | v.push(1u32);
| ---- ^^^^ expected `i32`, found `u32`
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/type/type-check/point-at-inference-4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ fn main() {
let s = S(None);
s.infer(0i32);
//~^ ERROR this method takes 2 arguments but 1 argument was supplied
//~| NOTE this argument has type `i32`...
//~| NOTE ... which causes `s` to have type `S<i32, _>`
//~| NOTE an argument is missing
//~| HELP provide the argument
//~| HELP change the type of the numeric literal from `i32` to `u32`
let t: S<u32, _> = s;
//~^ ERROR mismatched types
//~| NOTE expected `S<u32, _>`, found `S<i32, _>`
Expand Down
11 changes: 10 additions & 1 deletion tests/ui/type/type-check/point-at-inference-4.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,24 @@ LL | s.infer(0i32, /* b */);
| ~~~~~~~~~~~~~~~

error[E0308]: mismatched types
--> $DIR/point-at-inference-4.rs:16:24
--> $DIR/point-at-inference-4.rs:19:24
|
LL | s.infer(0i32);
| - ---- this argument has type `i32`...
| |
| ... which causes `s` to have type `S<i32, _>`
...
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, _>`
help: change the type of the numeric literal from `i32` to `u32`
|
LL | s.infer(0u32);
| ~~~

error: aborting due to 2 previous errors

Expand Down
4 changes: 3 additions & 1 deletion tests/ui/type/type-check/point-at-inference.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ error[E0308]: mismatched types
--> $DIR/point-at-inference.rs:12:9
|
LL | foo.push(i);
| - this is of type `&{integer}`, which causes `foo` to be inferred as `Vec<&{integer}>`
| --- - this argument has type `&{integer}`...
| |
| ... which causes `foo` to have type `Vec<&{integer}>`
...
LL | bar(foo);
| --- ^^^ expected `Vec<i32>`, found `Vec<&{integer}>`
Expand Down
1 change: 0 additions & 1 deletion tests/ui/typeck/bad-type-in-vec-contains.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ LL | primes.contains(3);
| | expected `&_`, found integer
| | help: consider borrowing here: `&3`
| arguments to this method are incorrect
| here the type of `primes` is inferred to be `[_]`
|
= note: expected reference `&_`
found type `{integer}`
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/typeck/bad-type-in-vec-push.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
error[E0308]: mismatched types
--> $DIR/bad-type-in-vec-push.rs:11:17
|
LL | vector.sort();
| ------ here the type of `vector` is inferred to be `Vec<_>`
LL | result.push(vector);
| ---- ^^^^^^ expected integer, found `Vec<_>`
| |
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/typeck/issue-107775.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ error[E0308]: mismatched types
--> $DIR/issue-107775.rs:35:16
|
LL | map.insert(1, Struct::do_something);
| - -------------------- this is of type `fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}`, which causes `map` to be inferred as `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
| |
| this is of type `{integer}`, which causes `map` to be inferred as `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
| --- -------------------- this argument has type `fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}`...
| |
| ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
LL | Self { map }
| ^^^ expected `HashMap<u16, fn(u8) -> Pin<...>>`, found `HashMap<{integer}, ...>`
|
Expand Down

0 comments on commit 7bfccb3

Please sign in to comment.