Skip to content

Commit 958bc7b

Browse files
committed
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 `/* */`.
1 parent 9714f60 commit 958bc7b

File tree

6 files changed

+34
-14
lines changed

6 files changed

+34
-14
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15161516
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
15171517
self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
15181518
PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1519-
_ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
1519+
PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
1520+
_ => {
1521+
self.dcx().span_delayed_bug(
1522+
param.pat.span,
1523+
"non-ident/wild param pat must trigger an error",
1524+
);
1525+
Ident::new(kw::Empty, self.lower_span(param.pat.span))
1526+
}
15201527
}))
15211528
}
15221529

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -2712,27 +2712,36 @@ enum FnParam<'hir> {
27122712
Param(&'hir hir::Param<'hir>),
27132713
Name(&'hir Ident),
27142714
}
2715+
27152716
impl FnParam<'_> {
27162717
fn span(&self) -> Span {
27172718
match self {
2718-
Self::Param(x) => x.span,
2719-
Self::Name(x) => x.span,
2719+
Self::Param(param) => param.span,
2720+
Self::Name(ident) => ident.span,
27202721
}
27212722
}
27222723

27232724
fn display(&self, idx: usize) -> impl '_ + fmt::Display {
27242725
struct D<'a>(FnParam<'a>, usize);
27252726
impl fmt::Display for D<'_> {
27262727
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2727-
let name = match self.0 {
2728-
FnParam::Param(x) if let hir::PatKind::Binding(_, _, ident, _) = x.pat.kind => {
2728+
// A "unique" param name is one that (a) exists, and (b) is guaranteed to be unique
2729+
// among the parameters, i.e. `_` does not count.
2730+
let unique_name = match self.0 {
2731+
FnParam::Param(param)
2732+
if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind =>
2733+
{
2734+
Some(ident.name)
2735+
}
2736+
FnParam::Name(ident)
2737+
if ident.name != kw::Empty && ident.name != kw::Underscore =>
2738+
{
27292739
Some(ident.name)
27302740
}
2731-
FnParam::Name(x) if x.name != kw::Empty => Some(x.name),
27322741
_ => None,
27332742
};
2734-
if let Some(name) = name {
2735-
write!(f, "`{name}`")
2743+
if let Some(unique_name) = unique_name {
2744+
write!(f, "`{unique_name}`")
27362745
} else {
27372746
write!(f, "parameter #{}", self.1 + 1)
27382747
}

compiler/rustc_middle/src/hir/map.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,9 @@ impl<'tcx> TyCtxt<'tcx> {
281281
}
282282

283283
pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Ident> {
284-
self.hir_body(id).params.iter().map(|arg| match arg.pat.kind {
284+
self.hir_body(id).params.iter().map(|param| match param.pat.kind {
285285
PatKind::Binding(_, _, ident, _) => ident,
286+
PatKind::Wild => Ident::new(kw::Underscore, param.pat.span),
286287
_ => Ident::empty(),
287288
})
288289
}

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
19981998
.iter()
19991999
.enumerate()
20002000
.map(|(i, ident)| {
2001-
if ident.name.is_empty() || ident.name == kw::SelfLower {
2001+
if ident.name.is_empty()
2002+
|| ident.name == kw::Underscore
2003+
|| ident.name == kw::SelfLower
2004+
{
20022005
format!("arg{i}")
20032006
} else {
20042007
format!("{ident}")

tests/pretty/hir-fn-params.pp

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
// because they had similar problems. But the pretty-printing tests currently
2828
// can't contain compile errors.
2929
30-
fn bare_fn(x: fn(: u32, : u32, a: u32)) { }
30+
fn bare_fn(x: fn(: u32, _: u32, a: u32)) { }
3131
3232
extern "C" {
33-
unsafe fn foreign_fn(: u32, a: u32);
33+
unsafe fn foreign_fn(_: u32, a: u32);
3434
}
3535
3636
trait T {
37-
fn trait_fn(: u32, : u32, a: u32);
37+
fn trait_fn(: u32, _: u32, a: u32);
3838
}

tests/ui/typeck/cyclic_type_ice.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ LL | let f = |_, _| ();
2323
help: provide the argument
2424
|
2525
LL - f(f);
26-
LL + f(/* */, /* */);
26+
LL + f(/* _ */, /* _ */);
2727
|
2828

2929
error: aborting due to 2 previous errors

0 commit comments

Comments
 (0)