Skip to content

Commit 7bfccb3

Browse files
authored
Rollup merge of #108687 - compiler-errors:reformulate-point_at_expr_source_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`
2 parents 660c966 + 5cc4757 commit 7bfccb3

12 files changed

+257
-221
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+220-186
Large diffs are not rendered by default.

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
472472
err_code: &str,
473473
fn_def_id: Option<DefId>,
474474
call_span: Span,
475-
call_expr: &hir::Expr<'tcx>,
475+
call_expr: &'tcx hir::Expr<'tcx>,
476476
) {
477477
// Next, let's construct the error
478478
let (error_span, full_call_span, call_name, is_method) = match &call_expr.kind {
@@ -807,24 +807,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
807807
full_call_span,
808808
format!("arguments to this {} are incorrect", call_name),
809809
);
810-
if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) =
811-
(callee_ty, &call_expr.kind)
810+
811+
if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind
812+
&& provided_idx.as_usize() == expected_idx.as_usize()
812813
{
813-
// Type that would have accepted this argument if it hadn't been inferred earlier.
814-
// FIXME: We leave an inference variable for now, but it'd be nice to get a more
815-
// specific type to increase the accuracy of the diagnostic.
816-
let expected = self.infcx.next_ty_var(TypeVariableOrigin {
817-
kind: TypeVariableOriginKind::MiscVariable,
818-
span: full_call_span,
819-
});
820-
self.point_at_expr_source_of_inferred_type(
814+
self.note_source_of_type_mismatch_constraint(
821815
&mut err,
822816
rcvr,
823-
expected,
824-
callee_ty,
825-
provided_arg_span,
817+
crate::demand::TypeMismatchSource::Arg {
818+
call_expr,
819+
incompatible_arg: provided_idx.as_usize(),
820+
},
826821
);
827822
}
823+
828824
// Call out where the function is defined
829825
self.label_fn_like(
830826
&mut err,

tests/ui/type/type-check/assignment-in-if.stderr

-9
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ LL | x == 5
6767
error[E0308]: mismatched types
6868
--> $DIR/assignment-in-if.rs:44:18
6969
|
70-
LL | if y = (Foo { foo: x }) {
71-
| - here the type of `x` is inferred to be `usize`
72-
...
7370
LL | if x == x && x = x && x == x {
7471
| ------ ^ expected `bool`, found `usize`
7572
| |
@@ -78,9 +75,6 @@ LL | if x == x && x = x && x == x {
7875
error[E0308]: mismatched types
7976
--> $DIR/assignment-in-if.rs:44:22
8077
|
81-
LL | if y = (Foo { foo: x }) {
82-
| - here the type of `x` is inferred to be `usize`
83-
...
8478
LL | if x == x && x = x && x == x {
8579
| ^ expected `bool`, found `usize`
8680

@@ -98,9 +92,6 @@ LL | if x == x && x == x && x == x {
9892
error[E0308]: mismatched types
9993
--> $DIR/assignment-in-if.rs:51:28
10094
|
101-
LL | if y = (Foo { foo: x }) {
102-
| - here the type of `x` is inferred to be `usize`
103-
...
10495
LL | if x == x && x == x && x = x {
10596
| ---------------- ^ expected `bool`, found `usize`
10697
| |

tests/ui/type/type-check/point-at-inference-3.fixed

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
fn main() {
33
let mut v = Vec::new();
44
v.push(0i32);
5-
//~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
5+
//~^ NOTE this argument has type `i32`...
6+
//~| NOTE ... which causes `v` to have type `Vec<i32>`
67
v.push(0);
78
v.push(1i32); //~ ERROR mismatched types
89
//~^ NOTE expected `i32`, found `u32`

tests/ui/type/type-check/point-at-inference-3.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
fn main() {
33
let mut v = Vec::new();
44
v.push(0i32);
5-
//~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
5+
//~^ NOTE this argument has type `i32`...
6+
//~| NOTE ... which causes `v` to have type `Vec<i32>`
67
v.push(0);
78
v.push(1u32); //~ ERROR mismatched types
89
//~^ NOTE expected `i32`, found `u32`

tests/ui/type/type-check/point-at-inference-3.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0308]: mismatched types
2-
--> $DIR/point-at-inference-3.rs:7:12
2+
--> $DIR/point-at-inference-3.rs:8:12
33
|
44
LL | v.push(0i32);
5-
| ---- this is of type `i32`, which causes `v` to be inferred as `Vec<i32>`
5+
| - ---- this argument has type `i32`...
6+
| |
7+
| ... which causes `v` to have type `Vec<i32>`
68
...
79
LL | v.push(1u32);
810
| ---- ^^^^ expected `i32`, found `u32`

tests/ui/type/type-check/point-at-inference-4.rs

+3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ fn main() {
1111
let s = S(None);
1212
s.infer(0i32);
1313
//~^ ERROR this method takes 2 arguments but 1 argument was supplied
14+
//~| NOTE this argument has type `i32`...
15+
//~| NOTE ... which causes `s` to have type `S<i32, _>`
1416
//~| NOTE an argument is missing
1517
//~| HELP provide the argument
18+
//~| HELP change the type of the numeric literal from `i32` to `u32`
1619
let t: S<u32, _> = s;
1720
//~^ ERROR mismatched types
1821
//~| NOTE expected `S<u32, _>`, found `S<i32, _>`

tests/ui/type/type-check/point-at-inference-4.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@ LL | s.infer(0i32, /* b */);
1515
| ~~~~~~~~~~~~~~~
1616

1717
error[E0308]: mismatched types
18-
--> $DIR/point-at-inference-4.rs:16:24
18+
--> $DIR/point-at-inference-4.rs:19:24
1919
|
20+
LL | s.infer(0i32);
21+
| - ---- this argument has type `i32`...
22+
| |
23+
| ... which causes `s` to have type `S<i32, _>`
24+
...
2025
LL | let t: S<u32, _> = s;
2126
| --------- ^ expected `S<u32, _>`, found `S<i32, _>`
2227
| |
2328
| expected due to this
2429
|
2530
= note: expected struct `S<u32, _>`
2631
found struct `S<i32, _>`
32+
help: change the type of the numeric literal from `i32` to `u32`
33+
|
34+
LL | s.infer(0u32);
35+
| ~~~
2736

2837
error: aborting due to 2 previous errors
2938

tests/ui/type/type-check/point-at-inference.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/point-at-inference.rs:12:9
33
|
44
LL | foo.push(i);
5-
| - this is of type `&{integer}`, which causes `foo` to be inferred as `Vec<&{integer}>`
5+
| --- - this argument has type `&{integer}`...
6+
| |
7+
| ... which causes `foo` to have type `Vec<&{integer}>`
68
...
79
LL | bar(foo);
810
| --- ^^^ expected `Vec<i32>`, found `Vec<&{integer}>`

tests/ui/typeck/bad-type-in-vec-contains.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | primes.contains(3);
77
| | expected `&_`, found integer
88
| | help: consider borrowing here: `&3`
99
| arguments to this method are incorrect
10-
| here the type of `primes` is inferred to be `[_]`
1110
|
1211
= note: expected reference `&_`
1312
found type `{integer}`

tests/ui/typeck/bad-type-in-vec-push.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0308]: mismatched types
22
--> $DIR/bad-type-in-vec-push.rs:11:17
33
|
4-
LL | vector.sort();
5-
| ------ here the type of `vector` is inferred to be `Vec<_>`
64
LL | result.push(vector);
75
| ---- ^^^^^^ expected integer, found `Vec<_>`
86
| |

tests/ui/typeck/issue-107775.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-107775.rs:35:16
33
|
44
LL | map.insert(1, Struct::do_something);
5-
| - -------------------- 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::<'_>}>`
6-
| |
7-
| 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::<'_>}>`
5+
| --- -------------------- this argument has type `fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}`...
6+
| |
7+
| ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
88
LL | Self { map }
99
| ^^^ expected `HashMap<u16, fn(u8) -> Pin<...>>`, found `HashMap<{integer}, ...>`
1010
|

0 commit comments

Comments
 (0)