Skip to content

Commit e40d5e8

Browse files
committed
Auto merge of #89862 - lcnr:path-generics-diagnostics, r=estebank
rewrite error handling for unresolved inference vars Pretty much completely rewrites `fn emit_inference_failure_err`. This new setup should hopefully be easier to extend and is already a lot better when looking for generic arguments. Because this is a rewrite there are still some parts which are lacking, these are tracked in #94483 and will be fixed in later PRs. r? `@estebank` `@petrochenkov`
2 parents 72f7e31 + b343a46 commit e40d5e8

File tree

124 files changed

+2132
-1481
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+2132
-1481
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+829-886
Large diffs are not rendered by default.

compiler/rustc_infer/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(let_else)]
2323
#![feature(min_specialization)]
2424
#![feature(never_type)]
25+
#![feature(try_blocks)]
2526
#![recursion_limit = "512"] // For rustdoc
2627

2728
#[macro_use]

compiler/rustc_middle/src/hir/map/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,11 @@ impl<'hir> Map<'hir> {
983983
Node::AnonConst(constant) => self.body(constant.body).value.span,
984984
Node::Expr(expr) => expr.span,
985985
Node::Stmt(stmt) => stmt.span,
986-
Node::PathSegment(seg) => seg.ident.span,
986+
Node::PathSegment(seg) => {
987+
let ident_span = seg.ident.span;
988+
ident_span
989+
.with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
990+
}
987991
Node::Ty(ty) => ty.span,
988992
Node::TraitRef(tr) => tr.path.span,
989993
Node::Binding(pat) => pat.span,

compiler/rustc_middle/src/ty/generics.rs

+29
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,29 @@ impl GenericParamDef {
6363
bug!("cannot convert a non-lifetime parameter def to an early bound region")
6464
}
6565
}
66+
67+
pub fn has_default(&self) -> bool {
68+
match self.kind {
69+
GenericParamDefKind::Type { has_default, .. }
70+
| GenericParamDefKind::Const { has_default } => has_default,
71+
GenericParamDefKind::Lifetime => false,
72+
}
73+
}
74+
75+
pub fn default_value<'tcx>(
76+
&self,
77+
tcx: TyCtxt<'tcx>,
78+
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
79+
match self.kind {
80+
GenericParamDefKind::Type { has_default, .. } if has_default => {
81+
Some(EarlyBinder(tcx.type_of(self.def_id).into()))
82+
}
83+
GenericParamDefKind::Const { has_default } if has_default => {
84+
Some(EarlyBinder(tcx.const_param_default(self.def_id).into()))
85+
}
86+
_ => None,
87+
}
88+
}
6689
}
6790

6891
#[derive(Default)]
@@ -204,6 +227,12 @@ impl<'tcx> Generics {
204227
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
205228
})
206229
}
230+
231+
/// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
232+
pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
233+
let own = &substs[self.parent_count..][..self.params.len()];
234+
if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
235+
}
207236
}
208237

209238
/// Bounds on generics.

src/test/ui/array-slice-vec/infer_array_len.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ error[E0282]: type annotations needed
22
--> $DIR/infer_array_len.rs:19:9
33
|
44
LL | let [_, _] = a.into();
5-
| ^^^^^^ consider giving this pattern a type
5+
| ^^^^^^
66
|
77
= note: type must be known at this point
8+
help: consider giving this pattern a type
9+
|
10+
LL | let [_, _]: _ = a.into();
11+
| +++
812

913
error: aborting due to previous error
1014

src/test/ui/array-slice-vec/vector-no-ann.stderr

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error[E0282]: type annotations needed for `Vec<T>`
2-
--> $DIR/vector-no-ann.rs:2:16
2+
--> $DIR/vector-no-ann.rs:2:9
33
|
44
LL | let _foo = Vec::new();
5-
| ---- ^^^^^^^^ cannot infer type for type parameter `T`
6-
| |
7-
| consider giving `_foo` the explicit type `Vec<T>`, where the type parameter `T` is specified
5+
| ^^^^
6+
|
7+
help: consider giving `_foo` an explicit type, where the type for type parameter `T` is specified
8+
|
9+
LL | let _foo: Vec<T> = Vec::new();
10+
| ++++++++
811

912
error: aborting due to previous error
1013

src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27
33
|
44
LL | with_closure(|x: u32, y| {});
5-
| ^ consider giving this closure parameter a type
5+
| ^
6+
|
7+
help: consider giving this closure parameter an explicit type
8+
|
9+
LL | with_closure(|x: u32, y: B| {});
10+
| +++
611

712
error: aborting due to previous error
813

src/test/ui/closures/issue-52437.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ error[E0282]: type annotations needed
88
--> $DIR/issue-52437.rs:2:30
99
|
1010
LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
11-
| ^ consider giving this closure parameter a type
11+
| ^
12+
|
13+
help: consider giving this closure parameter an explicit type
14+
|
15+
LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
16+
| +++
1217

1318
error[E0308]: mismatched types
1419
--> $DIR/issue-52437.rs:2:5

src/test/ui/const-generics/defaults/doesnt_infer.stderr

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
error[E0282]: type annotations needed for `Foo<N>`
2-
--> $DIR/doesnt_infer.rs:11:15
2+
--> $DIR/doesnt_infer.rs:11:9
33
|
44
LL | let foo = Foo::foo();
5-
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
6-
| |
7-
| consider giving `foo` the explicit type `Foo<N>`, where the const parameter `N` is specified
5+
| ^^^
6+
|
7+
help: consider giving `foo` an explicit type, where the the value of const parameter `N` is specified
8+
|
9+
LL | let foo: Foo<N> = Foo::foo();
10+
| ++++++++
811

912
error: aborting due to previous error
1013

src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
error[E0283]: type annotations needed for `Mask<_, LANES>`
2-
--> $DIR/issue-91614.rs:6:13
2+
--> $DIR/issue-91614.rs:6:9
33
|
44
LL | let y = Mask::<_, _>::splat(false);
5-
| - ^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
6-
| |
7-
| consider giving `y` the explicit type `Mask<_, LANES>`, where the type parameter `T` is specified
5+
| ^
86
|
97
= note: cannot satisfy `_: MaskElement`
108
note: required by a bound in `Mask::<T, LANES>::splat`
119
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
1210
|
1311
LL | T: MaskElement,
1412
| ^^^^^^^^^^^ required by this bound in `Mask::<T, LANES>::splat`
13+
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
14+
|
15+
LL | let y: Mask<_, LANES> = Mask::<_, _>::splat(false);
16+
| ++++++++++++++++
1517

1618
error: aborting due to previous error
1719

src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ error[E0282]: type annotations needed
22
--> $DIR/const_eval_resolve_canonical.rs:26:9
33
|
44
LL | let mut _q = Default::default();
5-
| ^^^^^^ consider giving `_q` a type
5+
| ^^^^^^
6+
|
7+
help: consider giving `_q` an explicit type
8+
|
9+
LL | let mut _q: _ = Default::default();
10+
| +++
611

712
error[E0283]: type annotations needed
813
--> $DIR/const_eval_resolve_canonical.rs:29:10
914
|
1015
LL | _q = foo::<_, 2>(_q);
11-
| ^^^^^^^^^^^ cannot infer type
16+
| ^^^^^^^^^^^ cannot infer the value of the constant `{ N + 1 }`
1217
|
1318
note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found
1419
--> $DIR/const_eval_resolve_canonical.rs:8:1

src/test/ui/const-generics/infer/cannot-infer-const-args.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/cannot-infer-const-args.rs:6:5
33
|
44
LL | foo();
5-
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
5+
| ^^^ cannot infer the value of the const parameter `X` declared on the function `foo`
66
|
7-
help: consider specifying the const argument
7+
help: consider specifying the generic argument
88
|
99
LL | foo::<X>();
10-
| ~~~~~~~~
10+
| +++++
1111

1212
error: aborting due to previous error
1313

src/test/ui/const-generics/infer/issue-77092.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-77092.rs:11:26
33
|
44
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
5-
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
5+
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut`
66
|
7-
help: consider specifying the const argument
7+
help: consider specifying the generic arguments
88
|
9-
LL | println!("{:?}", take_array_from_mut::<N>(&mut arr, i));
10-
| ~~~~~~~~~~~~~~~~~~~~~~~~
9+
LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i));
10+
| ++++++++++
1111

1212
error: aborting due to previous error
1313

src/test/ui/const-generics/infer/method-chain.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/method-chain.rs:15:33
33
|
44
LL | Foo.bar().bar().bar().bar().baz();
5-
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
5+
| ^^^ cannot infer the value of the const parameter `N` declared on the associated function `baz`
66
|
7-
help: consider specifying the const argument
7+
help: consider specifying the generic argument
88
|
99
LL | Foo.bar().bar().bar().bar().baz::<N>();
10-
| ~~~~~~~~
10+
| +++++
1111

1212
error: aborting due to previous error
1313

src/test/ui/const-generics/infer/one-param-uninferred.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/one-param-uninferred.rs:9:23
33
|
44
LL | let _: [u8; 17] = foo();
5-
| ^^^ cannot infer the value of const parameter `M` declared on the function `foo`
5+
| ^^^ cannot infer the value of the const parameter `M` declared on the function `foo`
66
|
7-
help: consider specifying the const argument
7+
help: consider specifying the generic arguments
88
|
9-
LL | let _: [u8; 17] = foo::<M>();
10-
| ~~~~~~~~
9+
LL | let _: [u8; 17] = foo::<17_usize, M>();
10+
| +++++++++++++++
1111

1212
error: aborting due to previous error
1313

src/test/ui/const-generics/infer/uninferred-consts.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/uninferred-consts.rs:9:9
33
|
44
LL | Foo.foo();
5-
| ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
5+
| ^^^ cannot infer the value of the const parameter `A` declared on the associated function `foo`
66
|
7-
help: consider specifying the const argument
7+
help: consider specifying the generic arguments
88
|
9-
LL | Foo.foo::<A>();
10-
| ~~~~~~~~
9+
LL | Foo.foo::<A, B>();
10+
| ++++++++
1111

1212
error: aborting due to previous error
1313

src/test/ui/const-generics/issues/issue-83249.stderr

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
error[E0282]: type annotations needed
2-
--> $DIR/issue-83249.rs:19:13
2+
--> $DIR/issue-83249.rs:19:9
33
|
44
LL | let _ = foo([0; 1]);
5-
| - ^^^ cannot infer type for type parameter `T` declared on the function `foo`
6-
| |
7-
| consider giving this pattern a type
5+
| ^
86
|
9-
help: type parameter declared here
10-
--> $DIR/issue-83249.rs:12:8
7+
help: consider giving this pattern a type
118
|
12-
LL | fn foo<T: Foo>(_: [u8; T::N]) -> T {
13-
| ^
9+
LL | let _: _ = foo([0; 1]);
10+
| +++
1411

1512
error: aborting due to previous error
1613

src/test/ui/consts/issue-64662.stderr

+8-10
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,23 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-64662.rs:2:9
33
|
44
LL | A = foo(),
5-
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
5+
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
66
|
7-
help: type parameter declared here
8-
--> $DIR/issue-64662.rs:6:14
7+
help: consider specifying the generic argument
98
|
10-
LL | const fn foo<T>() -> isize {
11-
| ^
9+
LL | A = foo::<T>(),
10+
| +++++
1211

1312
error[E0282]: type annotations needed
1413
--> $DIR/issue-64662.rs:3:9
1514
|
1615
LL | B = foo(),
17-
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
16+
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
1817
|
19-
help: type parameter declared here
20-
--> $DIR/issue-64662.rs:6:14
18+
help: consider specifying the generic argument
2119
|
22-
LL | const fn foo<T>() -> isize {
23-
| ^
20+
LL | B = foo::<T>(),
21+
| +++++
2422

2523
error: aborting due to 2 previous errors
2624

src/test/ui/error-codes/E0282.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/E0282.rs:2:9
33
|
44
LL | let x = "hello".chars().rev().collect();
5-
| ^ consider giving `x` a type
5+
| ^
6+
|
7+
help: consider giving `x` an explicit type
8+
|
9+
LL | let x: _ = "hello".chars().rev().collect();
10+
| +++
611

712
error: aborting due to previous error
813

src/test/ui/error-codes/E0283.stderr

+4-7
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ error[E0283]: type annotations needed
1010
--> $DIR/E0283.rs:35:24
1111
|
1212
LL | let bar = foo_impl.into() * 1u32;
13-
| ---------^^^^--
14-
| | |
15-
| | cannot infer type for type parameter `T` declared on the trait `Into`
16-
| this method call resolves to `T`
13+
| ^^^^
1714
|
1815
note: multiple `impl`s satisfying `Impl: Into<_>` found
1916
--> $DIR/E0283.rs:17:1
@@ -23,10 +20,10 @@ LL | impl Into<u32> for Impl {
2320
= note: and another `impl` found in the `core` crate:
2421
- impl<T, U> Into<U> for T
2522
where U: From<T>;
26-
help: use the fully qualified path for the potential candidate
23+
help: try using a fully qualified path to specify the expected types
2724
|
28-
LL | let bar = <Impl as Into<u32>>::into(foo_impl) * 1u32;
29-
| ++++++++++++++++++++++++++ ~
25+
LL | let bar = <Impl as Into<T>>::into(foo_impl) * 1u32;
26+
| ++++++++++++++++++++++++ ~
3027

3128
error: aborting due to 2 previous errors
3229

src/test/ui/error-codes/E0401.stderr

+4-5
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ error[E0282]: type annotations needed
3636
--> $DIR/E0401.rs:11:5
3737
|
3838
LL | bfnr(x);
39-
| ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr`
39+
| ^^^^ cannot infer type of the type parameter `U` declared on the function `bfnr`
4040
|
41-
help: type parameter declared here
42-
--> $DIR/E0401.rs:4:13
41+
help: consider specifying the generic arguments
4342
|
44-
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
45-
| ^
43+
LL | bfnr::<U, V, W>(x);
44+
| +++++++++++
4645

4746
error: aborting due to 4 previous errors
4847

0 commit comments

Comments
 (0)