Handle _
properly in a couple of places.
Currently (PatKind::Wild` (i.e. `_`) gets turned by `lower_fn_params_to_names` into an empty identifier, which means it is printed incorrectly by HIR pretty printing. And likewise for `lower_fn_params_to_names`, which affects some error messages. This commit fixes them. This requires a slight tweak in a couple of places to continue using parameter numbers in some error messages. And it improves the output of `tests/ui/typeck/cyclic_type_ice.rs`: `/* _ */` is a better suggestion than `/* */`.
This commit is contained in:
parent
9714f60f1d
commit
958bc7b365
6 changed files with 34 additions and 14 deletions
|
@ -1516,7 +1516,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
|
||||
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
|
||||
PatKind::Ident(_, ident, _) => self.lower_ident(ident),
|
||||
_ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
|
||||
PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
|
||||
_ => {
|
||||
self.dcx().span_delayed_bug(
|
||||
param.pat.span,
|
||||
"non-ident/wild param pat must trigger an error",
|
||||
);
|
||||
Ident::new(kw::Empty, self.lower_span(param.pat.span))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -2712,11 +2712,12 @@ enum FnParam<'hir> {
|
|||
Param(&'hir hir::Param<'hir>),
|
||||
Name(&'hir Ident),
|
||||
}
|
||||
|
||||
impl FnParam<'_> {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
Self::Param(x) => x.span,
|
||||
Self::Name(x) => x.span,
|
||||
Self::Param(param) => param.span,
|
||||
Self::Name(ident) => ident.span,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2724,15 +2725,23 @@ impl FnParam<'_> {
|
|||
struct D<'a>(FnParam<'a>, usize);
|
||||
impl fmt::Display for D<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let name = match self.0 {
|
||||
FnParam::Param(x) if let hir::PatKind::Binding(_, _, ident, _) = x.pat.kind => {
|
||||
// A "unique" param name is one that (a) exists, and (b) is guaranteed to be unique
|
||||
// among the parameters, i.e. `_` does not count.
|
||||
let unique_name = match self.0 {
|
||||
FnParam::Param(param)
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind =>
|
||||
{
|
||||
Some(ident.name)
|
||||
}
|
||||
FnParam::Name(ident)
|
||||
if ident.name != kw::Empty && ident.name != kw::Underscore =>
|
||||
{
|
||||
Some(ident.name)
|
||||
}
|
||||
FnParam::Name(x) if x.name != kw::Empty => Some(x.name),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(name) = name {
|
||||
write!(f, "`{name}`")
|
||||
if let Some(unique_name) = unique_name {
|
||||
write!(f, "`{unique_name}`")
|
||||
} else {
|
||||
write!(f, "parameter #{}", self.1 + 1)
|
||||
}
|
||||
|
|
|
@ -281,8 +281,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Ident> {
|
||||
self.hir_body(id).params.iter().map(|arg| match arg.pat.kind {
|
||||
self.hir_body(id).params.iter().map(|param| match param.pat.kind {
|
||||
PatKind::Binding(_, _, ident, _) => ident,
|
||||
PatKind::Wild => Ident::new(kw::Underscore, param.pat.span),
|
||||
_ => Ident::empty(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1998,7 +1998,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, ident)| {
|
||||
if ident.name.is_empty() || ident.name == kw::SelfLower {
|
||||
if ident.name.is_empty()
|
||||
|| ident.name == kw::Underscore
|
||||
|| ident.name == kw::SelfLower
|
||||
{
|
||||
format!("arg{i}")
|
||||
} else {
|
||||
format!("{ident}")
|
||||
|
|
|
@ -27,12 +27,12 @@ impl S {
|
|||
// because they had similar problems. But the pretty-printing tests currently
|
||||
// can't contain compile errors.
|
||||
|
||||
fn bare_fn(x: fn(: u32, : u32, a: u32)) { }
|
||||
fn bare_fn(x: fn(: u32, _: u32, a: u32)) { }
|
||||
|
||||
extern "C" {
|
||||
unsafe fn foreign_fn(: u32, a: u32);
|
||||
unsafe fn foreign_fn(_: u32, a: u32);
|
||||
}
|
||||
|
||||
trait T {
|
||||
fn trait_fn(: u32, : u32, a: u32);
|
||||
fn trait_fn(: u32, _: u32, a: u32);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ LL | let f = |_, _| ();
|
|||
help: provide the argument
|
||||
|
|
||||
LL - f(f);
|
||||
LL + f(/* */, /* */);
|
||||
LL + f(/* _ */, /* _ */);
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue