1
Fork 0

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::type_variable::TypeVariableOriginKind;
use crate::infer::InferCtxt; use crate::infer::{InferCtxt, Symbol};
use crate::rustc_middle::ty::TypeFoldable;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def::{DefKind, Namespace};
@ -938,8 +937,17 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
let substs: Vec<_> = substs let substs: Vec<_> = substs
.iter() .iter()
.zip(generics.params.iter()) .zip(generics.params.iter())
.map(|(subst, param)| match &param.kind { .map(|(subst, param)| match &(subst.unpack(), &param.kind) {
ty::GenericParamDefKind::Type { has_default: true, .. } => subst, (_, 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), _ => subst.super_fold_with(self),
}) })
.collect(); .collect();
@ -977,8 +985,19 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
| ty::FnPtr(_) | ty::FnPtr(_)
| ty::Opaque(..) | ty::Opaque(..)
| ty::Projection(_) | ty::Projection(_)
| ty::Never | ty::Never => t.super_fold_with(self),
| ty::Array(..) => 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. // 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 // This would be the type that will be written out with the type param
// name in the output. // name in the output.

View file

@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>`
LL | let foo = Foo::foo(); LL | let foo = Foo::foo();
| --- ^^^^^^^^ cannot infer the value of const parameter `N` | --- ^^^^^^^^ 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 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");`! LL | let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
| - ^^^ cannot infer the value of const parameter `N` declared on the function `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 error: aborting due to previous error