提交 3b47cdc4 编写于 作者: C Camille GILLOT

Add Span to StmtKind::Let.

上级 28d74a9b
...@@ -1984,6 +1984,13 @@ pub fn is_safe_to_remove(&self) -> bool { ...@@ -1984,6 +1984,13 @@ pub fn is_safe_to_remove(&self) -> bool {
} }
impl BorrowKind { impl BorrowKind {
pub fn mutability(&self) -> Mutability {
match *self {
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => Mutability::Not,
BorrowKind::Mut { .. } => Mutability::Mut,
}
}
pub fn allows_two_phase_borrow(&self) -> bool { pub fn allows_two_phase_borrow(&self) -> bool {
match *self { match *self {
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false, BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,
......
...@@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> { ...@@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> {
/// The lint level for this `let` statement. /// The lint level for this `let` statement.
lint_level: LintLevel, lint_level: LintLevel,
/// Span of the `let <PAT> = <INIT>` part.
span: Span,
}, },
} }
...@@ -594,6 +597,55 @@ pub fn simple_ident(&self) -> Option<Symbol> { ...@@ -594,6 +597,55 @@ pub fn simple_ident(&self) -> Option<Symbol> {
_ => None, _ => None,
} }
} }
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn each_binding(&self, mut f: impl FnMut(Symbol, BindingMode, Ty<'tcx>, Span)) {
self.walk_always(|p| {
if let PatKind::Binding { name, mode, ty, .. } = p.kind {
f(name, mode, ty, p.span);
}
});
}
/// Walk the pattern in left-to-right order.
///
/// If `it(pat)` returns `false`, the children are not visited.
pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
self.walk_(&mut it)
}
fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
if !it(self) {
return;
}
use PatKind::*;
match &self.kind {
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } => {}
AscribeUserType { subpattern, .. }
| Binding { subpattern: Some(subpattern), .. }
| Deref { subpattern } => subpattern.walk_(it),
Leaf { subpatterns } | Variant { subpatterns, .. } => {
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
}
Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
Array { box ref prefix, ref slice, box ref suffix }
| Slice { box ref prefix, ref slice, box ref suffix } => {
prefix.iter().chain(slice.iter()).chain(suffix.iter()).for_each(|p| p.walk_(it))
}
}
}
/// Walk the pattern in left-to-right order.
///
/// If you always want to recurse, prefer this method over `walk`.
pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
self.walk(|p| {
it(p);
true
})
}
} }
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> { impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
...@@ -879,7 +931,7 @@ mod size_asserts { ...@@ -879,7 +931,7 @@ mod size_asserts {
static_assert_size!(ExprKind<'_>, 40); static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 72); static_assert_size!(Pat<'_>, 72);
static_assert_size!(PatKind<'_>, 56); static_assert_size!(PatKind<'_>, 56);
static_assert_size!(Stmt<'_>, 48); static_assert_size!(Stmt<'_>, 56);
static_assert_size!(StmtKind<'_>, 40); static_assert_size!(StmtKind<'_>, 48);
// tidy-alphabetical-end // tidy-alphabetical-end
} }
...@@ -175,6 +175,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm ...@@ -175,6 +175,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
ref pattern, ref pattern,
lint_level: _, lint_level: _,
else_block, else_block,
span: _,
} => { } => {
if let Some(init) = initializer { if let Some(init) = initializer {
visitor.visit_expr(&visitor.thir()[*init]); visitor.visit_expr(&visitor.thir()[*init]);
......
...@@ -115,6 +115,7 @@ fn ast_block_stmts( ...@@ -115,6 +115,7 @@ fn ast_block_stmts(
initializer: Some(initializer), initializer: Some(initializer),
lint_level, lint_level,
else_block: Some(else_block), else_block: Some(else_block),
span: _,
} => { } => {
// When lowering the statement `let <pat> = <expr> else { <else> };`, // When lowering the statement `let <pat> = <expr> else { <else> };`,
// the `<else>` block is nested in the parent scope enclosing this statement. // the `<else>` block is nested in the parent scope enclosing this statement.
...@@ -278,6 +279,7 @@ fn ast_block_stmts( ...@@ -278,6 +279,7 @@ fn ast_block_stmts(
initializer, initializer,
lint_level, lint_level,
else_block: None, else_block: None,
span: _,
} => { } => {
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild); let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
this.block_context.push(BlockFrame::Statement { ignores_expr_result }); this.block_context.push(BlockFrame::Statement { ignores_expr_result });
......
...@@ -105,6 +105,10 @@ fn mirror_stmts( ...@@ -105,6 +105,10 @@ fn mirror_stmts(
} }
} }
let span = match local.init {
Some(init) => local.span.with_hi(init.span.hi()),
None => local.span,
};
let stmt = Stmt { let stmt = Stmt {
kind: StmtKind::Let { kind: StmtKind::Let {
remainder_scope, remainder_scope,
...@@ -116,6 +120,7 @@ fn mirror_stmts( ...@@ -116,6 +120,7 @@ fn mirror_stmts(
initializer: local.init.map(|init| self.mirror_expr(init)), initializer: local.init.map(|init| self.mirror_expr(init)),
else_block, else_block,
lint_level: LintLevel::Explicit(local.hir_id), lint_level: LintLevel::Explicit(local.hir_id),
span,
}, },
opt_destruction_scope: opt_dxn_ext, opt_destruction_scope: opt_dxn_ext,
}; };
......
...@@ -151,6 +151,7 @@ fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) { ...@@ -151,6 +151,7 @@ fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
initializer, initializer,
else_block, else_block,
lint_level, lint_level,
span,
} => { } => {
print_indented!(self, "kind: Let {", depth_lvl + 1); print_indented!(self, "kind: Let {", depth_lvl + 1);
print_indented!( print_indented!(
...@@ -181,6 +182,7 @@ fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) { ...@@ -181,6 +182,7 @@ fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
} }
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2); print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1); print_indented!(self, "}", depth_lvl + 1);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册