Skip to content

Commit 6a691b1

Browse files
committed
Refer to const params as "const params" and not "type params"
1 parent 3fd15c8 commit 6a691b1

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
@@ -587,6 +596,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
587596
}
588597
}
589598

599+
let param_type = arg_data.kind.descr();
590600
let suffix = match local_visitor.found_node_ty {
591601
Some(ty) if ty.is_closure() => {
592602
let substs =
@@ -625,15 +635,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
625635
}
626636
Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => {
627637
let ty = ty_to_string(ty);
628-
format!("the explicit type `{}`, with the type parameters specified", ty)
638+
format!("the explicit type `{}`, with the {} parameters specified", ty, param_type)
629639
}
630640
Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => {
631641
let ty = ResolvedTypeParamEraser::new(self.tcx).fold_ty(ty);
632642
let ty = ErrTypeParamEraser(self.tcx).fold_ty(ty);
633643
let ty = ty_to_string(ty);
634644
format!(
635-
"the explicit type `{}`, where the type parameter `{}` is specified",
636-
ty, arg_data.name,
645+
"the explicit type `{}`, where the {} parameter `{}` is specified",
646+
ty, param_type, arg_data.name,
637647
)
638648
}
639649
_ => "a type".to_string(),
@@ -910,7 +920,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
910920
}
911921
}
912922

913-
/// Turn resolved type params into `[type error]` to signal we don't want to display them.
923+
/// Turn *resolved* type params into `[type error]` to signal we don't want to display them. After
924+
/// performing that replacement, we'll turn all remaining infer type params to use their name from
925+
/// their definition, and replace all the `[type error]`s back to being infer so they display in
926+
/// the output as `_`. If we didn't go through `[type error]`, we would either show all type params
927+
/// by their name *or* `_`, neither of which is desireable: we want to show all types that we could
928+
/// infer as `_` to reduce verbosity and avoid telling the user about unnecessary type annotations.
914929
struct ResolvedTypeParamEraser<'tcx> {
915930
tcx: TyCtxt<'tcx>,
916931
level: usize,
@@ -920,7 +935,18 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> {
920935
fn new(tcx: TyCtxt<'tcx>) -> Self {
921936
ResolvedTypeParamEraser { tcx, level: 0 }
922937
}
938+
939+
/// Replace not yet inferred const params with their def name.
940+
fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> {
941+
match c.val {
942+
ty::ConstKind::Infer(..) => {
943+
self.tcx().mk_const_param(index, name, c.ty)
944+
}
945+
_ => c,
946+
}
947+
}
923948
}
949+
924950
impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
925951
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
926952
self.tcx
@@ -940,29 +966,22 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
940966
.map(|(subst, param)| match &(subst.unpack(), &param.kind) {
941967
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
942968
(crate::infer::GenericArgKind::Const(c), _) => {
943-
match c.val {
944-
ty::ConstKind::Infer(..) => {
945-
// Replace not yet inferred const params with their def name.
946-
self.tcx().mk_const_param(param.index, param.name, c.ty).into()
947-
}
948-
_ => subst,
949-
}
969+
self.replace_infers(c, param.index, param.name).into()
950970
}
951971
_ => subst.super_fold_with(self),
952972
})
953973
.collect();
954-
if self.level == 1
955-
|| substs.iter().any(|subst| match subst.unpack() {
956-
ty::subst::GenericArgKind::Type(t) => match t.kind() {
957-
ty::Error(_) => false,
958-
_ => true,
959-
},
960-
// Account for `const` params here, otherwise `doesnt_infer.rs`
961-
// shows `_` instead of `Foo<{ _: u32 }>`
962-
ty::subst::GenericArgKind::Const(_) => true,
963-
_ => false,
964-
})
965-
{
974+
let should_keep = |subst: &GenericArg<'_>| match subst.unpack() {
975+
ty::subst::GenericArgKind::Type(t) => match t.kind() {
976+
ty::Error(_) => false,
977+
_ => true,
978+
},
979+
// Account for `const` params here, otherwise `doesnt_infer.rs`
980+
// shows `_` instead of `Foo<{ _: u32 }>`
981+
ty::subst::GenericArgKind::Const(_) => true,
982+
_ => false,
983+
};
984+
if self.level == 1 || substs.iter().any(should_keep) {
966985
let substs = self.tcx().intern_substs(&substs[..]);
967986
self.tcx().mk_ty(ty::Adt(def, substs))
968987
} else {
@@ -986,18 +1005,9 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
9861005
| ty::Opaque(..)
9871006
| ty::Projection(_)
9881007
| ty::Never => t.super_fold_with(self),
989-
ty::Array(ty, c) => {
990-
self.tcx().mk_ty(ty::Array(
991-
self.fold_ty(ty),
992-
match c.val {
993-
ty::ConstKind::Infer(..) => {
994-
// Replace not yet inferred const params with their def name.
995-
self.tcx().mk_const_param(0, Symbol::intern("N"), c.ty).into()
996-
}
997-
_ => c,
998-
},
999-
))
1000-
}
1008+
ty::Array(ty, c) => self
1009+
.tcx()
1010+
.mk_ty(ty::Array(self.fold_ty(ty), self.replace_infers(c, 0, Symbol::intern("N")))),
10011011
// We don't want to hide type params that haven't been resolved yet.
10021012
// This would be the type that will be written out with the type param
10031013
// 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)