Skip to content

Commit

Permalink
move else block into the Local struct
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Jul 11, 2022
1 parent 6c529de commit 1cd30e7
Show file tree
Hide file tree
Showing 59 changed files with 138 additions and 131 deletions.
18 changes: 16 additions & 2 deletions compiler/rustc_ast_lowering/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
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 });
}
Expand Down Expand Up @@ -105,10 +105,24 @@ impl<'a, 'hir> LoweringContext<'a, '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 {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, '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);
})
}

Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2146,8 +2146,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
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> {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ pub trait Visitor<'v>: Sized {
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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,8 +915,8 @@ impl<'a> State<'a> {
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) => {
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -953,8 +953,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
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()) {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}
}

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);
})
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,9 +783,9 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
})
}

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);
})
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ impl<'hir> Map<'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);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/cx/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ impl<'tcx> Cx<'tcx> {
// 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(
index,
)),
};

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);
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, '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 {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2311,7 +2311,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'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)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/hir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'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>) {
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,12 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'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>) {
Expand Down Expand Up @@ -788,7 +788,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

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
Expand All @@ -803,7 +803,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// 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.
Expand Down Expand Up @@ -1341,14 +1341,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// 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>) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,15 +1275,15 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'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`.
return;
}
}

intravisit::walk_local(self, local, els);
intravisit::walk_local(self, local);
}

// Check types in item interfaces.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_save_analysis/src/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1414,14 +1414,14 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'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>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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
Expand Down
Loading

0 comments on commit 1cd30e7

Please sign in to comment.