Refer to uninferred const params by their name, instead of { _: _ }

When the value of a const param isn't inferred, replace it with the
param name from the definition.
This commit is contained in:
Esteban Kuber 2021-11-08 20:32:17 +00:00
parent 78e88f46d6
commit 3fd15c8404
3 changed files with 27 additions and 8 deletions

View File

@ -1,6 +1,5 @@
use crate::infer::type_variable::TypeVariableOriginKind;
use crate::infer::InferCtxt;
use crate::rustc_middle::ty::TypeFoldable;
use crate::infer::{InferCtxt, Symbol};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace};
@ -938,8 +937,17 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
let substs: Vec<_> = substs
.iter()
.zip(generics.params.iter())
.map(|(subst, param)| match &param.kind {
ty::GenericParamDefKind::Type { has_default: true, .. } => subst,
.map(|(subst, param)| match &(subst.unpack(), &param.kind) {
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
(crate::infer::GenericArgKind::Const(c), _) => {
match c.val {
ty::ConstKind::Infer(..) => {
// Replace not yet inferred const params with their def name.
self.tcx().mk_const_param(param.index, param.name, c.ty).into()
}
_ => subst,
}
}
_ => subst.super_fold_with(self),
})
.collect();
@ -977,8 +985,19 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
| ty::FnPtr(_)
| ty::Opaque(..)
| ty::Projection(_)
| ty::Never
| ty::Array(..) => t.super_fold_with(self),
| ty::Never => t.super_fold_with(self),
ty::Array(ty, c) => {
self.tcx().mk_ty(ty::Array(
self.fold_ty(ty),
match c.val {
ty::ConstKind::Infer(..) => {
// Replace not yet inferred const params with their def name.
self.tcx().mk_const_param(0, Symbol::intern("N"), c.ty).into()
}
_ => c,
},
))
}
// We don't want to hide type params that haven't been resolved yet.
// This would be the type that will be written out with the type param
// name in the output.

View File

@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>`
LL | let foo = Foo::foo();
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
| |
| consider giving `foo` the explicit type `Foo<{_: _}>`, where the type parameter `N` is specified
| consider giving `foo` the explicit type `Foo<N>`, where the type parameter `N` is specified
error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]`
LL | let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
| - ^^^ cannot infer the value of const parameter `N` declared on the function `foo`
| |
| consider giving this pattern the explicit type `[_; _]`, where the type parameter `N` is specified
| consider giving this pattern the explicit type `[_; N]`, where the type parameter `N` is specified
error: aborting due to previous error