Refer to const params as "const params" and not "type params"
This commit is contained in:
parent
3fd15c8404
commit
6a691b1d92
3 changed files with 48 additions and 38 deletions
|
@ -10,7 +10,7 @@ use rustc_middle::hir::map::Map;
|
|||
use rustc_middle::infer::unify_key::ConstVariableOriginKind;
|
||||
use rustc_middle::ty::print::Print;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||
use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_middle::ty::{self, Const, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::Span;
|
||||
use std::borrow::Cow;
|
||||
|
@ -305,6 +305,15 @@ pub enum UnderspecifiedArgKind {
|
|||
Const { is_parameter: bool },
|
||||
}
|
||||
|
||||
impl UnderspecifiedArgKind {
|
||||
fn descr(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Type { .. } => "type",
|
||||
Self::Const { .. } => "const",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InferenceDiagnosticsData {
|
||||
/// Generate a label for a generic argument which can't be inferred. When not
|
||||
/// much is known about the argument, `use_diag` may be used to describe the
|
||||
|
@ -587,6 +596,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let param_type = arg_data.kind.descr();
|
||||
let suffix = match local_visitor.found_node_ty {
|
||||
Some(ty) if ty.is_closure() => {
|
||||
let substs =
|
||||
|
@ -625,15 +635,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => {
|
||||
let ty = ty_to_string(ty);
|
||||
format!("the explicit type `{}`, with the type parameters specified", ty)
|
||||
format!("the explicit type `{}`, with the {} parameters specified", ty, param_type)
|
||||
}
|
||||
Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => {
|
||||
let ty = ResolvedTypeParamEraser::new(self.tcx).fold_ty(ty);
|
||||
let ty = ErrTypeParamEraser(self.tcx).fold_ty(ty);
|
||||
let ty = ty_to_string(ty);
|
||||
format!(
|
||||
"the explicit type `{}`, where the type parameter `{}` is specified",
|
||||
ty, arg_data.name,
|
||||
"the explicit type `{}`, where the {} parameter `{}` is specified",
|
||||
ty, param_type, arg_data.name,
|
||||
)
|
||||
}
|
||||
_ => "a type".to_string(),
|
||||
|
@ -910,7 +920,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Turn resolved type params into `[type error]` to signal we don't want to display them.
|
||||
/// Turn *resolved* type params into `[type error]` to signal we don't want to display them. After
|
||||
/// performing that replacement, we'll turn all remaining infer type params to use their name from
|
||||
/// their definition, and replace all the `[type error]`s back to being infer so they display in
|
||||
/// the output as `_`. If we didn't go through `[type error]`, we would either show all type params
|
||||
/// by their name *or* `_`, neither of which is desireable: we want to show all types that we could
|
||||
/// infer as `_` to reduce verbosity and avoid telling the user about unnecessary type annotations.
|
||||
struct ResolvedTypeParamEraser<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
level: usize,
|
||||
|
@ -920,7 +935,18 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> {
|
|||
fn new(tcx: TyCtxt<'tcx>) -> Self {
|
||||
ResolvedTypeParamEraser { tcx, level: 0 }
|
||||
}
|
||||
|
||||
/// Replace not yet inferred const params with their def name.
|
||||
fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> {
|
||||
match c.val {
|
||||
ty::ConstKind::Infer(..) => {
|
||||
self.tcx().mk_const_param(index, name, c.ty)
|
||||
}
|
||||
_ => c,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
|
@ -940,29 +966,22 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
|
|||
.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,
|
||||
}
|
||||
self.replace_infers(c, param.index, param.name).into()
|
||||
}
|
||||
_ => subst.super_fold_with(self),
|
||||
})
|
||||
.collect();
|
||||
if self.level == 1
|
||||
|| substs.iter().any(|subst| match subst.unpack() {
|
||||
ty::subst::GenericArgKind::Type(t) => match t.kind() {
|
||||
ty::Error(_) => false,
|
||||
_ => true,
|
||||
},
|
||||
// Account for `const` params here, otherwise `doesnt_infer.rs`
|
||||
// shows `_` instead of `Foo<{ _: u32 }>`
|
||||
ty::subst::GenericArgKind::Const(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
{
|
||||
let should_keep = |subst: &GenericArg<'_>| match subst.unpack() {
|
||||
ty::subst::GenericArgKind::Type(t) => match t.kind() {
|
||||
ty::Error(_) => false,
|
||||
_ => true,
|
||||
},
|
||||
// Account for `const` params here, otherwise `doesnt_infer.rs`
|
||||
// shows `_` instead of `Foo<{ _: u32 }>`
|
||||
ty::subst::GenericArgKind::Const(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
if self.level == 1 || substs.iter().any(should_keep) {
|
||||
let substs = self.tcx().intern_substs(&substs[..]);
|
||||
self.tcx().mk_ty(ty::Adt(def, substs))
|
||||
} else {
|
||||
|
@ -986,18 +1005,9 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
|
|||
| ty::Opaque(..)
|
||||
| ty::Projection(_)
|
||||
| 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,
|
||||
},
|
||||
))
|
||||
}
|
||||
ty::Array(ty, c) => self
|
||||
.tcx()
|
||||
.mk_ty(ty::Array(self.fold_ty(ty), self.replace_infers(c, 0, Symbol::intern("N")))),
|
||||
// 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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue