Skip to content

Commit 1cd30e7

Browse files
move else block into the Local struct
1 parent 6c529de commit 1cd30e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+138
-131
lines changed

compiler/rustc_ast_lowering/src/block.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
5252
};
5353
let local = self.lower_local(local);
5454
self.alias_attrs(hir_id, local.hir_id);
55-
let kind = hir::StmtKind::Local(local, els);
55+
let kind = hir::StmtKind::Local(local);
5656
let span = self.lower_span(s.span);
5757
stmts.push(hir::Stmt { hir_id, kind, span });
5858
}
@@ -105,10 +105,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
105105
let init = l.kind.init().map(|init| self.lower_expr(init));
106106
let hir_id = self.lower_node_id(l.id);
107107
let pat = self.lower_pat(&l.pat);
108+
let els = if let LocalKind::InitElse(_, els) = &l.kind {
109+
if !self.sess.features_untracked().let_else {
110+
feature_err(
111+
&self.sess.parse_sess,
112+
sym::let_else,
113+
l.span,
114+
"`let...else` statements are unstable",
115+
)
116+
.emit();
117+
}
118+
Some(self.lower_block(els, false))
119+
} else {
120+
None
121+
};
108122
let span = self.lower_span(l.span);
109123
let source = hir::LocalSource::Normal;
110124
self.lower_attrs(hir_id, &l.attrs);
111-
self.arena.alloc(hir::Local { hir_id, ty, pat, init, span, source })
125+
self.arena.alloc(hir::Local { hir_id, ty, pat, init, els, span, source })
112126
}
113127

114128
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {

compiler/rustc_ast_lowering/src/index.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
284284
});
285285
}
286286

287-
fn visit_local(&mut self, l: &'hir Local<'hir>, e: Option<&'hir Block<'hir>>) {
287+
fn visit_local(&mut self, l: &'hir Local<'hir>) {
288288
self.insert(l.span, l.hir_id, Node::Local(l));
289289
self.with_parent(l.hir_id, |this| {
290-
intravisit::walk_local(this, l, e);
290+
intravisit::walk_local(this, l);
291291
})
292292
}
293293

compiler/rustc_ast_lowering/src/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2146,8 +2146,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21462146
debug_assert!(!a.is_empty());
21472147
self.attrs.insert(hir_id.local_id, a);
21482148
}
2149-
let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
2150-
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local), None))
2149+
let local = hir::Local {
2150+
hir_id,
2151+
init,
2152+
pat,
2153+
els: None,
2154+
source,
2155+
span: self.lower_span(span),
2156+
ty: None,
2157+
};
2158+
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
21512159
}
21522160

21532161
fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {

compiler/rustc_hir/src/hir.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ pub struct Stmt<'hir> {
12971297
pub enum StmtKind<'hir> {
12981298
/// A local (`let`) binding.
12991299
/// FIXME: bundle the last two components into another `struct`
1300-
Local(&'hir Local<'hir>, Option<&'hir Block<'hir>>),
1300+
Local(&'hir Local<'hir>),
13011301

13021302
/// An item binding.
13031303
Item(ItemId),
@@ -1317,6 +1317,8 @@ pub struct Local<'hir> {
13171317
pub ty: Option<&'hir Ty<'hir>>,
13181318
/// Initializer expression to set the value, if any.
13191319
pub init: Option<&'hir Expr<'hir>>,
1320+
/// Else block for a `let...else` binding.
1321+
pub els: Option<&'hir Block<'hir>>,
13201322
pub hir_id: HirId,
13211323
pub span: Span,
13221324
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop

compiler/rustc_hir/src/intravisit.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ pub trait Visitor<'v>: Sized {
310310
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) {
311311
walk_foreign_item(self, i)
312312
}
313-
fn visit_local(&mut self, l: &'v Local<'v>, els: Option<&'v Block<'v>>) {
314-
walk_local(self, l, els)
313+
fn visit_local(&mut self, l: &'v Local<'v>) {
314+
walk_local(self, l)
315315
}
316316
fn visit_block(&mut self, b: &'v Block<'v>) {
317317
walk_block(self, b)
@@ -466,17 +466,13 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
466466
visitor.visit_expr(&body.value);
467467
}
468468

469-
pub fn walk_local<'v, V: Visitor<'v>>(
470-
visitor: &mut V,
471-
local: &'v Local<'v>,
472-
els: Option<&'v Block<'v>>,
473-
) {
469+
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
474470
// Intentionally visiting the expr first - the initialization expr
475471
// dominates the local's definition.
476472
walk_list!(visitor, visit_expr, &local.init);
477473
visitor.visit_id(local.hir_id);
478474
visitor.visit_pat(&local.pat);
479-
if let Some(els) = els {
475+
if let Some(els) = local.els {
480476
visitor.visit_block(els);
481477
}
482478
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>) {
10631059
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
10641060
visitor.visit_id(statement.hir_id);
10651061
match &statement.kind {
1066-
StmtKind::Local(ref local, els) => visitor.visit_local(local, *els),
1062+
StmtKind::Local(ref local) => visitor.visit_local(local),
10671063
StmtKind::Item(item) => visitor.visit_nested_item(*item),
10681064
StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
10691065
visitor.visit_expr(expression)

compiler/rustc_hir_pretty/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -915,8 +915,8 @@ impl<'a> State<'a> {
915915
pub fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
916916
self.maybe_print_comment(st.span.lo());
917917
match st.kind {
918-
hir::StmtKind::Local(loc, els) => {
919-
self.print_local(loc.init, els, |this| this.print_local_decl(loc));
918+
hir::StmtKind::Local(loc) => {
919+
self.print_local(loc.init, loc.els, |this| this.print_local_decl(loc));
920920
}
921921
hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
922922
hir::StmtKind::Expr(expr) => {
@@ -2305,7 +2305,7 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr<'_>) -> bool {
23052305
/// seen the semicolon, and thus don't need another.
23062306
fn stmt_ends_with_semi(stmt: &hir::StmtKind<'_>) -> bool {
23072307
match *stmt {
2308-
hir::StmtKind::Local(_, _) => true,
2308+
hir::StmtKind::Local(_) => true,
23092309
hir::StmtKind::Item(_) => false,
23102310
hir::StmtKind::Expr(e) => expr_requires_semi_to_be_stmt(e),
23112311
hir::StmtKind::Semi(..) => false,

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::infer::type_variable::TypeVariableOriginKind;
22
use crate::infer::InferCtxt;
3-
use hir::{Block, LocalSource};
3+
use hir::LocalSource;
44
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
55
use rustc_hir as hir;
66
use rustc_hir::def::Res;
@@ -953,8 +953,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
953953
self.infcx.tcx.hir()
954954
}
955955

956-
fn visit_local(&mut self, local: &'tcx Local<'tcx>, els: Option<&'tcx Block<'tcx>>) {
957-
intravisit::walk_local(self, local, els);
956+
fn visit_local(&mut self, local: &'tcx Local<'tcx>) {
957+
intravisit::walk_local(self, local);
958958

959959
if let Some(ty) = self.opt_node_type(local.hir_id) {
960960
if self.generic_arg_contains_target(ty.into()) {

compiler/rustc_lint/src/late.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
251251
}
252252
}
253253

254-
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
254+
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
255255
self.with_lint_attrs(l.hir_id, |cx| {
256-
lint_callback!(cx, check_local, l, e);
257-
hir_visit::walk_local(cx, l, e);
256+
lint_callback!(cx, check_local, l);
257+
hir_visit::walk_local(cx, l);
258258
})
259259
}
260260

compiler/rustc_lint/src/levels.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,9 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
783783
})
784784
}
785785

786-
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
786+
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
787787
self.with_lint_attrs(l.hir_id, |builder| {
788-
intravisit::walk_local(builder, l, e);
788+
intravisit::walk_local(builder, l);
789789
})
790790
}
791791

compiler/rustc_lint/src/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ macro_rules! late_lint_methods {
2424
fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>);
2525
fn check_item(a: &$hir hir::Item<$hir>);
2626
fn check_item_post(a: &$hir hir::Item<$hir>);
27-
fn check_local(a: &$hir hir::Local<$hir>, b: Option<&$hir hir::Block<$hir>>);
27+
fn check_local(a: &$hir hir::Local<$hir>);
2828
fn check_block(a: &$hir hir::Block<$hir>);
2929
fn check_block_post(a: &$hir hir::Block<$hir>);
3030
fn check_stmt(a: &$hir hir::Stmt<$hir>);

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ impl<'hir> Map<'hir> {
789789
| Node::ForeignItem(_)
790790
| Node::TraitItem(_)
791791
| Node::ImplItem(_)
792-
| Node::Stmt(Stmt { kind: StmtKind::Local(_, _), .. }) => break,
792+
| Node::Stmt(Stmt { kind: StmtKind::Local(_), .. }) => break,
793793
Node::Expr(expr @ Expr { kind: ExprKind::If(..) | ExprKind::Match(..), .. }) => {
794794
return Some(expr);
795795
}

compiler/rustc_mir_build/src/thir/cx/block.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ impl<'tcx> Cx<'tcx> {
6666
// ignore for purposes of the MIR
6767
None
6868
}
69-
hir::StmtKind::Local(local, els) => {
69+
hir::StmtKind::Local(local) => {
7070
let remainder_scope = region::Scope {
7171
id: block_id,
7272
data: region::ScopeData::Remainder(region::FirstStatementIndex::new(
7373
index,
7474
)),
7575
};
7676

77-
let else_block = els.map(|els| self.mirror_block(els));
77+
let else_block = local.els.map(|els| self.mirror_block(els));
7878

7979
let mut pattern = self.pattern_from_hir(local.pat);
8080
debug!(?pattern);

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
7575
}
7676
}
7777

78-
fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
79-
intravisit::walk_local(self, loc, els);
80-
if let Some(init) = &loc.init && els.is_some() {
81-
self.check_let(&loc.pat, &init, loc.span);
78+
fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>) {
79+
intravisit::walk_local(self, loc);
80+
let els = loc.els;
81+
if let Some(init) = loc.init && els.is_some() {
82+
self.check_let(&loc.pat, init, loc.span);
8283
}
8384

8485
let (msg, sp) = match loc.source {
@@ -1135,7 +1136,7 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
11351136

11361137
let parent_parent = hir.get_parent_node(parent);
11371138
let parent_parent_node = hir.get(parent_parent);
1138-
if let hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_, Some(_)), span, .. }) =
1139+
if let hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) =
11391140
parent_parent_node
11401141
{
11411142
return LetSource::LetElse(*span);

compiler/rustc_passes/src/check_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2311,7 +2311,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
23112311

23122312
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
23132313
// When checking statements ignore expressions, they will be checked later.
2314-
if let hir::StmtKind::Local(ref l, _) = stmt.kind {
2314+
if let hir::StmtKind::Local(ref l) = stmt.kind {
23152315
self.check_attributes(l.hir_id, stmt.span, Target::Statement, None);
23162316
}
23172317
intravisit::walk_stmt(self, stmt)

compiler/rustc_passes/src/hir_stats.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
131131
hir_visit::walk_foreign_item(self, i)
132132
}
133133

134-
fn visit_local(&mut self, l: &'v hir::Local<'v>, e: Option<&'v hir::Block<'v>>) {
134+
fn visit_local(&mut self, l: &'v hir::Local<'v>) {
135135
self.record("Local", Id::Node(l.hir_id), l);
136-
hir_visit::walk_local(self, l, e)
136+
hir_visit::walk_local(self, l)
137137
}
138138

139139
fn visit_block(&mut self, b: &'v hir::Block<'v>) {

compiler/rustc_passes/src/liveness.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -366,12 +366,12 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
366366
lsets.warn_about_unused_args(body, entry_ln);
367367
}
368368

369-
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
369+
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
370370
self.add_from_pat(&local.pat);
371-
if els.is_some() {
371+
if local.els.is_some() {
372372
self.add_live_node_for_node(local.hir_id, ExprNode(local.span, local.hir_id));
373373
}
374-
intravisit::walk_local(self, local, els);
374+
intravisit::walk_local(self, local);
375375
}
376376

377377
fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
@@ -788,7 +788,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
788788

789789
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt<'_>, succ: LiveNode) -> LiveNode {
790790
match stmt.kind {
791-
hir::StmtKind::Local(ref local, els) => {
791+
hir::StmtKind::Local(ref local) => {
792792
// Note: we mark the variable as defined regardless of whether
793793
// there is an initializer. Initially I had thought to only mark
794794
// the live variable as defined if it was initialized, and then we
@@ -803,7 +803,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
803803
// initialization, which is mildly more complex than checking
804804
// once at the func header but otherwise equivalent.
805805

806-
if let Some(els) = els {
806+
if let Some(els) = local.els {
807807
// Eventually, `let pat: ty = init else { els };` is mostly equivalent to
808808
// `let (bindings, ...) = match init { pat => (bindings, ...), _ => els };`
809809
// except that extended lifetime applies at the `init` location.
@@ -1341,14 +1341,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
13411341
// Checking for error conditions
13421342

13431343
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
1344-
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
1344+
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
13451345
self.check_unused_vars_in_pat(&local.pat, None, |spans, hir_id, ln, var| {
13461346
if local.init.is_some() {
13471347
self.warn_about_dead_assign(spans, hir_id, ln, var);
13481348
}
13491349
});
13501350

1351-
intravisit::walk_local(self, local, els);
1351+
intravisit::walk_local(self, local);
13521352
}
13531353

13541354
fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {

compiler/rustc_privacy/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1275,15 +1275,15 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
12751275
intravisit::walk_pat(self, pattern);
12761276
}
12771277

1278-
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>, els: Option<&'tcx hir::Block<'tcx>>) {
1278+
fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
12791279
if let Some(init) = local.init {
12801280
if self.check_expr_pat_type(init.hir_id, init.span) {
12811281
// Do not report duplicate errors for `let x = y`.
12821282
return;
12831283
}
12841284
}
12851285

1286-
intravisit::walk_local(self, local, els);
1286+
intravisit::walk_local(self, local);
12871287
}
12881288

12891289
// Check types in item interfaces.

compiler/rustc_save_analysis/src/dump_visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1414,14 +1414,14 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
14141414
intravisit::walk_stmt(self, s)
14151415
}
14161416

1417-
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>, e: Option<&'tcx hir::Block<'tcx>>) {
1417+
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
14181418
self.process_macro_use(l.span);
14191419
self.process_var_decl(&l.pat);
14201420

14211421
// Just walk the initializer, the else branch and type (don't want to walk the pattern again).
14221422
walk_list!(self, visit_ty, &l.ty);
14231423
walk_list!(self, visit_expr, &l.init);
1424-
walk_list!(self, visit_block, e);
1424+
walk_list!(self, visit_block, l.els);
14251425
}
14261426

14271427
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
734734
let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?);
735735
let parent_node = hir.get_parent_node(hir_id);
736736
match hir.find(parent_node) {
737-
Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local, _), .. })) => {
737+
Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => {
738738
get_name(err, &local.pat.kind)
739739
}
740740
// Different to previous arm because one is `&hir::Local` and the other

0 commit comments

Comments
 (0)