Skip to content

Commit 3b47cdc

Browse files
committed
Add Span to StmtKind::Let.
1 parent 28d74a9 commit 3b47cdc

File tree

6 files changed

+71
-2
lines changed

6 files changed

+71
-2
lines changed

compiler/rustc_middle/src/mir/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,13 @@ impl<'tcx> Rvalue<'tcx> {
19841984
}
19851985

19861986
impl BorrowKind {
1987+
pub fn mutability(&self) -> Mutability {
1988+
match *self {
1989+
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => Mutability::Not,
1990+
BorrowKind::Mut { .. } => Mutability::Mut,
1991+
}
1992+
}
1993+
19871994
pub fn allows_two_phase_borrow(&self) -> bool {
19881995
match *self {
19891996
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,

compiler/rustc_middle/src/thir.rs

+54-2
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> {
227227

228228
/// The lint level for this `let` statement.
229229
lint_level: LintLevel,
230+
231+
/// Span of the `let <PAT> = <INIT>` part.
232+
span: Span,
230233
},
231234
}
232235

@@ -594,6 +597,55 @@ impl<'tcx> Pat<'tcx> {
594597
_ => None,
595598
}
596599
}
600+
601+
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
602+
/// `match foo() { Some(a) => (), None => () }`
603+
pub fn each_binding(&self, mut f: impl FnMut(Symbol, BindingMode, Ty<'tcx>, Span)) {
604+
self.walk_always(|p| {
605+
if let PatKind::Binding { name, mode, ty, .. } = p.kind {
606+
f(name, mode, ty, p.span);
607+
}
608+
});
609+
}
610+
611+
/// Walk the pattern in left-to-right order.
612+
///
613+
/// If `it(pat)` returns `false`, the children are not visited.
614+
pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
615+
self.walk_(&mut it)
616+
}
617+
618+
fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
619+
if !it(self) {
620+
return;
621+
}
622+
623+
use PatKind::*;
624+
match &self.kind {
625+
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } => {}
626+
AscribeUserType { subpattern, .. }
627+
| Binding { subpattern: Some(subpattern), .. }
628+
| Deref { subpattern } => subpattern.walk_(it),
629+
Leaf { subpatterns } | Variant { subpatterns, .. } => {
630+
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
631+
}
632+
Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
633+
Array { box ref prefix, ref slice, box ref suffix }
634+
| Slice { box ref prefix, ref slice, box ref suffix } => {
635+
prefix.iter().chain(slice.iter()).chain(suffix.iter()).for_each(|p| p.walk_(it))
636+
}
637+
}
638+
}
639+
640+
/// Walk the pattern in left-to-right order.
641+
///
642+
/// If you always want to recurse, prefer this method over `walk`.
643+
pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
644+
self.walk(|p| {
645+
it(p);
646+
true
647+
})
648+
}
597649
}
598650

599651
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
@@ -879,7 +931,7 @@ mod size_asserts {
879931
static_assert_size!(ExprKind<'_>, 40);
880932
static_assert_size!(Pat<'_>, 72);
881933
static_assert_size!(PatKind<'_>, 56);
882-
static_assert_size!(Stmt<'_>, 48);
883-
static_assert_size!(StmtKind<'_>, 40);
934+
static_assert_size!(Stmt<'_>, 56);
935+
static_assert_size!(StmtKind<'_>, 48);
884936
// tidy-alphabetical-end
885937
}

compiler/rustc_middle/src/thir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
175175
ref pattern,
176176
lint_level: _,
177177
else_block,
178+
span: _,
178179
} => {
179180
if let Some(init) = initializer {
180181
visitor.visit_expr(&visitor.thir()[*init]);

compiler/rustc_mir_build/src/build/block.rs

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
115115
initializer: Some(initializer),
116116
lint_level,
117117
else_block: Some(else_block),
118+
span: _,
118119
} => {
119120
// When lowering the statement `let <pat> = <expr> else { <else> };`,
120121
// the `<else>` block is nested in the parent scope enclosing this statement.
@@ -278,6 +279,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
278279
initializer,
279280
lint_level,
280281
else_block: None,
282+
span: _,
281283
} => {
282284
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
283285
this.block_context.push(BlockFrame::Statement { ignores_expr_result });

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

+5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ impl<'tcx> Cx<'tcx> {
105105
}
106106
}
107107

108+
let span = match local.init {
109+
Some(init) => local.span.with_hi(init.span.hi()),
110+
None => local.span,
111+
};
108112
let stmt = Stmt {
109113
kind: StmtKind::Let {
110114
remainder_scope,
@@ -116,6 +120,7 @@ impl<'tcx> Cx<'tcx> {
116120
initializer: local.init.map(|init| self.mirror_expr(init)),
117121
else_block,
118122
lint_level: LintLevel::Explicit(local.hir_id),
123+
span,
119124
},
120125
opt_destruction_scope: opt_dxn_ext,
121126
};

compiler/rustc_mir_build/src/thir/print.rs

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
151151
initializer,
152152
else_block,
153153
lint_level,
154+
span,
154155
} => {
155156
print_indented!(self, "kind: Let {", depth_lvl + 1);
156157
print_indented!(
@@ -181,6 +182,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
181182
}
182183

183184
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
185+
print_indented!(self, format!("span: {:?}", span), depth_lvl + 2);
184186
print_indented!(self, "}", depth_lvl + 1);
185187
}
186188
}

0 commit comments

Comments
 (0)