Skip to content

Commit 8a08bef

Browse files
committed
Refer to const params as "const params" and not "type params"
1 parent d0d51ea commit 8a08bef

File tree

3 files changed

+48
-38
lines changed

3 files changed

+48
-38
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+46-36
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::hir::map::Map;
1010
use rustc_middle::infer::unify_key::ConstVariableOriginKind;
1111
use rustc_middle::ty::print::Print;
1212
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
13-
use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder};
13+
use rustc_middle::ty::{self, Const, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder};
1414
use rustc_span::symbol::kw;
1515
use rustc_span::Span;
1616
use std::borrow::Cow;
@@ -305,6 +305,15 @@ pub enum UnderspecifiedArgKind {
305305
Const { is_parameter: bool },
306306
}
307307

308+
impl UnderspecifiedArgKind {
309+
fn descr(&self) -> &'static str {
310+
match self {
311+
Self::Type { .. } => "type",
312+
Self::Const { .. } => "const",
313+
}
314+
}
315+
}
316+
308317
impl InferenceDiagnosticsData {
309318
/// Generate a label for a generic argument which can't be inferred. When not
310319
/// much is known about the argument, `use_diag` may be used to describe the
@@ -548,6 +557,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
548557
}
549558
}
550559

560+
let param_type = arg_data.kind.descr();
551561
let suffix = match local_visitor.found_node_ty {
552562
Some(ty) if ty.is_closure() => {
553563
let substs =
@@ -586,15 +596,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
586596
}
587597
Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => {
588598
let ty = ty_to_string(ty);
589-
format!("the explicit type `{}`, with the type parameters specified", ty)
599+
format!("the explicit type `{}`, with the {} parameters specified", ty, param_type)
590600
}
591601
Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => {
592602
let ty = ResolvedTypeParamEraser::new(self.tcx).fold_ty(ty);
593603
let ty = ErrTypeParamEraser(self.tcx).fold_ty(ty);
594604
let ty = ty_to_string(ty);
595605
format!(
596-
"the explicit type `{}`, where the type parameter `{}` is specified",
597-
ty, arg_data.name,
606+
"the explicit type `{}`, where the {} parameter `{}` is specified",
607+
ty, param_type, arg_data.name,
598608
)
599609
}
600610
_ => "a type".to_string(),
@@ -871,7 +881,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
871881
}
872882
}
873883

874-
/// Turn resolved type params into `[type error]` to signal we don't want to display them.
884+
/// Turn *resolved* type params into `[type error]` to signal we don't want to display them. After
885+
/// performing that replacement, we'll turn all remaining infer type params to use their name from
886+
/// their definition, and replace all the `[type error]`s back to being infer so they display in
887+
/// the output as `_`. If we didn't go through `[type error]`, we would either show all type params
888+
/// by their name *or* `_`, neither of which is desireable: we want to show all types that we could
889+
/// infer as `_` to reduce verbosity and avoid telling the user about unnecessary type annotations.
875890
struct ResolvedTypeParamEraser<'tcx> {
876891
tcx: TyCtxt<'tcx>,
877892
level: usize,
@@ -881,7 +896,18 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> {
881896
fn new(tcx: TyCtxt<'tcx>) -> Self {
882897
ResolvedTypeParamEraser { tcx, level: 0 }
883898
}
899+
900+
/// Replace not yet inferred const params with their def name.
901+
fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> {
902+
match c.val {
903+
ty::ConstKind::Infer(..) => {
904+
self.tcx().mk_const_param(index, name, c.ty)
905+
}
906+
_ => c,
907+
}
908+
}
884909
}
910+
885911
impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
886912
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
887913
self.tcx
@@ -901,29 +927,22 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
901927
.map(|(subst, param)| match &(subst.unpack(), &param.kind) {
902928
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
903929
(crate::infer::GenericArgKind::Const(c), _) => {
904-
match c.val {
905-
ty::ConstKind::Infer(..) => {
906-
// Replace not yet inferred const params with their def name.
907-
self.tcx().mk_const_param(param.index, param.name, c.ty).into()
908-
}
909-
_ => subst,
910-
}
930+
self.replace_infers(c, param.index, param.name).into()
911931
}
912932
_ => subst.super_fold_with(self),
913933
})
914934
.collect();
915-
if self.level == 1
916-
|| substs.iter().any(|subst| match subst.unpack() {
917-
ty::subst::GenericArgKind::Type(t) => match t.kind() {
918-
ty::Error(_) => false,
919-
_ => true,
920-
},
921-
// Account for `const` params here, otherwise `doesnt_infer.rs`
922-
// shows `_` instead of `Foo<{ _: u32 }>`
923-
ty::subst::GenericArgKind::Const(_) => true,
924-
_ => false,
925-
})
926-
{
935+
let should_keep = |subst: &GenericArg<'_>| match subst.unpack() {
936+
ty::subst::GenericArgKind::Type(t) => match t.kind() {
937+
ty::Error(_) => false,
938+
_ => true,
939+
},
940+
// Account for `const` params here, otherwise `doesnt_infer.rs`
941+
// shows `_` instead of `Foo<{ _: u32 }>`
942+
ty::subst::GenericArgKind::Const(_) => true,
943+
_ => false,
944+
};
945+
if self.level == 1 || substs.iter().any(should_keep) {
927946
let substs = self.tcx().intern_substs(&substs[..]);
928947
self.tcx().mk_ty(ty::Adt(def, substs))
929948
} else {
@@ -947,18 +966,9 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
947966
| ty::Opaque(..)
948967
| ty::Projection(_)
949968
| ty::Never => t.super_fold_with(self),
950-
ty::Array(ty, c) => {
951-
self.tcx().mk_ty(ty::Array(
952-
self.fold_ty(ty),
953-
match c.val {
954-
ty::ConstKind::Infer(..) => {
955-
// Replace not yet inferred const params with their def name.
956-
self.tcx().mk_const_param(0, Symbol::intern("N"), c.ty).into()
957-
}
958-
_ => c,
959-
},
960-
))
961-
}
969+
ty::Array(ty, c) => self
970+
.tcx()
971+
.mk_ty(ty::Array(self.fold_ty(ty), self.replace_infers(c, 0, Symbol::intern("N")))),
962972
// We don't want to hide type params that haven't been resolved yet.
963973
// This would be the type that will be written out with the type param
964974
// name in the output.

src/test/ui/const-generics/defaults/doesnt_infer.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>`
44
LL | let foo = Foo::foo();
55
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
66
| |
7-
| consider giving `foo` the explicit type `Foo<N>`, where the type parameter `N` is specified
7+
| consider giving `foo` the explicit type `Foo<N>`, where the const parameter `N` is specified
88

99
error: aborting due to previous error
1010

src/test/ui/inference/issue-83606.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]`
44
LL | let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
55
| - ^^^ cannot infer the value of const parameter `N` declared on the function `foo`
66
| |
7-
| consider giving this pattern the explicit type `[_; N]`, where the type parameter `N` is specified
7+
| consider giving this pattern the explicit type `[_; N]`, where the const parameter `N` is specified
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)