Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2024-03-14 05:01:33 +00:00
commit 22577e55ef
40 changed files with 52 additions and 52 deletions

View file

@ -52,7 +52,7 @@ fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_
.as_ref()
.map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
|stmt| match &stmt.kind {
StmtKind::Local(_) => true,
StmtKind::Let(_) => true,
StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
StmtKind::Item(_) => false,
},

View file

@ -349,7 +349,7 @@ impl BlockEq {
/// If the statement is a local, checks if the bound names match the expected list of names.
fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool {
if let StmtKind::Local(l) = s.kind {
if let StmtKind::Let(l) = s.kind {
let mut i = 0usize;
let mut res = true;
l.pat.each_binding_or_first(&mut |_, _, _, name| {
@ -389,7 +389,7 @@ fn eq_stmts(
eq: &mut HirEqInterExpr<'_, '_, '_>,
moved_bindings: &mut Vec<(HirId, Symbol)>,
) -> bool {
(if let StmtKind::Local(l) = stmt.kind {
(if let StmtKind::Let(l) = stmt.kind {
let old_count = moved_bindings.len();
l.pat.each_binding_or_first(&mut |_, id, _, name| {
moved_bindings.push((id, name.name));
@ -432,7 +432,7 @@ fn scan_block_for_eq<'tcx>(
.iter()
.enumerate()
.find(|&(i, stmt)| {
if let StmtKind::Local(l) = stmt.kind
if let StmtKind::Let(l) = stmt.kind
&& needs_ordered_drop(cx, cx.typeck_results().node_type(l.hir_id))
{
local_needs_ordered_drop = true;
@ -509,7 +509,7 @@ fn scan_block_for_eq<'tcx>(
// Clear out all locals seen at the end so far. None of them can be moved.
let stmts = &blocks[0].stmts;
for stmt in &stmts[stmts.len() - init..=stmts.len() - offset] {
if let StmtKind::Local(l) = stmt.kind {
if let StmtKind::Let(l) = stmt.kind {
l.pat.each_binding_or_first(&mut |_, id, _, _| {
// FIXME(rust/#120456) - is `swap_remove` correct?
eq.locals.swap_remove(&id);

View file

@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
// find all binding statements like `let mut _ = T::default()` where `T::default()` is the
// `default` method of the `Default` trait, and store statement index in current block being
// checked and the name of the bound variable
let (local, variant, binding_name, binding_type, span) = if let StmtKind::Local(local) = stmt.kind
let (local, variant, binding_name, binding_type, span) = if let StmtKind::Let(local) = stmt.kind
// only take `let ...` statements
&& let Some(expr) = local.init
&& !any_parent_is_automatically_derived(cx.tcx, expr.hir_id)

View file

@ -221,7 +221,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
match stmt.kind {
// we cannot check the exact type since it's a hir::Ty which does not implement `is_numeric`
StmtKind::Local(local) => self.ty_bounds.push(ExplicitTyBound(local.ty.is_some())),
StmtKind::Let(local) => self.ty_bounds.push(ExplicitTyBound(local.ty.is_some())),
_ => self.ty_bounds.push(ExplicitTyBound(false)),
}

View file

@ -423,7 +423,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
}
},
StmtKind::Expr(e) => self.visit_expr(e),
StmtKind::Local(l) => {
StmtKind::Let(l) => {
self.visit_pat(l.pat);
if let Some(e) = l.init {
self.allow_insert_closure &= !self.in_tail_pos;

View file

@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) -> &'tcx ExprKind<'hir> {
if let ExprKind::Block(block, _label @ None) = kind
&& let Block {
stmts: [Stmt { kind: StmtKind::Local(local), .. }],
stmts: [Stmt { kind: StmtKind::Let(local), .. }],
expr: Some(expr_end_of_block),
rules: BlockCheckMode::DefaultBlock,
..

View file

@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
let mut it = block.stmts.iter().peekable();
while let Some(stmt) = it.next() {
if let Some(expr) = it.peek()
&& let hir::StmtKind::Local(local) = stmt.kind
&& let hir::StmtKind::Let(local) = stmt.kind
&& let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind
&& let hir::StmtKind::Expr(if_) = expr.kind
&& let hir::ExprKind::If(

View file

@ -410,7 +410,7 @@ fn get_assignments<'a, 'tcx>(
stmts
.iter()
.filter_map(move |stmt| match stmt.kind {
StmtKind::Local(..) | StmtKind::Item(..) => None,
StmtKind::Let(..) | StmtKind::Item(..) => None,
StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e),
})
.chain(*expr)

View file

@ -72,7 +72,7 @@ fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr
}
fn check_local(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) {
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& is_vec_pop_unwrap(cx, init, is_empty_recv)
{

View file

@ -273,7 +273,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
}
return false; // no need to walk further *on the variable*
},
Res::Def(DefKind::Static(_) | DefKind::Const, ..) => {
Res::Def(DefKind::Static{..} | DefKind::Const, ..) => {
if index_used_directly {
self.indexed_directly.insert(
seqvar.segments[0].ident.name,

View file

@ -137,7 +137,7 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t
match stmt.kind {
StmtKind::Semi(e) | StmtKind::Expr(e) => Some((e, None)),
// add the let...else expression (if present)
StmtKind::Local(local) => local.init.map(|init| (init, local.els)),
StmtKind::Let(local) => local.init.map(|init| (init, local.els)),
StmtKind::Item(..) => None,
}
}

View file

@ -101,7 +101,7 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
Res::Local(hir_id) => {
self.ids.insert(hir_id);
},
Res::Def(DefKind::Static(_), def_id) => {
Res::Def(DefKind::Static{..}, def_id) => {
let mutable = self.cx.tcx.is_mutable_static(def_id);
self.def_ids.insert(def_id, mutable);
},

View file

@ -11,7 +11,7 @@ use rustc_lint::LateContext;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
([stmt, stmts @ ..], expr) => {
if let StmtKind::Local(&Local {
if let StmtKind::Let(&Local {
init: Some(e),
els: None,
..

View file

@ -53,7 +53,7 @@ impl<'tcx> QuestionMark {
return;
}
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& local.els.is_none()
&& local.ty.is_none()

View file

@ -138,7 +138,7 @@ fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<
// If block only contains statements,
// reduce `{ X; }` to `X` or `X;`
match inner_stmt.kind {
hir::StmtKind::Local(local) => Some(local.span),
hir::StmtKind::Let(local) => Some(local.span),
hir::StmtKind::Expr(e) => Some(e.span),
hir::StmtKind::Semi(..) => Some(inner_stmt.span),
hir::StmtKind::Item(..) => None,

View file

@ -91,7 +91,7 @@ pub(super) fn check<'tcx>(
},
hir::ExprKind::Path(ref p) => matches!(
cx.qpath_res(p, arg.hir_id),
hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static(_), _)
hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static{..}, _)
),
_ => false,
}

View file

@ -424,7 +424,7 @@ fn get_expr_and_hir_id_from_stmt<'v>(stmt: &'v Stmt<'v>) -> Option<(&'v Expr<'v>
match stmt.kind {
StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)),
StmtKind::Item(..) => None,
StmtKind::Local(Local { init, pat, .. }) => {
StmtKind::Let(Local { init, pat, .. }) => {
if let PatKind::Binding(_, hir_id, ..) = pat.kind {
init.map(|init_expr| (init_expr, Some(hir_id)))
} else {

View file

@ -198,7 +198,7 @@ fn indirect_usage<'tcx>(
binding: HirId,
ctxt: SyntaxContext,
) -> Option<IndirectUsage<'tcx>> {
if let StmtKind::Local(&Local {
if let StmtKind::Let(&Local {
pat: Pat {
kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None),
..

View file

@ -27,7 +27,7 @@ fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &E
fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option<HirId> {
for stmt in statements {
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Path(QPath::Resolved(_, path)) = init.kind
&& let hir::def::Res::Local(local_hir_id) = path.res

View file

@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
if !in_external_macro(cx.tcx.sess, stmt.span)
&& let StmtKind::Local(local) = stmt.kind
&& let StmtKind::Let(local) = stmt.kind
&& let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind
&& let Some(init) = local.init
// Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.

View file

@ -97,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
match stmt.kind {
StmtKind::Local(local) => {
StmtKind::Let(local) => {
if let Local { init: Some(e), .. } = local {
DivergenceVisitor { cx }.visit_expr(e);
}
@ -291,7 +291,7 @@ fn check_stmt<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, stmt: &'tcx Stmt<'_>) -> St
StmtKind::Expr(expr) | StmtKind::Semi(expr) => check_expr(vis, expr),
// If the declaration is of a local variable, check its initializer
// expression if it has one. Otherwise, keep going.
StmtKind::Local(local) => local
StmtKind::Let(local) => local
.init
.as_ref()
.map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)),

View file

@ -109,7 +109,7 @@ fn collect_unsafe_exprs<'tcx>(
ExprKind::Path(QPath::Resolved(
_,
hir::Path {
res: Res::Def(DefKind::Static(Mutability::Mut), _),
res: Res::Def(DefKind::Static{mutability:Mutability::Mut, ..}, _),
..
},
)) => {
@ -149,7 +149,7 @@ fn collect_unsafe_exprs<'tcx>(
ExprKind::Path(QPath::Resolved(
_,
hir::Path {
res: Res::Def(DefKind::Static(Mutability::Mut), _),
res: Res::Def(DefKind::Static{mutability:Mutability::Mut, ..}, _),
..
}
))

View file

@ -86,7 +86,7 @@ fn contains_let(cond: &Expr<'_>) -> bool {
}
fn stmt_needs_ordered_drop(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
let StmtKind::Local(local) = stmt.kind else {
let StmtKind::Let(local) = stmt.kind else {
return false;
};
!local.pat.walk_short(|pat| {

View file

@ -174,7 +174,7 @@ impl NoEffect {
);
return true;
}
} else if let StmtKind::Local(local) = stmt.kind {
} else if let StmtKind::Let(local) = stmt.kind {
if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)
&& !matches!(local.source, LocalSource::AsyncFn)
&& let Some(init) = local.init

View file

@ -82,7 +82,7 @@ declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);
impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
if let StmtKind::Local(local) = stmt.kind {
if let StmtKind::Let(local) = stmt.kind {
if in_external_macro(cx.sess(), local.pat.span) {
return;
}

View file

@ -109,7 +109,7 @@ fn find_let_else_ret_expression<'hir>(block: &'hir Block<'hir>) -> Option<&'hir
}
fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
if let StmtKind::Local(Local {
if let StmtKind::Let(Local {
pat,
init: Some(init_expr),
els: Some(els),

View file

@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
return;
}
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Local {
pat, init: Some(init), ..
} = local

View file

@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
}
for w in block.stmts.windows(2) {
if let hir::StmtKind::Local(local) = w[0].kind
if let hir::StmtKind::Let(local) = w[0].kind
&& let Option::Some(t) = local.init
&& let hir::ExprKind::Closure { .. } = t.kind
&& let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind

View file

@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
// we need both a let-binding stmt and an expr
if let Some(retexpr) = block.expr
&& let Some(stmt) = block.stmts.iter().last()
&& let StmtKind::Local(local) = &stmt.kind
&& let StmtKind::Let(local) = &stmt.kind
&& local.ty.is_none()
&& cx.tcx.hir().attrs(local.hir_id).is_empty()
&& let Some(initexpr) = &local.init

View file

@ -236,7 +236,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx
fn manage_has_expensive_expr_after_last_attr(&mut self) {
let has_expensive_stmt = match self.ap.curr_stmt.kind {
hir::StmtKind::Expr(expr) if is_inexpensive_expr(expr) => false,
hir::StmtKind::Local(local)
hir::StmtKind::Let(local)
if let Some(expr) = local.init
&& let hir::ExprKind::Path(_) = expr.kind =>
{
@ -290,7 +290,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o
};
let mut ac = AttrChecker::new(self.cx, self.seen_types, self.type_cache);
if ac.has_sig_drop_attr(self.cx.typeck_results().expr_ty(expr)) {
if let hir::StmtKind::Local(local) = self.ap.curr_stmt.kind
if let hir::StmtKind::Let(local) = self.ap.curr_stmt.kind
&& let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind
&& !self.ap.apas.contains_key(&hir_id)
&& {
@ -326,7 +326,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o
return;
};
match self.ap.curr_stmt.kind {
hir::StmtKind::Local(local) => {
hir::StmtKind::Let(local) => {
if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind {
apa.last_bind_ident = ident;
}

View file

@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
// Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`
// or `Vec::new()`
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let PatKind::Binding(BindingAnnotation::MUT, local_id, _, None) = local.pat.kind
&& let Some(init) = local.init
&& let Some(size_expr) = Self::as_vec_initializer(cx, init)

View file

@ -148,7 +148,7 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
}
for [s1, s2, s3] in block.stmts.array_windows::<3>() {
if let StmtKind::Local(tmp) = s1.kind
if let StmtKind::Let(tmp) = s1.kind
// let t = foo();
&& let Some(tmp_init) = tmp.init
&& let PatKind::Binding(.., ident, None) = tmp.pat.kind
@ -243,7 +243,7 @@ fn parse<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(ExprOrIdent<'hir>, &'a Expr<
if let ExprKind::Assign(lhs, rhs, _) = expr.kind {
return Some((ExprOrIdent::Expr(lhs), rhs));
}
} else if let StmtKind::Local(expr) = stmt.kind {
} else if let StmtKind::Let(expr) = stmt.kind {
if let Some(rhs) = expr.init {
if let PatKind::Binding(_, _, ident_l, _) = expr.pat.kind {
return Some((ExprOrIdent::Ident(ident_l), rhs));

View file

@ -158,7 +158,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {
let (hir::StmtKind::Local(&hir::Local { init: Some(expr), .. })
let (hir::StmtKind::Let(&hir::Local { init: Some(expr), .. })
| hir::StmtKind::Expr(expr)
| hir::StmtKind::Semi(expr)) = stmt.kind
else {
@ -358,7 +358,7 @@ fn block_parents_have_safety_comment(
},
Node::Stmt(hir::Stmt {
kind:
hir::StmtKind::Local(hir::Local { span, hir_id, .. })
hir::StmtKind::Let(hir::Local { span, hir_id, .. })
| hir::StmtKind::Expr(hir::Expr { span, hir_id, .. })
| hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }),
..

View file

@ -153,7 +153,7 @@ impl<'tcx> VecLocation<'tcx> {
/// or `self` expression for `Vec::reserve()`.
fn extract_init_or_reserve_target<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> Option<TargetVec<'tcx>> {
match stmt.kind {
StmtKind::Local(local) => {
StmtKind::Let(local) => {
if let Some(init_expr) = local.init
&& let PatKind::Binding(_, hir_id, _, None) = local.pat.kind
&& let Some(init_kind) = get_vec_init_kind(cx, init_expr)

View file

@ -61,10 +61,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
/// we need to check them at `check_expr` or `check_block` as they are not stmts
/// but we can't check them at `check_expr` because we need the broader context
/// because we should do this only for the final expression of the block, and not for
/// `StmtKind::Local` which binds values => the io amount is used.
/// `StmtKind::Let` which binds values => the io amount is used.
///
/// To check for unused io amount in stmts, we only consider `StmtKind::Semi`.
/// `StmtKind::Local` is not considered because it binds values => the io amount is used.
/// `StmtKind::Let` is not considered because it binds values => the io amount is used.
/// `StmtKind::Expr` is not considered because requires unit type => the io amount is used.
/// `StmtKind::Item` is not considered because it's not an expression.
///

View file

@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable {
for (idx, stmt) in block.stmts.iter().enumerate() {
if !stmt.span.from_expansion()
&& let StmtKind::Local(local) = stmt.kind
&& let StmtKind::Let(local) = stmt.kind
&& let PatKind::Binding(_, binding, ident, _) = local.pat.kind
&& let Some(init) = local.init
&& !init.span.from_expansion()
@ -197,7 +197,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
},
Node::Stmt(stmt) => {
match stmt.kind {
StmtKind::Local(_) | StmtKind::Item(_) => self.found_peek_call = true,
StmtKind::Let(_) | StmtKind::Item(_) => self.found_peek_call = true,
StmtKind::Expr(_) | StmtKind::Semi(_) => {},
}

View file

@ -724,7 +724,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
}
match stmt.value.kind {
StmtKind::Local(local) => {
StmtKind::Let(local) => {
bind!(self, local);
kind!("Local({local})");
self.option(field!(local.init), "init", |init| {

View file

@ -267,7 +267,7 @@ pub fn eq_block(l: &Block, r: &Block) -> bool {
pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
use StmtKind::*;
match (&l.kind, &r.kind) {
(Local(l), Local(r)) => {
(Let(l), Let(r)) => {
eq_pat(&l.pat, &r.pat)
&& both(&l.ty, &r.ty, |l, r| eq_ty(l, r))
&& eq_local_kind(&l.kind, &r.kind)

View file

@ -108,7 +108,7 @@ pub struct HirEqInterExpr<'a, 'b, 'tcx> {
impl HirEqInterExpr<'_, '_, '_> {
pub fn eq_stmt(&mut self, left: &Stmt<'_>, right: &Stmt<'_>) -> bool {
match (&left.kind, &right.kind) {
(&StmtKind::Local(l), &StmtKind::Local(r)) => {
(&StmtKind::Let(l), &StmtKind::Let(r)) => {
// This additional check ensures that the type of the locals are equivalent even if the init
// expression or type have some inferred parts.
if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {
@ -1030,7 +1030,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
std::mem::discriminant(&b.kind).hash(&mut self.s);
match &b.kind {
StmtKind::Local(local) => {
StmtKind::Let(local) => {
self.hash_pat(local.pat);
if let Some(init) = local.init {
self.hash_expr(init);

View file

@ -2161,7 +2161,7 @@ pub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
Node::Stmt(Stmt {
kind: StmtKind::Expr(_)
| StmtKind::Semi(_)
| StmtKind::Local(Local {
| StmtKind::Let(Local {
pat: Pat {
kind: PatKind::Wild,
..