diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2021-01-20 17:15:08 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2021-01-21 21:41:46 -0800 |
| commit | 060dba67b7523a69223a9aef7c9fe2494ec27535 (patch) | |
| tree | fecb07734e8e5b40293546ce53d410972f13316e | |
| parent | a701ff981d8768e2b81a053bf9189ff67a2bb7ea (diff) | |
| download | rust-060dba67b7523a69223a9aef7c9fe2494ec27535.tar.gz rust-060dba67b7523a69223a9aef7c9fe2494ec27535.zip | |
Add loop head span to hir
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/intravisit.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_const.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/loops.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/region.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/expr_use_visitor.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/loops.rs | 8 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/needless_continue.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/shadow.rs | 2 |
15 files changed, 35 insertions, 25 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1b9ccbd850b..31360158e2b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -10,9 +10,9 @@ use rustc_errors::struct_span_err; 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 @@ impl<'hir> LoweringContext<'_, '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 @@ impl<'hir> LoweringContext<'_, 'hir> { 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 @@ impl<'hir> LoweringContext<'_, 'hir> { // 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 @@ impl<'hir> LoweringContext<'_, 'hir> { ); // `[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, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 3673e5c8bf3..35170fa7c1d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 8707a84a98f..6c1bee2335a 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -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); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index a3ab1d96e1d..f1c2a6b7e6e 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1396,7 +1396,7 @@ impl<'a> State<'a> { 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(":"); diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 595458702e9..2962cbe8157 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -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)), diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index c887a860303..8950f9b33b6 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'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); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6202cc312fc..c11dc231d48 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -844,7 +844,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // 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) => { // diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 9b4da71e5e9..ed3bfce510c 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -53,7 +53,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { 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 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, '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; } } diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs index 91421d7f5f2..64356f73f6c 100644 --- a/compiler/rustc_passes/src/region.rs +++ b/compiler/rustc_passes/src/region.rs @@ -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); } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 64cc113dffe..95ac2a31dd3 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1173,7 +1173,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { } 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) { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 8aa6c6d924a..8f463af73c4 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } 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) => { diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 01519e4c8f7..24364c6954e 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Err => {} - hir::ExprKind::Loop(ref blk, _, _) => { + hir::ExprKind::Loop(ref blk, ..) => { self.walk_block(blk); } diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs index 1c5ab2874b0..bbcea387de2 100644 --- a/src/tools/clippy/clippy_lints/src/loops.rs +++ b/src/tools/clippy/clippy_lints/src/loops.rs @@ -533,7 +533,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } // 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 @@ impl<'tcx> LateLintPass<'tcx> for Loops { // 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), _ => {}, } diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs index a971d041ca6..bb4d8483404 100644 --- a/src/tools/clippy/clippy_lints/src/needless_continue.rs +++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs @@ -221,7 +221,7 @@ where { 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()); } diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 24da056770c..d5b1767e945 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -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) => { |
