diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-03-27 09:33:02 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-03-28 09:18:57 +1100 |
| commit | 9f089e080c47bc282aa98f1e8c72ff44076afbb9 (patch) | |
| tree | 89a9f31ddae2fe6fa86404d891cce7a51d4d71d6 /compiler/rustc_lint/src/builtin.rs | |
| parent | 217693a1f02ca6431a434926ff3417bdb6dbac2e (diff) | |
| download | rust-9f089e080c47bc282aa98f1e8c72ff44076afbb9.tar.gz rust-9f089e080c47bc282aa98f1e8c72ff44076afbb9.zip | |
Add `{ast,hir,thir}::PatKind::Missing` variants.
"Missing" patterns are possible in bare fn types (`fn f(u32)`) and
similar places. Currently these are represented in the AST with
`ast::PatKind::Ident` with no `by_ref`, no `mut`, an empty ident, and no
sub-pattern. This flows through to `{hir,thir}::PatKind::Binding` for
HIR and THIR.
This is a bit nasty. It's very non-obvious, and easy to forget to check
for the exceptional empty identifier case.
This commit adds a new variant, `PatKind::Missing`, to do it properly.
The process I followed:
- Add a `Missing` variant to `{ast,hir,thir}::PatKind`.
- Chang `parse_param_general` to produce `ast::PatKind::Missing`
instead of `ast::PatKind::Missing`.
- Look through `kw::Empty` occurrences to find functions where an
existing empty ident check needs replacing with a `PatKind::Missing`
check: `print_param`, `check_trait_item`, `is_named_param`.
- Add a `PatKind::Missing => unreachable!(),` arm to every exhaustive
match identified by the compiler.
- Find which arms are actually reachable by running the test suite,
changing them to something appropriate, usually by looking at what
would happen to a `PatKind::Ident`/`PatKind::Binding` with no ref, no
`mut`, an empty ident, and no subpattern.
Quite a few of the `unreachable!()` arms were never reached. This makes
sense because `PatKind::Missing` can't happen in every pattern, only
in places like bare fn tys and trait fn decls.
I also tried an alternative approach: modifying `ast::Param::pat` to
hold an `Option<P<Pat>>` instead of a `P<Pat>`, but that quickly turned
into a very large and painful change. Adding `PatKind::Missing` is much
easier.
Diffstat (limited to 'compiler/rustc_lint/src/builtin.rs')
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9dccd4a0552..0b5cdf99de5 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -778,21 +778,19 @@ impl EarlyLintPass for AnonymousParameters { } if let ast::AssocItemKind::Fn(box Fn { ref sig, .. }) = it.kind { for arg in sig.decl.inputs.iter() { - if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind { - if ident.name == kw::Empty { - let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); + if let ast::PatKind::Missing = arg.pat.kind { + let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); - let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { - (snip.as_str(), Applicability::MachineApplicable) - } else { - ("<type>", Applicability::HasPlaceholders) - }; - cx.emit_span_lint( - ANONYMOUS_PARAMETERS, - arg.pat.span, - BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip }, - ); - } + let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { + (snip.as_str(), Applicability::MachineApplicable) + } else { + ("<type>", Applicability::HasPlaceholders) + }; + cx.emit_span_lint( + ANONYMOUS_PARAMETERS, + arg.pat.span, + BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip }, + ); } } } |
