Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite error handling for unresolved inference vars #89862

Merged
merged 7 commits into from Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
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
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()))
}
Comment on lines +986 to +990
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would guess that the only thing which may impact the amount of process_obligations would be this.

We now use a different span from seg.ident which may mean that we don't dedup obligations as readily as they now have different spans? Can try to take a deeper look at this in the near future

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
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
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
@@ -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
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
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
@@ -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
@@ -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);
| ++++++++++++++++
Comment on lines +13 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a shame that it is _ and not T here, but that shouldn't block this PR from landing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the reason for that is unfortunate:

  • we have the inference var which is the input, that one has T as its origin
  • that inference var is unified with ?0 in Mask<?0, _> which doesn't have T as its origin. Going to add this to Tracking Issue for post #89862 cleanup #94483


error: aborting due to previous error

Expand Down
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
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>();
| ~~~~~~~~
| +++++
Comment on lines +7 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm realizing that this message should mention what type X is and/or point at the foo definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added to #94483


error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/const-generics/infer/issue-77092.stderr
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
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
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
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
@@ -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
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
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
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
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