Skip to content

Commit

Permalink
Auto merge of #89862 - lcnr:path-generics-diagnostics, r=estebank
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Jun 3, 2022
2 parents 72f7e31 + b343a46 commit e40d5e8
Show file tree
Hide file tree
Showing 124 changed files with 2,132 additions and 1,481 deletions.
1,715 changes: 829 additions & 886 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(try_blocks)]
#![recursion_limit = "512"] // For rustdoc

#[macro_use]
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,11 @@ impl<'hir> Map<'hir> {
Node::AnonConst(constant) => self.body(constant.body).value.span,
Node::Expr(expr) => expr.span,
Node::Stmt(stmt) => stmt.span,
Node::PathSegment(seg) => seg.ident.span,
Node::PathSegment(seg) => {
let ident_span = seg.ident.span;
ident_span
.with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
}
Node::Ty(ty) => ty.span,
Node::TraitRef(tr) => tr.path.span,
Node::Binding(pat) => pat.span,
Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@ impl GenericParamDef {
bug!("cannot convert a non-lifetime parameter def to an early bound region")
}
}

pub fn has_default(&self) -> bool {
match self.kind {
GenericParamDefKind::Type { has_default, .. }
| GenericParamDefKind::Const { has_default } => has_default,
GenericParamDefKind::Lifetime => false,
}
}

pub fn default_value<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
match self.kind {
GenericParamDefKind::Type { has_default, .. } if has_default => {
Some(EarlyBinder(tcx.type_of(self.def_id).into()))
}
GenericParamDefKind::Const { has_default } if has_default => {
Some(EarlyBinder(tcx.const_param_default(self.def_id).into()))
}
_ => None,
}
}
}

#[derive(Default)]
Expand Down Expand Up @@ -204,6 +227,12 @@ impl<'tcx> Generics {
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
})
}

/// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
let own = &substs[self.parent_count..][..self.params.len()];
if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
}
}

/// Bounds on generics.
Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/array-slice-vec/infer_array_len.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ error[E0282]: type annotations needed
--> $DIR/infer_array_len.rs:19:9
|
LL | let [_, _] = a.into();
| ^^^^^^ consider giving this pattern a type
| ^^^^^^
|
= note: type must be known at this point
help: consider giving this pattern a type
|
LL | let [_, _]: _ = a.into();
| +++

error: aborting due to previous error

Expand Down
11 changes: 7 additions & 4 deletions src/test/ui/array-slice-vec/vector-no-ann.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
error[E0282]: type annotations needed for `Vec<T>`
--> $DIR/vector-no-ann.rs:2:16
--> $DIR/vector-no-ann.rs:2:9
|
LL | let _foo = Vec::new();
| ---- ^^^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving `_foo` the explicit type `Vec<T>`, where the type parameter `T` is specified
| ^^^^
|
help: consider giving `_foo` an explicit type, where the type for type parameter `T` is specified
|
LL | let _foo: Vec<T> = Vec::new();
| ++++++++

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27
|
LL | with_closure(|x: u32, y| {});
| ^ consider giving this closure parameter a type
| ^
|
help: consider giving this closure parameter an explicit type
|
LL | with_closure(|x: u32, y: B| {});
| +++

error: aborting due to previous error

Expand Down
7 changes: 6 additions & 1 deletion src/test/ui/closures/issue-52437.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ error[E0282]: type annotations needed
--> $DIR/issue-52437.rs:2:30
|
LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
| ^ consider giving this closure parameter a type
| ^
|
help: consider giving this closure parameter an explicit type
|
LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
| +++

error[E0308]: mismatched types
--> $DIR/issue-52437.rs:2:5
Expand Down
11 changes: 7 additions & 4 deletions src/test/ui/const-generics/defaults/doesnt_infer.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
error[E0282]: type annotations needed for `Foo<N>`
--> $DIR/doesnt_infer.rs:11:15
--> $DIR/doesnt_infer.rs:11:9
|
LL | let foo = Foo::foo();
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
| |
| consider giving `foo` the explicit type `Foo<N>`, where the const parameter `N` is specified
| ^^^
|
help: consider giving `foo` an explicit type, where the the value of const parameter `N` is specified
|
LL | let foo: Foo<N> = Foo::foo();
| ++++++++

error: aborting due to previous error

Expand Down
10 changes: 6 additions & 4 deletions src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
error[E0283]: type annotations needed for `Mask<_, LANES>`
--> $DIR/issue-91614.rs:6:13
--> $DIR/issue-91614.rs:6:9
|
LL | let y = Mask::<_, _>::splat(false);
| - ^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving `y` the explicit type `Mask<_, LANES>`, where the type parameter `T` is specified
| ^
|
= note: cannot satisfy `_: MaskElement`
note: required by a bound in `Mask::<T, LANES>::splat`
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
|
LL | T: MaskElement,
| ^^^^^^^^^^^ required by this bound in `Mask::<T, LANES>::splat`
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
LL | let y: Mask<_, LANES> = Mask::<_, _>::splat(false);
| ++++++++++++++++

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ error[E0282]: type annotations needed
--> $DIR/const_eval_resolve_canonical.rs:26:9
|
LL | let mut _q = Default::default();
| ^^^^^^ consider giving `_q` a type
| ^^^^^^
|
help: consider giving `_q` an explicit type
|
LL | let mut _q: _ = Default::default();
| +++

error[E0283]: type annotations needed
--> $DIR/const_eval_resolve_canonical.rs:29:10
|
LL | _q = foo::<_, 2>(_q);
| ^^^^^^^^^^^ cannot infer type
| ^^^^^^^^^^^ cannot infer the value of the constant `{ N + 1 }`
|
note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found
--> $DIR/const_eval_resolve_canonical.rs:8:1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:6:5
|
LL | foo();
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
| ^^^ cannot infer the value of the const parameter `X` declared on the function `foo`
|
help: consider specifying the const argument
help: consider specifying the generic argument
|
LL | foo::<X>();
| ~~~~~~~~
| +++++

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/const-generics/infer/issue-77092.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/issue-77092.rs:11:26
|
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut`
|
help: consider specifying the const argument
help: consider specifying the generic arguments
|
LL | println!("{:?}", take_array_from_mut::<N>(&mut arr, i));
| ~~~~~~~~~~~~~~~~~~~~~~~~
LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i));
| ++++++++++

error: aborting due to previous error

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/const-generics/infer/method-chain.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/method-chain.rs:15:33
|
LL | Foo.bar().bar().bar().bar().baz();
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
| ^^^ cannot infer the value of the const parameter `N` declared on the associated function `baz`
|
help: consider specifying the const argument
help: consider specifying the generic argument
|
LL | Foo.bar().bar().bar().bar().baz::<N>();
| ~~~~~~~~
| +++++

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/const-generics/infer/one-param-uninferred.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/one-param-uninferred.rs:9:23
|
LL | let _: [u8; 17] = foo();
| ^^^ cannot infer the value of const parameter `M` declared on the function `foo`
| ^^^ cannot infer the value of the const parameter `M` declared on the function `foo`
|
help: consider specifying the const argument
help: consider specifying the generic arguments
|
LL | let _: [u8; 17] = foo::<M>();
| ~~~~~~~~
LL | let _: [u8; 17] = foo::<17_usize, M>();
| +++++++++++++++

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/const-generics/infer/uninferred-consts.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/uninferred-consts.rs:9:9
|
LL | Foo.foo();
| ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
| ^^^ cannot infer the value of the const parameter `A` declared on the associated function `foo`
|
help: consider specifying the const argument
help: consider specifying the generic arguments
|
LL | Foo.foo::<A>();
| ~~~~~~~~
LL | Foo.foo::<A, B>();
| ++++++++

error: aborting due to previous error

Expand Down
13 changes: 5 additions & 8 deletions src/test/ui/const-generics/issues/issue-83249.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
error[E0282]: type annotations needed
--> $DIR/issue-83249.rs:19:13
--> $DIR/issue-83249.rs:19:9
|
LL | let _ = foo([0; 1]);
| - ^^^ cannot infer type for type parameter `T` declared on the function `foo`
| |
| consider giving this pattern a type
| ^
|
help: type parameter declared here
--> $DIR/issue-83249.rs:12:8
help: consider giving this pattern a type
|
LL | fn foo<T: Foo>(_: [u8; T::N]) -> T {
| ^
LL | let _: _ = foo([0; 1]);
| +++

error: aborting due to previous error

Expand Down
18 changes: 8 additions & 10 deletions src/test/ui/consts/issue-64662.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@ error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:2:9
|
LL | A = foo(),
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
|
help: type parameter declared here
--> $DIR/issue-64662.rs:6:14
help: consider specifying the generic argument
|
LL | const fn foo<T>() -> isize {
| ^
LL | A = foo::<T>(),
| +++++

error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:3:9
|
LL | B = foo(),
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
|
help: type parameter declared here
--> $DIR/issue-64662.rs:6:14
help: consider specifying the generic argument
|
LL | const fn foo<T>() -> isize {
| ^
LL | B = foo::<T>(),
| +++++

error: aborting due to 2 previous errors

Expand Down
7 changes: 6 additions & 1 deletion src/test/ui/error-codes/E0282.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ error[E0282]: type annotations needed
--> $DIR/E0282.rs:2:9
|
LL | let x = "hello".chars().rev().collect();
| ^ consider giving `x` a type
| ^
|
help: consider giving `x` an explicit type
|
LL | let x: _ = "hello".chars().rev().collect();
| +++

error: aborting due to previous error

Expand Down
11 changes: 4 additions & 7 deletions src/test/ui/error-codes/E0283.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ error[E0283]: type annotations needed
--> $DIR/E0283.rs:35:24
|
LL | let bar = foo_impl.into() * 1u32;
| ---------^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `Into`
| this method call resolves to `T`
| ^^^^
|
note: multiple `impl`s satisfying `Impl: Into<_>` found
--> $DIR/E0283.rs:17:1
Expand All @@ -23,10 +20,10 @@ LL | impl Into<u32> for Impl {
= note: and another `impl` found in the `core` crate:
- impl<T, U> Into<U> for T
where U: From<T>;
help: use the fully qualified path for the potential candidate
help: try using a fully qualified path to specify the expected types
|
LL | let bar = <Impl as Into<u32>>::into(foo_impl) * 1u32;
| ++++++++++++++++++++++++++ ~
LL | let bar = <Impl as Into<T>>::into(foo_impl) * 1u32;
| ++++++++++++++++++++++++ ~

error: aborting due to 2 previous errors

Expand Down
9 changes: 4 additions & 5 deletions src/test/ui/error-codes/E0401.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ error[E0282]: type annotations needed
--> $DIR/E0401.rs:11:5
|
LL | bfnr(x);
| ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr`
| ^^^^ cannot infer type of the type parameter `U` declared on the function `bfnr`
|
help: type parameter declared here
--> $DIR/E0401.rs:4:13
help: consider specifying the generic arguments
|
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
| ^
LL | bfnr::<U, V, W>(x);
| +++++++++++

error: aborting due to 4 previous errors

Expand Down
Loading

0 comments on commit e40d5e8

Please sign in to comment.