diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 6b9952ba5d6..56f0b5c1927 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -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 ¶m.kind { - ty::GenericParamDefKind::Type { has_default: true, .. } => subst, + .map(|(subst, param)| match &(subst.unpack(), ¶m.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. diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr index 183be1b1517..10cd491b480 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -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`, where the type parameter `N` is specified error: aborting due to previous error diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr index c66606b9c83..0746b2491fb 100644 --- a/src/test/ui/inference/issue-83606.stderr +++ b/src/test/ui/inference/issue-83606.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); //<- Do not suggest `foo::("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