提交 060dba67 编写于 作者: E Esteban Küber

Add loop head span to hir

上级 a701ff98
......@@ -10,9 +10,9 @@
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_session::parse::feature_err;
use rustc_span::hygiene::ForLoopLoc;
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{hygiene::ForLoopLoc, DUMMY_SP};
use rustc_target::asm;
use std::collections::hash_map::Entry;
use std::fmt::Write;
......@@ -102,6 +102,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
this.lower_block(body, false),
opt_label,
hir::LoopSource::Loop,
DUMMY_SP,
)
}),
ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body),
......@@ -453,7 +454,12 @@ fn lower_expr_while_in_loop_scope(
self.expr_match(span, scrutinee, arena_vec![self; then_arm, else_arm], desugar);
// `[opt_ident]: loop { ... }`
hir::ExprKind::Loop(self.block_expr(self.arena.alloc(match_expr)), opt_label, source)
hir::ExprKind::Loop(
self.block_expr(self.arena.alloc(match_expr)),
opt_label,
source,
span.with_hi(cond.span.hi()),
)
}
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
......@@ -748,7 +754,7 @@ fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'
// loop { .. }
let loop_expr = self.arena.alloc(hir::Expr {
hir_id: loop_hir_id,
kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop),
kind: hir::ExprKind::Loop(loop_block, None, hir::LoopSource::Loop, span),
span,
attrs: ThinVec::new(),
});
......@@ -1709,7 +1715,12 @@ fn lower_expr_for(
);
// `[opt_ident]: loop { ... }`
let kind = hir::ExprKind::Loop(loop_block, opt_label, hir::LoopSource::ForLoop);
let kind = hir::ExprKind::Loop(
loop_block,
opt_label,
hir::LoopSource::ForLoop,
e.span.with_hi(orig_head_span.hi()),
);
let loop_expr = self.arena.alloc(hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
......
......@@ -1617,7 +1617,9 @@ pub enum ExprKind<'hir> {
/// A conditionless loop (can be exited with `break`, `continue`, or `return`).
///
/// I.e., `'label: loop { <block> }`.
Loop(&'hir Block<'hir>, Option<Label>, LoopSource),
///
/// The `Span` is the loop header (`for x in y`/`while let pat = expr`).
Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
/// A `match` block, with a source that indicates whether or not it is
/// the result of a desugaring, and if so, which kind.
Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
......
......@@ -1151,7 +1151,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
visitor.visit_expr(then);
walk_list!(visitor, visit_expr, else_opt);
}
ExprKind::Loop(ref block, ref opt_label, _) => {
ExprKind::Loop(ref block, ref opt_label, _, _) => {
walk_list!(visitor, visit_label, opt_label);
visitor.visit_block(block);
}
......
......@@ -1396,7 +1396,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr<'_>) {
hir::ExprKind::If(ref test, ref blk, ref elseopt) => {
self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e));
}
hir::ExprKind::Loop(ref blk, opt_label, _) => {
hir::ExprKind::Loop(ref blk, opt_label, _, _) => {
if let Some(label) = opt_label {
self.print_ident(label.ident);
self.word_space(":");
......
......@@ -546,9 +546,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
scrutinee: discr.to_ref(),
arms: arms.iter().map(|a| convert_arm(cx, a)).collect(),
},
hir::ExprKind::Loop(ref body, _, _) => {
ExprKind::Loop { body: block::to_expr_ref(cx, body) }
}
hir::ExprKind::Loop(ref body, ..) => ExprKind::Loop { body: block::to_expr_ref(cx, body) },
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
lhs: source.to_ref(),
name: Field::new(cx.tcx.field_index(expr.hir_id, cx.typeck_results)),
......
......@@ -199,7 +199,7 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
// Skip the following checks if we are not currently in a const context.
_ if self.const_kind.is_none() => {}
hir::ExprKind::Loop(_, _, source) => {
hir::ExprKind::Loop(_, _, source, _) => {
self.const_check_violated(NonConstExpr::Loop(*source), e.span);
}
......
......@@ -844,7 +844,7 @@ fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNod
// Note that labels have been resolved, so we don't need to look
// at the label ident
hir::ExprKind::Loop(ref blk, _, _) => self.propagate_through_loop(expr, &blk, succ),
hir::ExprKind::Loop(ref blk, ..) => self.propagate_through_loop(expr, &blk, succ),
hir::ExprKind::If(ref cond, ref then, ref else_opt) => {
//
......
......@@ -53,7 +53,7 @@ fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
match e.kind {
hir::ExprKind::Loop(ref b, _, source) => {
hir::ExprKind::Loop(ref b, _, source, _) => {
self.with_context(Loop(source), |v| v.visit_block(&b));
}
hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
......@@ -89,8 +89,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
Err(hir::LoopIdError::UnresolvedLabel) => None,
};
if let Some(loop_id) = loop_id {
if let Node::Block(_) = self.hir_map.find(loop_id).unwrap() {
if let Some(Node::Block(_)) = loop_id.and_then(|id| self.hir_map.find(id)) {
return;
}
}
......
......@@ -252,7 +252,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
terminating(then.hir_id.local_id);
}
hir::ExprKind::Loop(ref body, _, _) => {
hir::ExprKind::Loop(ref body, _, _, _) => {
terminating(body.hir_id.local_id);
}
......
......@@ -1173,7 +1173,7 @@ fn visit_expr(&mut self, ex: &hir::Expr<'_>) {
}
fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
if let hir::ExprKind::Loop(_, Some(label), _) = ex.kind { Some(label.ident) } else { None }
if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None }
}
fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {
......
......@@ -266,7 +266,7 @@ fn check_expr_kind(
}
}
ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
ExprKind::Loop(ref body, _, source) => {
ExprKind::Loop(ref body, _, source, _) => {
self.check_expr_loop(body, source, expected, expr)
}
ExprKind::Match(ref discrim, ref arms, match_src) => {
......
......@@ -289,7 +289,7 @@ pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
| hir::ExprKind::ConstBlock(..)
| hir::ExprKind::Err => {}
hir::ExprKind::Loop(ref blk, _, _) => {
hir::ExprKind::Loop(ref blk, ..) => {
self.walk_block(blk);
}
......
......@@ -533,7 +533,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
}
// check for never_loop
if let ExprKind::Loop(ref block, _, _) = expr.kind {
if let ExprKind::Loop(ref block, _, _, _) = expr.kind {
match never_loop_block(block, expr.hir_id) {
NeverLoopResult::AlwaysBreak => span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops"),
NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (),
......@@ -543,7 +543,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// check for `loop { if let {} else break }` that could be `while let`
// (also matches an explicit "match" instead of "if let")
// (even if the "match" or "if let" is used for declaration)
if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind {
if let ExprKind::Loop(ref block, _, LoopSource::Loop, _) = expr.kind {
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
let msg = "empty `loop {}` wastes CPU cycles";
......@@ -738,7 +738,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
| ExprKind::Assign(ref e1, ref e2, _)
| ExprKind::AssignOp(_, ref e1, ref e2)
| ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
ExprKind::Loop(ref b, _, _) => {
ExprKind::Loop(ref b, _, _, _) => {
// Break can come from the inner loop so remove them.
absorb_break(&never_loop_block(b, main_loop_id))
},
......@@ -1314,7 +1314,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
match &expr.kind {
// Non-determinism may occur ... don't give a lint
ExprKind::Loop(_, _, _) | ExprKind::Match(_, _, _) => self.should_lint = false,
ExprKind::Loop(..) | ExprKind::Match(..) => self.should_lint = false,
ExprKind::Block(block, _) => self.visit_block(block),
_ => {},
}
......
......@@ -221,7 +221,7 @@ fn with_loop_block<F>(expr: &ast::Expr, mut func: F)
{
if let ast::ExprKind::While(_, loop_block, label)
| ast::ExprKind::ForLoop(_, _, loop_block, label)
| ast::ExprKind::Loop(loop_block, label) = &expr.kind
| ast::ExprKind::Loop(loop_block, label, _) = &expr.kind
{
func(loop_block, label.as_ref());
}
......
......@@ -325,7 +325,7 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut
| ExprKind::Field(ref e, _)
| ExprKind::AddrOf(_, _, ref e)
| ExprKind::Box(ref e) => check_expr(cx, e, bindings),
ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, _, _) => check_block(cx, block, bindings),
ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, ..) => check_block(cx, block, bindings),
// ExprKind::Call
// ExprKind::MethodCall
ExprKind::Array(v) | ExprKind::Tup(v) => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册