move else block into the Local
struct
This commit is contained in:
parent
6c529ded86
commit
1cd30e7b32
@ -52,7 +52,7 @@ fn lower_stmts(
|
||||
};
|
||||
let local = self.lower_local(local);
|
||||
self.alias_attrs(hir_id, local.hir_id);
|
||||
let kind = hir::StmtKind::Local(local, els);
|
||||
let kind = hir::StmtKind::Local(local);
|
||||
let span = self.lower_span(s.span);
|
||||
stmts.push(hir::Stmt { hir_id, kind, span });
|
||||
}
|
||||
@ -105,10 +105,24 @@ fn lower_local(&mut self, l: &Local) -> &'hir hir::Local<'hir> {
|
||||
let init = l.kind.init().map(|init| self.lower_expr(init));
|
||||
let hir_id = self.lower_node_id(l.id);
|
||||
let pat = self.lower_pat(&l.pat);
|
||||
let els = if let LocalKind::InitElse(_, els) = &l.kind {
|
||||
if !self.sess.features_untracked().let_else {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::let_else,
|
||||
l.span,
|
||||
"`let...else` statements are unstable",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
Some(self.lower_block(els, false))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let span = self.lower_span(l.span);
|
||||
let source = hir::LocalSource::Normal;
|
||||
self.lower_attrs(hir_id, &l.attrs);
|
||||
self.arena.alloc(hir::Local { hir_id, ty, pat, init, span, source })
|
||||
self.arena.alloc(hir::Local { hir_id, ty, pat, init, els, span, source })
|
||||
}
|
||||
|
||||
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
|
||||
|
@ -284,10 +284,10 @@ fn visit_block(&mut self, block: &'hir Block<'hir>) {
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'hir Local<'hir>, e: Option<&'hir Block<'hir>>) {
|
||||
fn visit_local(&mut self, l: &'hir Local<'hir>) {
|
||||
self.insert(l.span, l.hir_id, Node::Local(l));
|
||||
self.with_parent(l.hir_id, |this| {
|
||||
intravisit::walk_local(this, l, e);
|
||||
intravisit::walk_local(this, l);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2146,8 +2146,16 @@ fn stmt_let_pat(
|
||||
debug_assert!(!a.is_empty());
|
||||
self.attrs.insert(hir_id.local_id, a);
|
||||
}
|
||||
let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
|
||||
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local), None))
|
||||
let local = hir::Local {
|
||||
hir_id,
|
||||
init,
|
||||
pat,
|
||||
els: None,
|
||||
source,
|
||||
span: self.lower_span(span),
|
||||
ty: None,
|
||||
};
|
||||
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
|
||||
}
|
||||
|
||||
fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
|
||||
|
@ -1297,7 +1297,7 @@ pub struct Stmt<'hir> {
|
||||
pub enum StmtKind<'hir> {
|
||||
/// A local (`let`) binding.
|
||||
/// FIXME: bundle the last two components into another `struct`
|
||||
Local(&'hir Local<'hir>, Option<&'hir Block<'hir>>),
|
||||
Local(&'hir Local<'hir>),
|
||||
|
||||
/// An item binding.
|
||||
Item(ItemId),
|
||||
@ -1317,6 +1317,8 @@ pub struct Local<'hir> {
|
||||
pub ty: Option<&'hir Ty<'hir>>,
|
||||
/// Initializer expression to set the value, if any.
|
||||
pub init: Option<&'hir Expr<'hir>>,
|
||||
/// Else block for a `let...else` binding.
|
||||
pub els: Option<&'hir Block<'hir>>,
|
||||
pub hir_id: HirId,
|
||||
pub span: Span,
|
||||
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
|
||||
|
@ -310,8 +310,8 @@ fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, n: HirId) {
|
||||
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) {
|
||||
walk_foreign_item(self, i)
|
||||
}
|
||||
fn visit_local(&mut self, l: &'v Local<'v>, els: Option<&'v Block<'v>>) {
|
||||
walk_local(self, l, els)
|
||||
fn visit_local(&mut self, l: &'v Local<'v>) {
|
||||
walk_local(self, l)
|
||||
}
|
||||
fn visit_block(&mut self, b: &'v Block<'v>) {
|
||||
walk_block(self, b)
|
||||
@ -466,17 +466,13 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
|
||||
visitor.visit_expr(&body.value);
|
||||
}
|
||||
|
||||
pub fn walk_local<'v, V: Visitor<'v>>(
|
||||
visitor: &mut V,
|
||||
local: &'v Local<'v>,
|
||||
els: Option<&'v Block<'v>>,
|
||||
) {
|
||||
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
|
||||
// Intentionally visiting the expr first - the initialization expr
|
||||
// dominates the local's definition.
|
||||
walk_list!(visitor, visit_expr, &local.init);
|
||||
visitor.visit_id(local.hir_id);
|
||||
visitor.visit_pat(&local.pat);
|
||||
if let Some(els) = els {
|
||||
if let Some(els) = local.els {
|
||||
visitor.visit_block(els);
|
||||
}
|
||||
walk_list!(visitor, visit_ty, &local.ty);
|
||||
@ -1063,7 +1059,7 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) {
|
||||
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
|
||||
visitor.visit_id(statement.hir_id);
|
||||
match &statement.kind {
|
||||
StmtKind::Local(ref local, els) => visitor.visit_local(local, *els),
|
||||
StmtKind::Local(ref local) => visitor.visit_local(local),
|
||||
StmtKind::Item(item) => visitor.visit_nested_item(*item),
|
||||
StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
|
||||
visitor.visit_expr(expression)
|
||||
|
@ -915,8 +915,8 @@ pub fn print_local(
|
||||
pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
|
||||
self.maybe_print_comment(st.span.lo());
|
||||
match st.kind {
|
||||
hir::StmtKind::Local(loc, els) => {
|
||||
self.print_local(loc.init, els, |this| this.print_local_decl(loc));
|
||||
hir::StmtKind::Local(loc) => {
|
||||
self.print_local(loc.init, loc.els, |this| this.print_local_decl(loc));
|
||||
}
|
||||
hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
|
||||
hir::StmtKind::Expr(expr) => {
|
||||
@ -2305,7 +2305,7 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr<'_>) -> bool {
|
||||
/// seen the semicolon, and thus don't need another.
|
||||
fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool {
|
||||
match *stmt {
|
||||
hir::StmtKind::Local(_, _) => true,
|
||||
hir::StmtKind::Local(_) => true,
|
||||
hir::StmtKind::Item(_) => false,
|
||||
hir::StmtKind::Expr(e) => expr_requires_semi_to_be_stmt(e),
|
||||
hir::StmtKind::Semi(..) => false,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::infer::type_variable::TypeVariableOriginKind;
|
||||
use crate::infer::InferCtxt;
|
||||
use hir::{Block, LocalSource};
|
||||
use hir::LocalSource;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
@ -953,8 +953,8 @@ fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.infcx.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &'tcx Local<'tcx>, els: Option<&'tcx Block<'tcx>>) {
|
||||
intravisit::walk_local(self, local, els);
|
||||
fn visit_local(&mut self, local: &'tcx Local<'tcx>) {
|
||||
intravisit::walk_local(self, local);
|
||||
|
||||
if let Some(ty) = self.opt_node_type(local.hir_id) {
|
||||
if self.generic_arg_contains_target(ty.into()) {
|
||||
|
@ -251,10 +251,10 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
|
||||
self.with_lint_attrs(l.hir_id, |cx| {
|
||||
lint_callback!(cx, check_local, l, e);
|
||||
hir_visit::walk_local(cx, l, e);
|
||||
lint_callback!(cx, check_local, l);
|
||||
hir_visit::walk_local(cx, l);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -783,9 +783,9 @@ fn visit_variant(
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
|
||||
self.with_lint_attrs(l.hir_id, |builder| {
|
||||
intravisit::walk_local(builder, l, e);
|
||||
intravisit::walk_local(builder, l);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ macro_rules! late_lint_methods {
|
||||
fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>);
|
||||
fn check_item(a: &$hir hir::Item<$hir>);
|
||||
fn check_item_post(a: &$hir hir::Item<$hir>);
|
||||
fn check_local(a: &$hir hir::Local<$hir>, b: Option<&$hir hir::Block<$hir>>);
|
||||
fn check_local(a: &$hir hir::Local<$hir>);
|
||||
fn check_block(a: &$hir hir::Block<$hir>);
|
||||
fn check_block_post(a: &$hir hir::Block<$hir>);
|
||||
fn check_stmt(a: &$hir hir::Stmt<$hir>);
|
||||
|
@ -789,7 +789,7 @@ pub fn get_if_cause(self, hir_id: HirId) -> Option<&'hir Expr<'hir>> {
|
||||
| Node::ForeignItem(_)
|
||||
| Node::TraitItem(_)
|
||||
| Node::ImplItem(_)
|
||||
| Node::Stmt(Stmt { kind: StmtKind::Local(_, _), .. }) => break,
|
||||
| Node::Stmt(Stmt { kind: StmtKind::Local(_), .. }) => break,
|
||||
Node::Expr(expr @ Expr { kind: ExprKind::If(..) | ExprKind::Match(..), .. }) => {
|
||||
return Some(expr);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ fn mirror_stmts(
|
||||
// ignore for purposes of the MIR
|
||||
None
|
||||
}
|
||||
hir::StmtKind::Local(local, els) => {
|
||||
hir::StmtKind::Local(local) => {
|
||||
let remainder_scope = region::Scope {
|
||||
id: block_id,
|
||||
data: region::ScopeData::Remainder(region::FirstStatementIndex::new(
|
||||
@ -74,7 +74,7 @@ fn mirror_stmts(
|
||||
)),
|
||||
};
|
||||
|
||||
let else_block = els.map(|els| self.mirror_block(els));
|
||||
let else_block = local.els.map(|els| self.mirror_block(els));
|
||||
|
||||
let mut pattern = self.pattern_from_hir(local.pat);
|
||||
debug!(?pattern);
|
||||
|
@ -75,10 +75,11 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
|
||||
intravisit::walk_local(self, loc, els);
|
||||
if let Some(init) = &loc.init && els.is_some() {
|
||||
self.check_let(&loc.pat, &init, loc.span);
|
||||
fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>) {
|
||||
intravisit::walk_local(self, loc);
|
||||
let els = loc.els;
|
||||
if let Some(init) = loc.init && els.is_some() {
|
||||
self.check_let(&loc.pat, init, loc.span);
|
||||
}
|
||||
|
||||
let (msg, sp) = match loc.source {
|
||||
@ -1135,7 +1136,7 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
|
||||
|
||||
let parent_parent = hir.get_parent_node(parent);
|
||||
let parent_parent_node = hir.get(parent_parent);
|
||||
if let hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_, Some(_)), span, .. }) =
|
||||
if let hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) =
|
||||
parent_parent_node
|
||||
{
|
||||
return LetSource::LetElse(*span);
|
||||
|
@ -2311,7 +2311,7 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||
|
||||
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
|
||||
// When checking statements ignore expressions, they will be checked later.
|
||||
if let hir::StmtKind::Local(ref l, _) = stmt.kind {
|
||||
if let hir::StmtKind::Local(ref l) = stmt.kind {
|
||||
self.check_attributes(l.hir_id, stmt.span, Target::Statement, None);
|
||||
}
|
||||
intravisit::walk_stmt(self, stmt)
|
||||
|
@ -131,9 +131,9 @@ fn visit_foreign_item(&mut self, i: &'v hir::ForeignItem<'v>) {
|
||||
hir_visit::walk_foreign_item(self, i)
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'v hir::Local<'v>, e: Option<&'v hir::Block<'v>>) {
|
||||
fn visit_local(&mut self, l: &'v hir::Local<'v>) {
|
||||
self.record("Local", Id::Node(l.hir_id), l);
|
||||
hir_visit::walk_local(self, l, e)
|
||||
hir_visit::walk_local(self, l)
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'v hir::Block<'v>) {
|
||||
|
@ -366,12 +366,12 @@ fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
|
||||
lsets.warn_about_unused_args(body, entry_ln);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
|
||||
self.add_from_pat(&local.pat);
|
||||
if els.is_some() {
|
||||
if local.els.is_some() {
|
||||
self.add_live_node_for_node(local.hir_id, ExprNode(local.span, local.hir_id));
|
||||
}
|
||||
intravisit::walk_local(self, local, els);
|
||||
intravisit::walk_local(self, local);
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
|
||||
@ -788,7 +788,7 @@ fn propagate_through_block(&mut self, blk: &hir::Block<'_>, succ: LiveNode) -> L
|
||||
|
||||
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> LiveNode {
|
||||
match stmt.kind {
|
||||
hir::StmtKind::Local(ref local, els) => {
|
||||
hir::StmtKind::Local(ref local) => {
|
||||
// Note: we mark the variable as defined regardless of whether
|
||||
// there is an initializer. Initially I had thought to only mark
|
||||
// the live variable as defined if it was initialized, and then we
|
||||
@ -803,7 +803,7 @@ fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> Li
|
||||
// initialization, which is mildly more complex than checking
|
||||
// once at the func header but otherwise equivalent.
|
||||
|
||||
if let Some(els) = els {
|
||||
if let Some(els) = local.els {
|
||||
// Eventually, `let pat: ty = init else { els };` is mostly equivalent to
|
||||
// `let (bindings, ...) = match init { pat => (bindings, ...), _ => els };`
|
||||
// except that extended lifetime applies at the `init` location.
|
||||
@ -1341,14 +1341,14 @@ fn warn_about_unreachable(
|
||||
// Checking for error conditions
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
|
||||
self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| {
|
||||
if local.init.is_some() {
|
||||
self.warn_about_dead_assign(spans, hir_id, ln, var);
|
||||
}
|
||||
});
|
||||
|
||||
intravisit::walk_local(self, local, els);
|
||||
intravisit::walk_local(self, local);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
||||
|
@ -1275,7 +1275,7 @@ fn visit_pat(&mut self, pattern: &'tcx hir::Pat<'tcx>) {
|
||||
intravisit::walk_pat(self, pattern);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
|
||||
if let Some(init) = local.init {
|
||||
if self.check_expr_pat_type(init.hir_id, init.span) {
|
||||
// Do not report duplicate errors for `let x = y`.
|
||||
@ -1283,7 +1283,7 @@ fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::
|
||||
}
|
||||
}
|
||||
|
||||
intravisit::walk_local(self, local, els);
|
||||
intravisit::walk_local(self, local);
|
||||
}
|
||||
|
||||
// Check types in item interfaces.
|
||||
|
@ -1414,14 +1414,14 @@ fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
|
||||
intravisit::walk_stmt(self, s)
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
|
||||
self.process_macro_use(l.span);
|
||||
self.process_var_decl(&l.pat);
|
||||
|
||||
// Just walk the initializer, the else branch and type (don't want to walk the pattern again).
|
||||
walk_list!(self, visit_ty, &l.ty);
|
||||
walk_list!(self, visit_expr, &l.init);
|
||||
walk_list!(self, visit_block, e);
|
||||
walk_list!(self, visit_block, l.els);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
|
||||
|
@ -734,7 +734,7 @@ fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Op
|
||||
let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?);
|
||||
let parent_node = hir.get_parent_node(hir_id);
|
||||
match hir.find(parent_node) {
|
||||
Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local, _), .. })) => {
|
||||
Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => {
|
||||
get_name(err, &local.pat.kind)
|
||||
}
|
||||
// Different to previous arm because one is `&hir::Local` and the other
|
||||
|
@ -1218,13 +1218,9 @@ pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
|
||||
}
|
||||
|
||||
/// Type check a `let` statement.
|
||||
pub fn check_decl_local(
|
||||
&self,
|
||||
local: &'tcx hir::Local<'tcx>,
|
||||
els: Option<&'tcx hir::Block<'tcx>>,
|
||||
) {
|
||||
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
|
||||
self.check_decl(local.into());
|
||||
if let Some(blk) = els {
|
||||
if let Some(blk) = local.els {
|
||||
let previous_diverges = self.diverges.get();
|
||||
let else_ty = self.check_block_with_expected(blk, NoExpectation);
|
||||
let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
|
||||
@ -1251,8 +1247,8 @@ pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) {
|
||||
let old_has_errors = self.has_errors.replace(false);
|
||||
|
||||
match stmt.kind {
|
||||
hir::StmtKind::Local(l, e) => {
|
||||
self.check_decl_local(l, e);
|
||||
hir::StmtKind::Local(l) => {
|
||||
self.check_decl_local(l);
|
||||
}
|
||||
// Ignore for now.
|
||||
hir::StmtKind::Item(_) => {}
|
||||
@ -1411,7 +1407,7 @@ pub(in super::super) fn check_block_with_expected(
|
||||
source:
|
||||
hir::LocalSource::AssignDesugar(_),
|
||||
..
|
||||
}, _),
|
||||
}),
|
||||
..
|
||||
},
|
||||
hir::Stmt {
|
||||
|
@ -99,9 +99,9 @@ fn declare(&mut self, decl: Declaration<'tcx>) {
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
|
||||
// Add explicitly-declared locals.
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
|
||||
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
|
||||
self.declare(local.into());
|
||||
intravisit::walk_local(self, local, els)
|
||||
intravisit::walk_local(self, local)
|
||||
}
|
||||
|
||||
fn visit_let_expr(&mut self, let_expr: &'tcx hir::Let<'tcx>) {
|
||||
|
@ -796,8 +796,8 @@ fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
|
||||
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
|
||||
resolve_expr(self, ex);
|
||||
}
|
||||
fn visit_local(&mut self, l: &'tcx Local<'tcx>, e: Option<&'tcx Block<'tcx>>) {
|
||||
resolve_local(self, Some(&l.pat), l.init, e)
|
||||
fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
|
||||
resolve_local(self, Some(&l.pat), l.init, l.els)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,8 +321,8 @@ fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
|
||||
intravisit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
|
||||
intravisit::walk_local(self, l, e);
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
|
||||
intravisit::walk_local(self, l);
|
||||
let var_ty = self.fcx.local_ty(l.span, l.hir_id).decl_ty;
|
||||
let var_ty = self.resolve(var_ty, &l.span);
|
||||
self.write_ty_to_typeck_results(l.hir_id, var_ty);
|
||||
|
@ -453,11 +453,11 @@ pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
|
||||
|
||||
fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
|
||||
match stmt.kind {
|
||||
hir::StmtKind::Local(hir::Local { pat, init: Some(expr), .. }, els) => {
|
||||
self.walk_local(expr, pat, els, |_| {})
|
||||
hir::StmtKind::Local(hir::Local { pat, init: Some(expr), els, .. }) => {
|
||||
self.walk_local(expr, pat, *els, |_| {})
|
||||
}
|
||||
|
||||
hir::StmtKind::Local(_, _) => {}
|
||||
hir::StmtKind::Local(_) => {}
|
||||
|
||||
hir::StmtKind::Item(_) => {
|
||||
// We don't visit nested items in this visitor,
|
||||
|
@ -505,7 +505,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::Local(_) => true,
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
|
||||
StmtKind::Item(_) => false,
|
||||
},
|
||||
|
@ -324,7 +324,7 @@ fn end_span(&self, b: &Block<'_>, sm: &SourceMap) -> Option<Span> {
|
||||
|
||||
/// 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::Local(l) = s.kind {
|
||||
let mut i = 0usize;
|
||||
let mut res = true;
|
||||
l.pat.each_binding_or_first(&mut |_, _, _, name| {
|
||||
@ -349,7 +349,7 @@ fn eq_stmts(
|
||||
eq: &mut HirEqInterExpr<'_, '_, '_>,
|
||||
moved_bindings: &mut Vec<(HirId, Symbol)>,
|
||||
) -> bool {
|
||||
(if let StmtKind::Local(l, _) = stmt.kind {
|
||||
(if let StmtKind::Local(l) = stmt.kind {
|
||||
let old_count = moved_bindings.len();
|
||||
l.pat.each_binding_or_first(&mut |_, id, _, name| {
|
||||
moved_bindings.push((id, name.name));
|
||||
@ -435,7 +435,7 @@ fn scan_block_for_eq(cx: &LateContext<'_>, _conds: &[&Expr<'_>], block: &Block<'
|
||||
// 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::Local(l) = stmt.kind {
|
||||
l.pat.each_binding_or_first(&mut |_, id, _, _| {
|
||||
eq.locals.remove(&id);
|
||||
});
|
||||
|
@ -126,7 +126,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
|
||||
// checked and the name of the bound variable
|
||||
let (local, variant, binding_name, binding_type, span) = if_chain! {
|
||||
// only take `let ...` statements
|
||||
if let StmtKind::Local(local, _) = stmt.kind;
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let Some(expr) = local.init;
|
||||
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
|
||||
if !expr.span.from_expansion();
|
||||
|
@ -192,7 +192,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
|
||||
fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
|
||||
match stmt.kind {
|
||||
StmtKind::Local(local, _) => {
|
||||
StmtKind::Local(local) => {
|
||||
if local.ty.is_some() {
|
||||
self.ty_bounds.push(TyBound::Any);
|
||||
} else {
|
||||
|
@ -386,7 +386,7 @@ fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
|
||||
}
|
||||
},
|
||||
StmtKind::Expr(e) => self.visit_expr(e),
|
||||
StmtKind::Local(l, _) => {
|
||||
StmtKind::Local(l) => {
|
||||
self.visit_pat(l.pat);
|
||||
if let Some(e) = l.init {
|
||||
self.allow_insert_closure &= !self.in_tail_pos;
|
||||
|
@ -116,7 +116,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
|
||||
if_chain! {
|
||||
if let ExprKind::Block(block, _label @ None) = kind;
|
||||
if let Block {
|
||||
stmts: [Stmt { kind: StmtKind::Local(local, _), .. }],
|
||||
stmts: [Stmt { kind: StmtKind::Local(local), .. }],
|
||||
expr: Some(expr_end_of_block),
|
||||
rules: BlockCheckMode::DefaultBlock,
|
||||
..
|
||||
|
@ -62,7 +62,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
|
||||
while let Some(stmt) = it.next() {
|
||||
if_chain! {
|
||||
if let Some(expr) = it.peek();
|
||||
if let hir::StmtKind::Local(local, _) = stmt.kind;
|
||||
if let hir::StmtKind::Local(local) = stmt.kind;
|
||||
if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind;
|
||||
if let hir::StmtKind::Expr(if_) = expr.kind;
|
||||
if let hir::ExprKind::If(hir::Expr { kind: hir::ExprKind::DropTemps(cond), ..}, then, else_) = if_.kind;
|
||||
|
@ -2,7 +2,7 @@
|
||||
use clippy_utils::ty::{is_must_use_ty, match_type};
|
||||
use clippy_utils::{is_must_use_func_call, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::{Block, Local, PatKind};
|
||||
use rustc_hir::{Local, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
@ -109,7 +109,7 @@
|
||||
];
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>, _: Option<&Block<'_>>) {
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
|
||||
if in_external_macro(cx.tcx.sess, local.span) {
|
||||
return;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
|
||||
if let ExprKind::Block(block, _) = expr.kind {
|
||||
for stmt in block.stmts {
|
||||
if_chain! {
|
||||
if let StmtKind::Local(local, _) = stmt.kind;
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let PatKind::Binding(_, id, ..) = local.pat.kind;
|
||||
if let Some(init_expr) = local.init;
|
||||
if let ExprKind::MethodCall(method_name, &[ref iter_source], ..) = init_expr.kind;
|
||||
@ -276,7 +276,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::Local(Local { init, pat, .. }) => {
|
||||
if let PatKind::Binding(_, hir_id, ..) = pat.kind {
|
||||
init.map(|init_expr| (init_expr, Some(hir_id)))
|
||||
} else {
|
||||
|
@ -104,7 +104,7 @@ fn never_loop_expr_seq<'a, T: Iterator<Item = &'a Expr<'a>>>(es: &mut T, main_lo
|
||||
fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
||||
match stmt.kind {
|
||||
StmtKind::Semi(e, ..) | StmtKind::Expr(e, ..) => Some(e),
|
||||
StmtKind::Local(local, _) => local.init,
|
||||
StmtKind::Local(local) => local.init,
|
||||
StmtKind::Item(..) => None,
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
use rustc_ast::ast::{LitIntType, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, walk_local, walk_pat, walk_stmt, Visitor};
|
||||
use rustc_hir::{BinOpKind, Block, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
|
||||
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
@ -148,7 +148,7 @@ pub(super) fn get_result(&self) -> Option<(Symbol, Option<Ty<'tcx>>, &'tcx Expr<
|
||||
impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
|
||||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx Local<'_>, e: Option<&'tcx Block<'_>>) {
|
||||
fn visit_local(&mut self, l: &'tcx Local<'_>) {
|
||||
// Look for declarations of the variable
|
||||
if_chain! {
|
||||
if l.pat.hir_id == self.var_id;
|
||||
@ -166,7 +166,7 @@ fn visit_local(&mut self, l: &'tcx Local<'_>, e: Option<&'tcx Block<'_>>) {
|
||||
}
|
||||
}
|
||||
|
||||
walk_local(self, l, e);
|
||||
walk_local(self, l);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
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 { init: Some(e), .. }, None) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
|
||||
if let StmtKind::Local(&Local { init: Some(e), els: None, .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
|
||||
(e, !stmts.is_empty() || expr.is_some())
|
||||
} else {
|
||||
return;
|
||||
|
@ -8,7 +8,7 @@
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{def::Res, Block, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
|
||||
use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_span::{symbol::sym, Symbol};
|
||||
@ -283,7 +283,7 @@ struct NestedLoopVisitor<'a, 'b, 'tcx> {
|
||||
used_after: bool,
|
||||
}
|
||||
impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedLoopVisitor<'a, 'b, 'tcx> {
|
||||
fn visit_local(&mut self, l: &'tcx Local<'_>, _: Option<&'tcx Block<'_>>) {
|
||||
fn visit_local(&mut self, l: &'tcx Local<'_>) {
|
||||
if !self.after_loop {
|
||||
l.pat.each_binding_or_first(&mut |_, id, _, _| {
|
||||
if id == self.local_id {
|
||||
|
@ -144,7 +144,7 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) ->
|
||||
// If block only contains statements,
|
||||
// reduce `{ X; }` to `X` or `X;`
|
||||
match inner_stmt.kind {
|
||||
hir::StmtKind::Local(local, _) => Some(local.span),
|
||||
hir::StmtKind::Local(local) => Some(local.span),
|
||||
hir::StmtKind::Expr(e) => Some(e.span),
|
||||
hir::StmtKind::Semi(..) => Some(inner_stmt.span),
|
||||
hir::StmtKind::Item(..) => None,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::source::{snippet_opt, span_starts_with, walk_span_to_context};
|
||||
use clippy_utils::{higher, in_constant, meets_msrv, msrvs};
|
||||
use rustc_hir::{Arm, Block, Expr, ExprKind, Local, MatchSource, Pat};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
@ -1040,14 +1040,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(
|
||||
&mut self,
|
||||
cx: &LateContext<'tcx>,
|
||||
local: &'tcx Local<'_>,
|
||||
els: Option<&'tcx Block<'_>>,
|
||||
) {
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
|
||||
self.infallible_destructuring_match_linted |=
|
||||
els.is_none() && infallible_destructuring_match::check(cx, local);
|
||||
local.els.is_none() && infallible_destructuring_match::check(cx, local);
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||
|
@ -220,7 +220,7 @@ fn indirect_usage<'tcx>(
|
||||
init: Some(init_expr),
|
||||
hir_id: local_hir_id,
|
||||
..
|
||||
}, _) = stmt.kind
|
||||
}) = stmt.kind
|
||||
{
|
||||
let mut path_to_binding = None;
|
||||
expr_visitor(cx, |expr| {
|
||||
|
@ -161,7 +161,7 @@ fn check_fn(
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
||||
if_chain! {
|
||||
if !in_external_macro(cx.tcx.sess, stmt.span);
|
||||
if let StmtKind::Local(local, _) = stmt.kind;
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let PatKind::Binding(an, .., name, None) = local.pat.kind;
|
||||
if let Some(init) = local.init;
|
||||
if an == BindingAnnotation::Ref || an == BindingAnnotation::RefMut;
|
||||
|
@ -96,7 +96,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
}
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
||||
match stmt.kind {
|
||||
StmtKind::Local(local, _) => {
|
||||
StmtKind::Local(local) => {
|
||||
if let Local { init: Some(e), .. } = local {
|
||||
DivergenceVisitor { cx }.visit_expr(e);
|
||||
}
|
||||
@ -273,7 +273,7 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt<'_>) -
|
||||
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::Local(local) => local
|
||||
.init
|
||||
.as_ref()
|
||||
.map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)),
|
||||
|
@ -101,12 +101,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitIte
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(
|
||||
&mut self,
|
||||
cx: &LateContext<'_>,
|
||||
local: &hir::Local<'_>,
|
||||
_: Option<&hir::Block<'_>>,
|
||||
) {
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
||||
if let hir::PatKind::Wild = local.pat.kind {
|
||||
return;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ fn contains_let(cond: &Expr<'_>) -> bool {
|
||||
}
|
||||
|
||||
fn stmt_needs_ordered_drop(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
|
||||
let StmtKind::Local(local, _) = stmt.kind else { return false };
|
||||
let StmtKind::Local(local) = stmt.kind else { return false };
|
||||
!local.pat.walk_short(|pat| {
|
||||
if let PatKind::Binding(.., None) = pat.kind {
|
||||
!needs_ordered_drop(cx, cx.typeck_results().pat_ty(pat))
|
||||
@ -367,7 +367,7 @@ fn check<'tcx>(
|
||||
}
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>, _: Option<&'tcx Block<'tcx>>) {
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
|
||||
let mut parents = cx.tcx.hir().parent_iter(local.hir_id);
|
||||
if_chain! {
|
||||
if let Local {
|
||||
|
@ -88,11 +88,11 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
|
||||
span_lint_hir(cx, NO_EFFECT, expr.hir_id, stmt.span, "statement with no effect");
|
||||
return true;
|
||||
}
|
||||
} else if let StmtKind::Local(local, els) = stmt.kind {
|
||||
} else if let StmtKind::Local(local) = stmt.kind {
|
||||
if_chain! {
|
||||
if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id);
|
||||
if let Some(init) = local.init;
|
||||
if els.is_none();
|
||||
if local.els.is_none();
|
||||
if !local.pat.span.from_expansion();
|
||||
if has_no_effect(cx, init);
|
||||
if let PatKind::Binding(_, _, ident, _) = local.pat.kind;
|
||||
|
@ -261,13 +261,13 @@ fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
|
||||
match s.kind {
|
||||
StmtKind::Local(Local {
|
||||
pat, init: Some(init), ..
|
||||
}, _) => {
|
||||
}) => {
|
||||
self.visit_pat_expr(pat, init, false);
|
||||
},
|
||||
StmtKind::Item(_) | StmtKind::Expr(_) | StmtKind::Semi(_) => {
|
||||
walk_stmt(self, s);
|
||||
},
|
||||
StmtKind::Local(_, _) => {},
|
||||
StmtKind::Local(_) => {},
|
||||
}
|
||||
self.ret_vars.clear();
|
||||
}
|
||||
|
@ -83,7 +83,7 @@
|
||||
|
||||
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::Local(local) = stmt.kind {
|
||||
if in_external_macro(cx.sess(), local.pat.span) {
|
||||
return;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &hir::Block<'tcx>) {
|
||||
for (idx, stmt) in block.stmts.iter().enumerate() {
|
||||
if !stmt.span.from_expansion()
|
||||
// matches `let v = Vec::new();`
|
||||
&& let StmtKind::Local(local, _) = stmt.kind
|
||||
&& let StmtKind::Local(local) = stmt.kind
|
||||
&& let Local { pat, init: Some(init), .. } = local
|
||||
&& let PatKind::Binding(_, _, ident, _) = pat.kind
|
||||
&& let Some(vec_init_kind) = get_vec_init_kind(cx, init)
|
||||
|
@ -133,7 +133,7 @@ fn nested_visit_map(&mut self) -> Self::Map {
|
||||
|
||||
for w in block.stmts.windows(2) {
|
||||
if_chain! {
|
||||
if let hir::StmtKind::Local(local, _) = w[0].kind;
|
||||
if let hir::StmtKind::Local(local) = w[0].kind;
|
||||
if let Option::Some(t) = local.init;
|
||||
if let hir::ExprKind::Closure { .. } = t.kind;
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind;
|
||||
|
@ -82,7 +82,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {
|
||||
if_chain! {
|
||||
if let Some(retexpr) = block.expr;
|
||||
if let Some(stmt) = block.stmts.iter().last();
|
||||
if let StmtKind::Local(local, _) = &stmt.kind;
|
||||
if let StmtKind::Local(local) = &stmt.kind;
|
||||
if local.ty.is_none();
|
||||
if cx.tcx.hir().attrs(local.hir_id).is_empty();
|
||||
if let Some(initexpr) = &local.init;
|
||||
|
@ -98,7 +98,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
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)`
|
||||
if_chain! {
|
||||
if let StmtKind::Local(local, _) = stmt.kind;
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, local_id, _, None) = local.pat.kind;
|
||||
if let Some(init) = local.init;
|
||||
if let Some(len_arg) = Self::is_vec_with_capacity(cx, init);
|
||||
|
@ -141,7 +141,7 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
|
||||
for w in block.stmts.windows(3) {
|
||||
if_chain! {
|
||||
// let t = foo();
|
||||
if let StmtKind::Local(tmp, _) = w[0].kind;
|
||||
if let StmtKind::Local(tmp) = w[0].kind;
|
||||
if let Some(tmp_init) = tmp.init;
|
||||
if let PatKind::Binding(.., ident, None) = tmp.pat.kind;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
Block, Body, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem,
|
||||
Body, FnDecl, FnRetTy, GenericArg, HirId, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem,
|
||||
TraitItemKind, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -406,7 +406,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>, _: Option<&Block<'_>>) {
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
|
||||
if let Some(ty) = local.ty {
|
||||
self.check_ty(
|
||||
cx,
|
||||
|
@ -155,7 +155,7 @@ pub fn eq_expr(self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
|
||||
/// 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::Local(local) => {
|
||||
if_chain! {
|
||||
if let Some(init_expr) = local.init;
|
||||
if let PatKind::Binding(_, hir_id, _, None) = local.pat.kind;
|
||||
|
@ -12,7 +12,7 @@
|
||||
use super::LET_UNIT_VALUE;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
||||
if let StmtKind::Local(local, _) = stmt.kind
|
||||
if let StmtKind::Local(local) = stmt.kind
|
||||
&& let Some(init) = local.init
|
||||
&& !local.pat.span.from_expansion()
|
||||
&& !in_external_macro(cx.sess(), stmt.span)
|
||||
|
@ -685,7 +685,7 @@ macro_rules! kind {
|
||||
}
|
||||
|
||||
match stmt.value.kind {
|
||||
StmtKind::Local(local, _) => {
|
||||
StmtKind::Local(local) => {
|
||||
bind!(self, local);
|
||||
kind!("Local({local})");
|
||||
self.option(field!(local.init), "init", |init| {
|
||||
|
@ -155,7 +155,7 @@ fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {
|
||||
self.searcher = None;
|
||||
}
|
||||
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>, _: Option<&'tcx Block<'tcx>>) {
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
|
||||
if let Some(init_expr) = local.init
|
||||
&& let PatKind::Binding(BindingAnnotation::Mutable, id, name, None) = local.pat.kind
|
||||
&& !in_external_macro(cx.sess(), local.span)
|
||||
|
@ -102,7 +102,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, le), &StmtKind::Local(r, re)) => {
|
||||
(&StmtKind::Local(l, ), &StmtKind::Local(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 {
|
||||
@ -117,7 +117,7 @@ pub fn eq_stmt(&mut self, left: &Stmt<'_>, right: &Stmt<'_>) -> bool {
|
||||
// these only get added if the init and type is equal.
|
||||
both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
|
||||
&& both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
|
||||
&& both(&le, &re, |l, r| self.eq_block(l, r))
|
||||
&& both(&l.els, &r.els, |l, r| self.eq_block(l, r))
|
||||
&& self.eq_pat(l.pat, r.pat)
|
||||
},
|
||||
(&StmtKind::Expr(l), &StmtKind::Expr(r)) | (&StmtKind::Semi(l), &StmtKind::Semi(r)) => self.eq_expr(l, r),
|
||||
@ -922,12 +922,12 @@ pub fn hash_stmt(&mut self, b: &Stmt<'_>) {
|
||||
std::mem::discriminant(&b.kind).hash(&mut self.s);
|
||||
|
||||
match &b.kind {
|
||||
StmtKind::Local(local, els) => {
|
||||
StmtKind::Local(local, ) => {
|
||||
self.hash_pat(local.pat);
|
||||
if let Some(init) = local.init {
|
||||
self.hash_expr(init);
|
||||
}
|
||||
if let Some(els) = els {
|
||||
if let Some(els) = local.els {
|
||||
self.hash_block(els);
|
||||
}
|
||||
},
|
||||
|
@ -1826,7 +1826,7 @@ pub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
|
||||
..
|
||||
},
|
||||
..
|
||||
}, _),
|
||||
}),
|
||||
..
|
||||
}),
|
||||
_
|
||||
|
Loading…
Reference in New Issue
Block a user