From d67628e053db3235b9d4d406e4b47113b51a1fad Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Mon, 14 May 2018 23:32:21 -0700 Subject: [PATCH 01/15] Add lint checks for unused loop labels --- src/librustc_lint/lib.rs | 4 +- src/librustc_lint/unused.rs | 63 ++++++++++++++++++++++ src/librustc_mir/interpret/eval_context.rs | 2 +- src/test/ui/lint/unused_loop_label.rs | 55 +++++++++++++++++++ src/test/ui/lint/unused_loop_label.stderr | 32 +++++++++++ src/test/ui/lint/unused_loop_label.stdout | 0 6 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/lint/unused_loop_label.rs create mode 100644 src/test/ui/lint/unused_loop_label.stderr create mode 100644 src/test/ui/lint/unused_loop_label.stdout diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0ae133640fad9..19e0bbd830530 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -110,6 +110,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { add_early_builtin_with_new!(sess, DeprecatedAttr, + UnusedLoopLabel, ); add_builtin!(sess, @@ -177,7 +178,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_DOC_COMMENT, UNUSED_EXTERN_CRATES, UNUSED_FEATURES, - UNUSED_PARENS); + UNUSED_PARENS, + UNUSED_LOOP_LABEL); add_lint_group!(sess, "rust_2018_idioms", diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 845c964b986dd..38c5a36067c46 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -25,6 +25,8 @@ use syntax_pos::Span; use rustc::hir; +use std::vec; + declare_lint! { pub UNUSED_MUST_USE, Warn, @@ -464,3 +466,64 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { } } } + +declare_lint! { + pub(super) UNUSED_LOOP_LABEL, + Warn, + "warns on unused labels for loops" +} + +#[derive(Clone)] +pub struct UnusedLoopLabel(pub vec::Vec); + +impl UnusedLoopLabel { + pub fn new() -> Self { + UnusedLoopLabel(vec![]) + } +} + +impl LintPass for UnusedLoopLabel { + fn get_lints(&self) -> LintArray { + lint_array!(UNUSED_LOOP_LABEL) + } +} + +impl EarlyLintPass for UnusedLoopLabel { + fn check_expr(&mut self, _: &EarlyContext, expr: &ast::Expr) { + match expr.node { + ast::ExprKind::While(_, _, Some(ref label)) + | ast::ExprKind::WhileLet(_, _, _, Some(ref label)) + | ast::ExprKind::ForLoop(_, _, _, Some(ref label)) + | ast::ExprKind::Loop(_, Some(ref label)) => { + self.0.push(*label); + } + ast::ExprKind::Break(Some(ref label), _) | ast::ExprKind::Continue(Some(ref label)) => { + 'remove_used_label: for i in (0..self.0.len()).rev() { + if self.0.get(i).unwrap().ident.name == label.ident.name { + self.0.remove(i); + break 'remove_used_label; + } + } + } + _ => {} + } + } + + fn check_expr_post(&mut self, ctxt: &EarlyContext, expr: &ast::Expr) { + match expr.node { + ast::ExprKind::While(_, _, Some(ref label)) + | ast::ExprKind::WhileLet(_, _, _, Some(ref label)) + | ast::ExprKind::ForLoop(_, _, _, Some(ref label)) + | ast::ExprKind::Loop(_, Some(ref label)) => if !self.0.is_empty() { + { + let unused_label = self.0.last().unwrap(); + if label.ident.name == unused_label.ident.name { + ctxt.span_lint(UNUSED_LOOP_LABEL, label.ident.span, "unused loop label"); + } + } + self.0.pop(); + }, + _ => {} + } + } +} diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 03137619edaf4..7b6cee96a875c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1705,7 +1705,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let mut trace_text = "\n\nAn error occurred in miri:\n".to_string(); backtrace.resolve(); write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap(); - 'frames: for (i, frame) in backtrace.frames().iter().enumerate() { + for (i, frame) in backtrace.frames().iter().enumerate() { if frame.symbols().is_empty() { write!(trace_text, "{}: no symbols\n", i).unwrap(); } diff --git a/src/test/ui/lint/unused_loop_label.rs b/src/test/ui/lint/unused_loop_label.rs new file mode 100644 index 0000000000000..b3142cd863375 --- /dev/null +++ b/src/test/ui/lint/unused_loop_label.rs @@ -0,0 +1,55 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// The output should warn when a loop label is not used. However, it +// should also deal with the edge cases where a label is shadowed, +// within nested loops + +// compile-pass +// compile-flags: -W unused_loop_label + +fn main() { + 'unused_while_label: while 0 == 0 { + //~^ WARN unused loop label + } + + let opt = Some(0); + 'unused_while_let_label: while let Some(_) = opt { + //~^ WARN unused loop label + } + + 'unused_for_label: for _ in 0..10 { + //~^ WARN unused loop label + } + + 'used_loop_label: loop { + break 'used_loop_label; + } + + 'used_loop_label_outer: loop { + 'used_loop_label_inner: loop { + break 'used_loop_label_inner; + } + break 'used_loop_label_outer; + } + + 'unused_loop_label_outer: loop { + 'unused_loop_label_inner: loop { + //~^ WARN unused loop label + break 'unused_loop_label_outer; + } + } + + // This is diverging, so put it at the end so we don't get unreachable_code errors everywhere + // else + 'unused_loop_label: loop { + //~^ WARN unused loop label + } +} diff --git a/src/test/ui/lint/unused_loop_label.stderr b/src/test/ui/lint/unused_loop_label.stderr new file mode 100644 index 0000000000000..4804c268975f7 --- /dev/null +++ b/src/test/ui/lint/unused_loop_label.stderr @@ -0,0 +1,32 @@ +warning: unused loop label + --> $DIR/unused_loop_label.rs:19:5 + | +LL | 'unused_while_label: while 0 == 0 { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-loop-label` + +warning: unused loop label + --> $DIR/unused_loop_label.rs:24:5 + | +LL | 'unused_while_let_label: while let Some(_) = opt { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused loop label + --> $DIR/unused_loop_label.rs:28:5 + | +LL | 'unused_for_label: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^ + +warning: unused loop label + --> $DIR/unused_loop_label.rs:44:9 + | +LL | 'unused_loop_label_inner: loop { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused loop label + --> $DIR/unused_loop_label.rs:52:5 + | +LL | 'unused_loop_label: loop { + | ^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/lint/unused_loop_label.stdout b/src/test/ui/lint/unused_loop_label.stdout new file mode 100644 index 0000000000000..e69de29bb2d1d From 7c4aa7362e9bca54e5bb4f96cc67b4aafe35b33a Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 16:34:08 -0700 Subject: [PATCH 02/15] Rename test to `unused_label` and remove empty `stdout` file --- src/test/ui/lint/{unused_loop_label.rs => unused_label.rs} | 0 .../ui/lint/{unused_loop_label.stderr => unused_label.stderr} | 0 src/test/ui/lint/unused_loop_label.stdout | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/lint/{unused_loop_label.rs => unused_label.rs} (100%) rename src/test/ui/lint/{unused_loop_label.stderr => unused_label.stderr} (100%) delete mode 100644 src/test/ui/lint/unused_loop_label.stdout diff --git a/src/test/ui/lint/unused_loop_label.rs b/src/test/ui/lint/unused_label.rs similarity index 100% rename from src/test/ui/lint/unused_loop_label.rs rename to src/test/ui/lint/unused_label.rs diff --git a/src/test/ui/lint/unused_loop_label.stderr b/src/test/ui/lint/unused_label.stderr similarity index 100% rename from src/test/ui/lint/unused_loop_label.stderr rename to src/test/ui/lint/unused_label.stderr diff --git a/src/test/ui/lint/unused_loop_label.stdout b/src/test/ui/lint/unused_loop_label.stdout deleted file mode 100644 index e69de29bb2d1d..0000000000000 From bb867d3512b009c660f8a9c3154d19e119f7ff5d Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 17:08:24 -0700 Subject: [PATCH 03/15] Add additional test case to unused_label lint --- src/test/ui/lint/unused_label.rs | 25 ++++++++++++++-------- src/test/ui/lint/unused_label.stderr | 32 +++++++++++++++++----------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/test/ui/lint/unused_label.rs b/src/test/ui/lint/unused_label.rs index b3142cd863375..43cf8c75ae3f0 100644 --- a/src/test/ui/lint/unused_label.rs +++ b/src/test/ui/lint/unused_label.rs @@ -33,22 +33,29 @@ fn main() { break 'used_loop_label; } - 'used_loop_label_outer: loop { - 'used_loop_label_inner: loop { - break 'used_loop_label_inner; + 'used_loop_label_outer_1: loop { + 'used_loop_label_inner_1: loop { + break 'used_loop_label_inner_1; } - break 'used_loop_label_outer; + break 'used_loop_label_outer_1; } - 'unused_loop_label_outer: loop { - 'unused_loop_label_inner: loop { + 'used_loop_label_outer_2: loop { + 'unused_loop_label_inner_2: loop { //~^ WARN unused loop label - break 'unused_loop_label_outer; + break 'used_loop_label_outer_2; } } - // This is diverging, so put it at the end so we don't get unreachable_code errors everywhere - // else + 'unused_loop_label_outer_3: loop { + 'used_loop_label_inner_3: loop { + //~^ WARN unused loop label + break 'used_loop_label_inner_3; + } + } + + // This is diverging, so put it at the end so we don't get + // unreachable_code errors everywhere else 'unused_loop_label: loop { //~^ WARN unused loop label } diff --git a/src/test/ui/lint/unused_label.stderr b/src/test/ui/lint/unused_label.stderr index 4804c268975f7..3e7be476e6439 100644 --- a/src/test/ui/lint/unused_label.stderr +++ b/src/test/ui/lint/unused_label.stderr @@ -1,31 +1,37 @@ -warning: unused loop label - --> $DIR/unused_loop_label.rs:19:5 +warning: unused label + --> $DIR/unused_label.rs:19:5 | LL | 'unused_while_label: while 0 == 0 { | ^^^^^^^^^^^^^^^^^^^ | - = note: requested on the command line with `-W unused-loop-label` + = note: requested on the command line with `-W unused-label` -warning: unused loop label - --> $DIR/unused_loop_label.rs:24:5 +warning: unused label + --> $DIR/unused_label.rs:24:5 | LL | 'unused_while_let_label: while let Some(_) = opt { | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: unused loop label - --> $DIR/unused_loop_label.rs:28:5 +warning: unused label + --> $DIR/unused_label.rs:28:5 | LL | 'unused_for_label: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^ -warning: unused loop label - --> $DIR/unused_loop_label.rs:44:9 +warning: unused label + --> $DIR/unused_label.rs:44:9 | -LL | 'unused_loop_label_inner: loop { - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | 'unused_loop_label_inner_2: loop { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: unused loop label - --> $DIR/unused_loop_label.rs:52:5 +warning: unused label + --> $DIR/unused_label.rs:50:9 + | +LL | 'unused_loop_label_outer_3: loop { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_label.rs:52:5 | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ From acd6ab8f0f00365b424ac9cd83d9d08852add0bc Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 17:36:43 -0700 Subject: [PATCH 04/15] Rename `unused_loop_label` to `unused_label` and fix/clean up lint logic --- src/librustc_lint/lib.rs | 6 +-- src/librustc_lint/unused.rs | 55 +++++++++++++--------------- src/test/ui/lint/unused_label.rs | 14 +++---- src/test/ui/lint/unused_label.stderr | 4 +- 4 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 19e0bbd830530..b0a766ec05874 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -110,7 +110,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { add_early_builtin_with_new!(sess, DeprecatedAttr, - UnusedLoopLabel, + UnusedLabel, ); add_builtin!(sess, @@ -178,8 +178,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_DOC_COMMENT, UNUSED_EXTERN_CRATES, UNUSED_FEATURES, - UNUSED_PARENS, - UNUSED_LOOP_LABEL); + UNUSED_LABEL, + UNUSED_PARENS); add_lint_group!(sess, "rust_2018_idioms", diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 38c5a36067c46..61c0485f88615 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -25,8 +25,6 @@ use syntax_pos::Span; use rustc::hir; -use std::vec; - declare_lint! { pub UNUSED_MUST_USE, Warn, @@ -468,41 +466,38 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { } declare_lint! { - pub(super) UNUSED_LOOP_LABEL, + pub(super) UNUSED_LABEL, Warn, - "warns on unused labels for loops" + "warns on unused labels" } #[derive(Clone)] -pub struct UnusedLoopLabel(pub vec::Vec); +pub struct UnusedLabel(pub Vec); -impl UnusedLoopLabel { +impl UnusedLabel { pub fn new() -> Self { - UnusedLoopLabel(vec![]) + UnusedLabel(vec![]) } } -impl LintPass for UnusedLoopLabel { +impl LintPass for UnusedLabel { fn get_lints(&self) -> LintArray { - lint_array!(UNUSED_LOOP_LABEL) + lint_array!(UNUSED_LABEL) } } -impl EarlyLintPass for UnusedLoopLabel { +impl EarlyLintPass for UnusedLabel { fn check_expr(&mut self, _: &EarlyContext, expr: &ast::Expr) { match expr.node { - ast::ExprKind::While(_, _, Some(ref label)) - | ast::ExprKind::WhileLet(_, _, _, Some(ref label)) - | ast::ExprKind::ForLoop(_, _, _, Some(ref label)) - | ast::ExprKind::Loop(_, Some(ref label)) => { - self.0.push(*label); + ast::ExprKind::While(_, _, Some(label)) + | ast::ExprKind::WhileLet(_, _, _, Some(label)) + | ast::ExprKind::ForLoop(_, _, _, Some(label)) + | ast::ExprKind::Loop(_, Some(label)) => { + self.0.push(label); } - ast::ExprKind::Break(Some(ref label), _) | ast::ExprKind::Continue(Some(ref label)) => { - 'remove_used_label: for i in (0..self.0.len()).rev() { - if self.0.get(i).unwrap().ident.name == label.ident.name { - self.0.remove(i); - break 'remove_used_label; - } + ast::ExprKind::Break(Some(label), _) | ast::ExprKind::Continue(Some(label)) => { + if let Some(index) = self.0.iter().rposition(|&l| l.ident == label.ident) { + self.0.remove(index); } } _ => {} @@ -511,17 +506,17 @@ impl EarlyLintPass for UnusedLoopLabel { fn check_expr_post(&mut self, ctxt: &EarlyContext, expr: &ast::Expr) { match expr.node { - ast::ExprKind::While(_, _, Some(ref label)) - | ast::ExprKind::WhileLet(_, _, _, Some(ref label)) - | ast::ExprKind::ForLoop(_, _, _, Some(ref label)) - | ast::ExprKind::Loop(_, Some(ref label)) => if !self.0.is_empty() { - { - let unused_label = self.0.last().unwrap(); - if label.ident.name == unused_label.ident.name { - ctxt.span_lint(UNUSED_LOOP_LABEL, label.ident.span, "unused loop label"); + ast::ExprKind::While(_, _, Some(label)) + | ast::ExprKind::WhileLet(_, _, _, Some(label)) + | ast::ExprKind::ForLoop(_, _, _, Some(label)) + | ast::ExprKind::Loop(_, Some(label)) => { + if let Some(unused_label) = self.0.pop() { + if label.ident == unused_label.ident { + ctxt.span_lint(UNUSED_LABEL, label.ident.span, "unused label"); + } else { + self.0.push(unused_label); } } - self.0.pop(); }, _ => {} } diff --git a/src/test/ui/lint/unused_label.rs b/src/test/ui/lint/unused_label.rs index 43cf8c75ae3f0..ceb70fc542dc0 100644 --- a/src/test/ui/lint/unused_label.rs +++ b/src/test/ui/lint/unused_label.rs @@ -13,20 +13,20 @@ // within nested loops // compile-pass -// compile-flags: -W unused_loop_label +// compile-flags: -W unused-label fn main() { 'unused_while_label: while 0 == 0 { - //~^ WARN unused loop label + //~^ WARN unused label } let opt = Some(0); 'unused_while_let_label: while let Some(_) = opt { - //~^ WARN unused loop label + //~^ WARN unused label } 'unused_for_label: for _ in 0..10 { - //~^ WARN unused loop label + //~^ WARN unused label } 'used_loop_label: loop { @@ -42,14 +42,14 @@ fn main() { 'used_loop_label_outer_2: loop { 'unused_loop_label_inner_2: loop { - //~^ WARN unused loop label + //~^ WARN unused label break 'used_loop_label_outer_2; } } 'unused_loop_label_outer_3: loop { + //~^ WARN unused label 'used_loop_label_inner_3: loop { - //~^ WARN unused loop label break 'used_loop_label_inner_3; } } @@ -57,6 +57,6 @@ fn main() { // This is diverging, so put it at the end so we don't get // unreachable_code errors everywhere else 'unused_loop_label: loop { - //~^ WARN unused loop label + //~^ WARN unused label } } diff --git a/src/test/ui/lint/unused_label.stderr b/src/test/ui/lint/unused_label.stderr index 3e7be476e6439..31f78b28ef5e9 100644 --- a/src/test/ui/lint/unused_label.stderr +++ b/src/test/ui/lint/unused_label.stderr @@ -25,13 +25,13 @@ LL | 'unused_loop_label_inner_2: loop { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_label.rs:50:9 + --> $DIR/unused_label.rs:50:5 | LL | 'unused_loop_label_outer_3: loop { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_label.rs:52:5 + --> $DIR/unused_label.rs:59:5 | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ From 0f274122eef3c69c09c406dff32d695fca5509b3 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 20:17:20 -0700 Subject: [PATCH 05/15] Add test case for shadowed labels, with the inner broken multiple times --- src/test/ui/lint/unused_label.rs | 26 ++++++++++++++++++++------ src/test/ui/lint/unused_label.stderr | 19 +++++++++++++++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/test/ui/lint/unused_label.rs b/src/test/ui/lint/unused_label.rs index ceb70fc542dc0..f19b793546eb1 100644 --- a/src/test/ui/lint/unused_label.rs +++ b/src/test/ui/lint/unused_label.rs @@ -33,27 +33,41 @@ fn main() { break 'used_loop_label; } - 'used_loop_label_outer_1: loop { - 'used_loop_label_inner_1: loop { + 'used_loop_label_outer_1: for _ in 0..10 { + 'used_loop_label_inner_1: for _ in 0..10 { break 'used_loop_label_inner_1; } break 'used_loop_label_outer_1; } - 'used_loop_label_outer_2: loop { - 'unused_loop_label_inner_2: loop { + 'used_loop_label_outer_2: for _ in 0..10 { + 'unused_loop_label_inner_2: for _ in 0..10 { //~^ WARN unused label break 'used_loop_label_outer_2; } } - 'unused_loop_label_outer_3: loop { + 'unused_loop_label_outer_3: for _ in 0..10 { //~^ WARN unused label - 'used_loop_label_inner_3: loop { + 'used_loop_label_inner_3: for _ in 0..10 { break 'used_loop_label_inner_3; } } + // Test breaking many times with the same inner label doesn't break the + // warning on the outer label + 'many_used_shadowed: for _ in 0..10 { + //~^ WARN unused label + 'many_used_shadowed: for _ in 0..10 { + //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope + if 1 % 2 == 0 { + break 'many_used_shadowed; + } else { + break 'many_used_shadowed; + } + } + } + // This is diverging, so put it at the end so we don't get // unreachable_code errors everywhere else 'unused_loop_label: loop { diff --git a/src/test/ui/lint/unused_label.stderr b/src/test/ui/lint/unused_label.stderr index 31f78b28ef5e9..e78df67794218 100644 --- a/src/test/ui/lint/unused_label.stderr +++ b/src/test/ui/lint/unused_label.stderr @@ -21,18 +21,33 @@ LL | 'unused_for_label: for _ in 0..10 { warning: unused label --> $DIR/unused_label.rs:44:9 | -LL | 'unused_loop_label_inner_2: loop { +LL | 'unused_loop_label_inner_2: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label --> $DIR/unused_label.rs:50:5 | -LL | 'unused_loop_label_outer_3: loop { +LL | 'unused_loop_label_outer_3: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label --> $DIR/unused_label.rs:59:5 | +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_label.rs:73:5 + | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ +warning: label name `'many_used_shadowed` shadows a label name that is already in scope + --> $DIR/unused_label.rs:61:9 + | +LL | 'many_used_shadowed: for _ in 0..10 { + | ------------------- first declared here +LL | //~^ WARN unused label +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ lifetime 'many_used_shadowed already in scope + From 4de4e6186417489b37bc73c064b35effe7e4409a Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 20:32:43 -0700 Subject: [PATCH 06/15] Fix ignored unused outer label when inner label shadows and is broken multiple times --- src/librustc_lint/unused.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 61c0485f88615..f55a37697bc3f 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -472,7 +472,7 @@ declare_lint! { } #[derive(Clone)] -pub struct UnusedLabel(pub Vec); +pub struct UnusedLabel(pub Vec<(ast::Label, bool)>); impl UnusedLabel { pub fn new() -> Self { @@ -493,11 +493,11 @@ impl EarlyLintPass for UnusedLabel { | ast::ExprKind::WhileLet(_, _, _, Some(label)) | ast::ExprKind::ForLoop(_, _, _, Some(label)) | ast::ExprKind::Loop(_, Some(label)) => { - self.0.push(label); + self.0.push((label, false)); } ast::ExprKind::Break(Some(label), _) | ast::ExprKind::Continue(Some(label)) => { - if let Some(index) = self.0.iter().rposition(|&l| l.ident == label.ident) { - self.0.remove(index); + if let Some((_, ref mut was_used)) = self.0.iter_mut().rev().find(|(l, _)| label == *l) { + *was_used = true; } } _ => {} @@ -510,11 +510,9 @@ impl EarlyLintPass for UnusedLabel { | ast::ExprKind::WhileLet(_, _, _, Some(label)) | ast::ExprKind::ForLoop(_, _, _, Some(label)) | ast::ExprKind::Loop(_, Some(label)) => { - if let Some(unused_label) = self.0.pop() { - if label.ident == unused_label.ident { + if let Some((_, was_used)) = self.0.pop() { + if !was_used { ctxt.span_lint(UNUSED_LABEL, label.ident.span, "unused label"); - } else { - self.0.push(unused_label); } } }, From 167cedefe63b366278dbd83b533b051cd417fcf0 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Tue, 15 May 2018 20:58:09 -0700 Subject: [PATCH 07/15] Fix formatting in unused label linting to make tidy checks pass --- src/librustc_lint/unused.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index f55a37697bc3f..2321d40f150e1 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -496,7 +496,9 @@ impl EarlyLintPass for UnusedLabel { self.0.push((label, false)); } ast::ExprKind::Break(Some(label), _) | ast::ExprKind::Continue(Some(label)) => { - if let Some((_, ref mut was_used)) = self.0.iter_mut().rev().find(|(l, _)| label == *l) { + if let Some((_, ref mut was_used)) = + self.0.iter_mut().rev().find(|(l, _)| label == *l) + { *was_used = true; } } @@ -515,7 +517,7 @@ impl EarlyLintPass for UnusedLabel { ctxt.span_lint(UNUSED_LABEL, label.ident.span, "unused label"); } } - }, + } _ => {} } } From 7676982e90120cf4edacc6b1ed8a8cebce12b97c Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Thu, 17 May 2018 16:57:46 -0700 Subject: [PATCH 08/15] Revert "Add lint checks for unused loop labels" This functionality is being reimplemented in the resolver phase This reverts commit 503a69e844970476b27bf1ac7be951bb22194f50. --- src/librustc_lint/lib.rs | 2 - src/librustc_lint/unused.rs | 58 ----------------- src/librustc_mir/interpret/eval_context.rs | 2 +- src/test/ui/lint/unused_label.rs | 76 ---------------------- src/test/ui/lint/unused_label.stderr | 53 --------------- 5 files changed, 1 insertion(+), 190 deletions(-) delete mode 100644 src/test/ui/lint/unused_label.rs delete mode 100644 src/test/ui/lint/unused_label.stderr diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index b0a766ec05874..0ae133640fad9 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -110,7 +110,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { add_early_builtin_with_new!(sess, DeprecatedAttr, - UnusedLabel, ); add_builtin!(sess, @@ -178,7 +177,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_DOC_COMMENT, UNUSED_EXTERN_CRATES, UNUSED_FEATURES, - UNUSED_LABEL, UNUSED_PARENS); add_lint_group!(sess, diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 2321d40f150e1..845c964b986dd 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -464,61 +464,3 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { } } } - -declare_lint! { - pub(super) UNUSED_LABEL, - Warn, - "warns on unused labels" -} - -#[derive(Clone)] -pub struct UnusedLabel(pub Vec<(ast::Label, bool)>); - -impl UnusedLabel { - pub fn new() -> Self { - UnusedLabel(vec![]) - } -} - -impl LintPass for UnusedLabel { - fn get_lints(&self) -> LintArray { - lint_array!(UNUSED_LABEL) - } -} - -impl EarlyLintPass for UnusedLabel { - fn check_expr(&mut self, _: &EarlyContext, expr: &ast::Expr) { - match expr.node { - ast::ExprKind::While(_, _, Some(label)) - | ast::ExprKind::WhileLet(_, _, _, Some(label)) - | ast::ExprKind::ForLoop(_, _, _, Some(label)) - | ast::ExprKind::Loop(_, Some(label)) => { - self.0.push((label, false)); - } - ast::ExprKind::Break(Some(label), _) | ast::ExprKind::Continue(Some(label)) => { - if let Some((_, ref mut was_used)) = - self.0.iter_mut().rev().find(|(l, _)| label == *l) - { - *was_used = true; - } - } - _ => {} - } - } - - fn check_expr_post(&mut self, ctxt: &EarlyContext, expr: &ast::Expr) { - match expr.node { - ast::ExprKind::While(_, _, Some(label)) - | ast::ExprKind::WhileLet(_, _, _, Some(label)) - | ast::ExprKind::ForLoop(_, _, _, Some(label)) - | ast::ExprKind::Loop(_, Some(label)) => { - if let Some((_, was_used)) = self.0.pop() { - if !was_used { - ctxt.span_lint(UNUSED_LABEL, label.ident.span, "unused label"); - } - } - } - _ => {} - } - } -} diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 7b6cee96a875c..03137619edaf4 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1705,7 +1705,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let mut trace_text = "\n\nAn error occurred in miri:\n".to_string(); backtrace.resolve(); write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap(); - for (i, frame) in backtrace.frames().iter().enumerate() { + 'frames: for (i, frame) in backtrace.frames().iter().enumerate() { if frame.symbols().is_empty() { write!(trace_text, "{}: no symbols\n", i).unwrap(); } diff --git a/src/test/ui/lint/unused_label.rs b/src/test/ui/lint/unused_label.rs deleted file mode 100644 index f19b793546eb1..0000000000000 --- a/src/test/ui/lint/unused_label.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// The output should warn when a loop label is not used. However, it -// should also deal with the edge cases where a label is shadowed, -// within nested loops - -// compile-pass -// compile-flags: -W unused-label - -fn main() { - 'unused_while_label: while 0 == 0 { - //~^ WARN unused label - } - - let opt = Some(0); - 'unused_while_let_label: while let Some(_) = opt { - //~^ WARN unused label - } - - 'unused_for_label: for _ in 0..10 { - //~^ WARN unused label - } - - 'used_loop_label: loop { - break 'used_loop_label; - } - - 'used_loop_label_outer_1: for _ in 0..10 { - 'used_loop_label_inner_1: for _ in 0..10 { - break 'used_loop_label_inner_1; - } - break 'used_loop_label_outer_1; - } - - 'used_loop_label_outer_2: for _ in 0..10 { - 'unused_loop_label_inner_2: for _ in 0..10 { - //~^ WARN unused label - break 'used_loop_label_outer_2; - } - } - - 'unused_loop_label_outer_3: for _ in 0..10 { - //~^ WARN unused label - 'used_loop_label_inner_3: for _ in 0..10 { - break 'used_loop_label_inner_3; - } - } - - // Test breaking many times with the same inner label doesn't break the - // warning on the outer label - 'many_used_shadowed: for _ in 0..10 { - //~^ WARN unused label - 'many_used_shadowed: for _ in 0..10 { - //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope - if 1 % 2 == 0 { - break 'many_used_shadowed; - } else { - break 'many_used_shadowed; - } - } - } - - // This is diverging, so put it at the end so we don't get - // unreachable_code errors everywhere else - 'unused_loop_label: loop { - //~^ WARN unused label - } -} diff --git a/src/test/ui/lint/unused_label.stderr b/src/test/ui/lint/unused_label.stderr deleted file mode 100644 index e78df67794218..0000000000000 --- a/src/test/ui/lint/unused_label.stderr +++ /dev/null @@ -1,53 +0,0 @@ -warning: unused label - --> $DIR/unused_label.rs:19:5 - | -LL | 'unused_while_label: while 0 == 0 { - | ^^^^^^^^^^^^^^^^^^^ - | - = note: requested on the command line with `-W unused-label` - -warning: unused label - --> $DIR/unused_label.rs:24:5 - | -LL | 'unused_while_let_label: while let Some(_) = opt { - | ^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused label - --> $DIR/unused_label.rs:28:5 - | -LL | 'unused_for_label: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^ - -warning: unused label - --> $DIR/unused_label.rs:44:9 - | -LL | 'unused_loop_label_inner_2: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused label - --> $DIR/unused_label.rs:50:5 - | -LL | 'unused_loop_label_outer_3: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: unused label - --> $DIR/unused_label.rs:59:5 - | -LL | 'many_used_shadowed: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^ - -warning: unused label - --> $DIR/unused_label.rs:73:5 - | -LL | 'unused_loop_label: loop { - | ^^^^^^^^^^^^^^^^^^ - -warning: label name `'many_used_shadowed` shadows a label name that is already in scope - --> $DIR/unused_label.rs:61:9 - | -LL | 'many_used_shadowed: for _ in 0..10 { - | ------------------- first declared here -LL | //~^ WARN unused label -LL | 'many_used_shadowed: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^ lifetime 'many_used_shadowed already in scope - From 88f4063c8320f8c0b6a9cc047887b63da1490ffb Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Thu, 17 May 2018 17:20:30 -0700 Subject: [PATCH 09/15] Reimplement unused_labels lint as a compiler builtin in the resolver --- src/librustc/lint/builtin.rs | 7 ++ src/librustc_resolve/check_unused.rs | 4 + src/librustc_resolve/lib.rs | 12 ++- src/test/ui/lint/unused_labels.rs | 75 +++++++++++++++++++ src/test/ui/lint/unused_labels.stderr | 53 +++++++++++++ .../ui/loops-reject-duplicate-labels-2.rs | 1 + .../ui/loops-reject-duplicate-labels-2.stderr | 18 ++--- src/test/ui/loops-reject-duplicate-labels.rs | 1 + .../ui/loops-reject-duplicate-labels.stderr | 18 ++--- src/test/ui/suggestions/suggest-labels.rs | 2 +- 10 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/lint/unused_labels.rs create mode 100644 src/test/ui/lint/unused_labels.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c55c71f85dab7..71eefec2210e4 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -279,6 +279,12 @@ declare_lint! { "detects name collision with an existing but unstable method" } +declare_lint! { + pub UNUSED_LABELS, + Warn, + "detects labels that are never used" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -325,6 +331,7 @@ impl LintPass for HardwiredLints { UNUSED_MUT, SINGLE_USE_LIFETIME, UNUSED_LIFETIME, + UNUSED_LABELS, TYVAR_BEHIND_RAW_POINTER, ELIDED_LIFETIME_IN_PATH, BARE_TRAIT_OBJECT, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 163f6a64010b5..590ce168d5d0f 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -142,6 +142,10 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { } } + for (id, span) in resolver.unused_labels.iter() { + resolver.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); + } + let mut visitor = UnusedImportCheckVisitor { resolver, unused_imports: NodeMap(), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e13e6bc6b7456..feb5af571e435 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1473,6 +1473,10 @@ pub struct Resolver<'a> { pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, + /// A list of labels as of yet unused. Labels will be removed from this map when + /// they are used (in a `break` or `continue` statement) + pub unused_labels: FxHashMap, + /// privacy errors are delayed until the end in order to deduplicate them privacy_errors: Vec>, /// ambiguity errors are delayed for deduplication @@ -1752,6 +1756,8 @@ impl<'a> Resolver<'a> { maybe_unused_trait_imports: NodeSet(), maybe_unused_extern_crates: Vec::new(), + unused_labels: FxHashMap(), + privacy_errors: Vec::new(), ambiguity_errors: Vec::new(), use_injections: Vec::new(), @@ -3694,6 +3700,7 @@ impl<'a> Resolver<'a> { where F: FnOnce(&mut Resolver) { if let Some(label) = label { + self.unused_labels.insert(id, label.ident.span); let def = Def::Label(id); self.with_label_rib(|this| { this.label_ribs.last_mut().unwrap().bindings.insert(label.ident, def); @@ -3742,9 +3749,10 @@ impl<'a> Resolver<'a> { ResolutionError::UndeclaredLabel(&label.ident.name.as_str(), close_match)); } - Some(def @ Def::Label(_)) => { + Some(Def::Label(id)) => { // Since this def is a label, it is never read. - self.record_def(expr.id, PathResolution::new(def)); + self.record_def(expr.id, PathResolution::new(Def::Label(id))); + self.unused_labels.remove(&id); } Some(_) => { span_bug!(expr.span, "label wasn't mapped to a label def!"); diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs new file mode 100644 index 0000000000000..86abb34658a39 --- /dev/null +++ b/src/test/ui/lint/unused_labels.rs @@ -0,0 +1,75 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// The output should warn when a loop label is not used. However, it +// should also deal with the edge cases where a label is shadowed, +// within nested loops + +// compile-pass + +fn main() { + 'unused_while_label: while 0 == 0 { + //~^ WARN unused label + } + + let opt = Some(0); + 'unused_while_let_label: while let Some(_) = opt { + //~^ WARN unused label + } + + 'unused_for_label: for _ in 0..10 { + //~^ WARN unused label + } + + 'used_loop_label: loop { + break 'used_loop_label; + } + + 'used_loop_label_outer_1: for _ in 0..10 { + 'used_loop_label_inner_1: for _ in 0..10 { + break 'used_loop_label_inner_1; + } + break 'used_loop_label_outer_1; + } + + 'used_loop_label_outer_2: for _ in 0..10 { + 'unused_loop_label_inner_2: for _ in 0..10 { + //~^ WARN unused label + break 'used_loop_label_outer_2; + } + } + + 'unused_loop_label_outer_3: for _ in 0..10 { + //~^ WARN unused label + 'used_loop_label_inner_3: for _ in 0..10 { + break 'used_loop_label_inner_3; + } + } + + // Test breaking many times with the same inner label doesn't break the + // warning on the outer label + 'many_used_shadowed: for _ in 0..10 { + //~^ WARN unused label + 'many_used_shadowed: for _ in 0..10 { + //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope + if 1 % 2 == 0 { + break 'many_used_shadowed; + } else { + break 'many_used_shadowed; + } + } + } + + // This is diverging, so put it at the end so we don't get + // unreachable_code errors everywhere else + 'unused_loop_label: loop { + //~^ WARN unused label + } +} diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr new file mode 100644 index 0000000000000..425b0b1769dc7 --- /dev/null +++ b/src/test/ui/lint/unused_labels.stderr @@ -0,0 +1,53 @@ +warning: unused label + --> $DIR/unused_labels.rs:18:5 + | +LL | 'unused_while_label: while 0 == 0 { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(unused_labels)] on by default + +warning: unused label + --> $DIR/unused_labels.rs:23:5 + | +LL | 'unused_while_let_label: while let Some(_) = opt { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_labels.rs:27:5 + | +LL | 'unused_for_label: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_labels.rs:43:9 + | +LL | 'unused_loop_label_inner_2: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_labels.rs:49:5 + | +LL | 'unused_loop_label_outer_3: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_labels.rs:58:5 + | +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ + +warning: unused label + --> $DIR/unused_labels.rs:72:5 + | +LL | 'unused_loop_label: loop { + | ^^^^^^^^^^^^^^^^^^ + +warning: label name `'many_used_shadowed` shadows a label name that is already in scope + --> $DIR/unused_labels.rs:60:9 + | +LL | 'many_used_shadowed: for _ in 0..10 { + | ------------------- first declared here +LL | //~^ WARN unused label +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ lifetime 'many_used_shadowed already in scope + diff --git a/src/test/ui/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops-reject-duplicate-labels-2.rs index 598c7370b8906..b273e7a0c7c9e 100644 --- a/src/test/ui/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops-reject-duplicate-labels-2.rs @@ -18,6 +18,7 @@ // discussed here: // https://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833 +#[allow(unused_labels)] pub fn foo() { { 'fl: for _ in 0..10 { break; } } { 'fl: loop { break; } } //~ WARN label name `'fl` shadows a label name that is already in scope diff --git a/src/test/ui/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops-reject-duplicate-labels-2.stderr index 830270a99d112..41b4a850f1bfb 100644 --- a/src/test/ui/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops-reject-duplicate-labels-2.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:23:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:24:7 | LL | { 'fl: for _ in 0..10 { break; } } | --- first declared here @@ -7,7 +7,7 @@ LL | { 'fl: loop { break; } } //~ WARN label name `'fl` shadows | ^^^ lifetime 'fl already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:25:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:26:7 | LL | { 'lf: loop { break; } } | --- first declared here @@ -15,7 +15,7 @@ LL | { 'lf: for _ in 0..10 { break; } } //~ WARN label name `'lf` shadows | ^^^ lifetime 'lf already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:27:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:28:7 | LL | { 'wl: while 2 > 1 { break; } } | --- first declared here @@ -23,7 +23,7 @@ LL | { 'wl: loop { break; } } //~ WARN label name `'wl` shadows | ^^^ lifetime 'wl already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:29:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:30:7 | LL | { 'lw: loop { break; } } | --- first declared here @@ -31,7 +31,7 @@ LL | { 'lw: while 2 > 1 { break; } } //~ WARN label name `'lw` shadows | ^^^ lifetime 'lw already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:31:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:32:7 | LL | { 'fw: for _ in 0..10 { break; } } | --- first declared here @@ -39,7 +39,7 @@ LL | { 'fw: while 2 > 1 { break; } } //~ WARN label name `'fw` shadows | ^^^ lifetime 'fw already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:33:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:34:7 | LL | { 'wf: while 2 > 1 { break; } } | --- first declared here @@ -47,7 +47,7 @@ LL | { 'wf: for _ in 0..10 { break; } } //~ WARN label name `'wf` shadows | ^^^ lifetime 'wf already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:35:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:36:7 | LL | { 'tl: while let Some(_) = None:: { break; } } | --- first declared here @@ -55,7 +55,7 @@ LL | { 'tl: loop { break; } } //~ WARN label name `'tl` shadows | ^^^ lifetime 'tl already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:37:7 + --> $DIR/loops-reject-duplicate-labels-2.rs:38:7 | LL | { 'lt: loop { break; } } | --- first declared here @@ -63,7 +63,7 @@ LL | { 'lt: while let Some(_) = None:: { break; } } | ^^^ lifetime 'lt already in scope error: compilation successful - --> $DIR/loops-reject-duplicate-labels-2.rs:42:1 + --> $DIR/loops-reject-duplicate-labels-2.rs:43:1 | LL | / pub fn main() { //~ ERROR compilation successful LL | | foo(); diff --git a/src/test/ui/loops-reject-duplicate-labels.rs b/src/test/ui/loops-reject-duplicate-labels.rs index d768b002ab10c..ad24f69871c85 100644 --- a/src/test/ui/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops-reject-duplicate-labels.rs @@ -15,6 +15,7 @@ // Issue #21633: reject duplicate loop labels in function bodies. // This is testing the exact cases that are in the issue description. +#[allow(unused_labels)] fn foo() { 'fl: for _ in 0..10 { break; } 'fl: loop { break; } //~ WARN label name `'fl` shadows a label name that is already in scope diff --git a/src/test/ui/loops-reject-duplicate-labels.stderr b/src/test/ui/loops-reject-duplicate-labels.stderr index a71f98b812a8c..d0cb81544f828 100644 --- a/src/test/ui/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops-reject-duplicate-labels.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:20:5 + --> $DIR/loops-reject-duplicate-labels.rs:21:5 | LL | 'fl: for _ in 0..10 { break; } | --- first declared here @@ -7,7 +7,7 @@ LL | 'fl: loop { break; } //~ WARN label name `'fl` shadows a labe | ^^^ lifetime 'fl already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:23:5 + --> $DIR/loops-reject-duplicate-labels.rs:24:5 | LL | 'lf: loop { break; } | --- first declared here @@ -15,7 +15,7 @@ LL | 'lf: for _ in 0..10 { break; } //~ WARN label name `'lf` shadows a labe | ^^^ lifetime 'lf already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:25:5 + --> $DIR/loops-reject-duplicate-labels.rs:26:5 | LL | 'wl: while 2 > 1 { break; } | --- first declared here @@ -23,7 +23,7 @@ LL | 'wl: loop { break; } //~ WARN label name `'wl` shadows a labe | ^^^ lifetime 'wl already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:27:5 + --> $DIR/loops-reject-duplicate-labels.rs:28:5 | LL | 'lw: loop { break; } | --- first declared here @@ -31,7 +31,7 @@ LL | 'lw: while 2 > 1 { break; } //~ WARN label name `'lw` shadows a labe | ^^^ lifetime 'lw already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:29:5 + --> $DIR/loops-reject-duplicate-labels.rs:30:5 | LL | 'fw: for _ in 0..10 { break; } | --- first declared here @@ -39,7 +39,7 @@ LL | 'fw: while 2 > 1 { break; } //~ WARN label name `'fw` shadows a labe | ^^^ lifetime 'fw already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:31:5 + --> $DIR/loops-reject-duplicate-labels.rs:32:5 | LL | 'wf: while 2 > 1 { break; } | --- first declared here @@ -47,7 +47,7 @@ LL | 'wf: for _ in 0..10 { break; } //~ WARN label name `'wf` shadows a labe | ^^^ lifetime 'wf already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:33:5 + --> $DIR/loops-reject-duplicate-labels.rs:34:5 | LL | 'tl: while let Some(_) = None:: { break; } | --- first declared here @@ -55,7 +55,7 @@ LL | 'tl: loop { break; } //~ WARN label name `'tl` shadows a labe | ^^^ lifetime 'tl already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:35:5 + --> $DIR/loops-reject-duplicate-labels.rs:36:5 | LL | 'lt: loop { break; } | --- first declared here @@ -63,7 +63,7 @@ LL | 'lt: while let Some(_) = None:: { break; } | ^^^ lifetime 'lt already in scope error: compilation successful - --> $DIR/loops-reject-duplicate-labels.rs:49:1 + --> $DIR/loops-reject-duplicate-labels.rs:50:1 | LL | / pub fn main() { //~ ERROR compilation successful LL | | let s = S; diff --git a/src/test/ui/suggestions/suggest-labels.rs b/src/test/ui/suggestions/suggest-labels.rs index 8c97301f40b91..9fb519c57edf3 100644 --- a/src/test/ui/suggestions/suggest-labels.rs +++ b/src/test/ui/suggestions/suggest-labels.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(unreachable_code)] +#[allow(unreachable_code, unused_labels)] fn main() { 'foo: loop { break 'fo; //~ ERROR use of undeclared label From 702f1dd8469bd7710f320d48749dc1d69ffca808 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Thu, 17 May 2018 17:32:05 -0700 Subject: [PATCH 10/15] Add tests for new labeled blocks for `unused_labels` --- src/test/ui/label_break_value_continue.rs | 1 + src/test/ui/label_break_value_continue.stderr | 8 ++++---- .../ui/label_break_value_unlabeled_break.rs | 1 + .../label_break_value_unlabeled_break.stderr | 4 ++-- src/test/ui/lint/unused_labels.rs | 15 ++++++++++++-- src/test/ui/lint/unused_labels.stderr | 20 ++++++++++++------- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/test/ui/label_break_value_continue.rs b/src/test/ui/label_break_value_continue.rs index 52e24b759d1d2..4a505dff3d467 100644 --- a/src/test/ui/label_break_value_continue.rs +++ b/src/test/ui/label_break_value_continue.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(label_break_value)] +#![allow(unused_labels)] // Simple continue pointing to an unlabeled break should yield in an error fn continue_simple() { diff --git a/src/test/ui/label_break_value_continue.stderr b/src/test/ui/label_break_value_continue.stderr index 24c2d1a22d01c..12a21a8a59441 100644 --- a/src/test/ui/label_break_value_continue.stderr +++ b/src/test/ui/label_break_value_continue.stderr @@ -1,17 +1,17 @@ error[E0695]: unlabeled `continue` inside of a labeled block - --> $DIR/label_break_value_continue.rs:16:9 + --> $DIR/label_break_value_continue.rs:17:9 | LL | continue; //~ ERROR unlabeled `continue` inside of a labeled block | ^^^^^^^^ `continue` statements that would diverge to or through a labeled block need to bear a label error[E0696]: `continue` pointing to a labeled block - --> $DIR/label_break_value_continue.rs:23:9 + --> $DIR/label_break_value_continue.rs:24:9 | LL | continue 'b; //~ ERROR `continue` pointing to a labeled block | ^^^^^^^^^^^ labeled blocks cannot be `continue`'d | note: labeled block the continue points to - --> $DIR/label_break_value_continue.rs:22:5 + --> $DIR/label_break_value_continue.rs:23:5 | LL | / 'b: { LL | | continue 'b; //~ ERROR `continue` pointing to a labeled block @@ -19,7 +19,7 @@ LL | | } | |_____^ error[E0695]: unlabeled `continue` inside of a labeled block - --> $DIR/label_break_value_continue.rs:31:13 + --> $DIR/label_break_value_continue.rs:32:13 | LL | continue; //~ ERROR unlabeled `continue` inside of a labeled block | ^^^^^^^^ `continue` statements that would diverge to or through a labeled block need to bear a label diff --git a/src/test/ui/label_break_value_unlabeled_break.rs b/src/test/ui/label_break_value_unlabeled_break.rs index 38918da291c86..454ebd4c6cf6d 100644 --- a/src/test/ui/label_break_value_unlabeled_break.rs +++ b/src/test/ui/label_break_value_unlabeled_break.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(label_break_value)] +#![allow(unused_labels)] // Simple unlabeled break should yield in an error fn unlabeled_break_simple() { diff --git a/src/test/ui/label_break_value_unlabeled_break.stderr b/src/test/ui/label_break_value_unlabeled_break.stderr index 8a25975a7bda2..62c4a12231baf 100644 --- a/src/test/ui/label_break_value_unlabeled_break.stderr +++ b/src/test/ui/label_break_value_unlabeled_break.stderr @@ -1,11 +1,11 @@ error[E0695]: unlabeled `break` inside of a labeled block - --> $DIR/label_break_value_unlabeled_break.rs:16:9 + --> $DIR/label_break_value_unlabeled_break.rs:17:9 | LL | break; //~ ERROR unlabeled `break` inside of a labeled block | ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label error[E0695]: unlabeled `break` inside of a labeled block - --> $DIR/label_break_value_unlabeled_break.rs:24:13 + --> $DIR/label_break_value_unlabeled_break.rs:25:13 | LL | break; //~ ERROR unlabeled `break` inside of a labeled block | ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index 86abb34658a39..22b7ad4e6a7c9 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -14,6 +14,8 @@ // compile-pass +#![feature(label_break_value)] + fn main() { 'unused_while_label: while 0 == 0 { //~^ WARN unused label @@ -67,9 +69,18 @@ fn main() { } } - // This is diverging, so put it at the end so we don't get - // unreachable_code errors everywhere else 'unused_loop_label: loop { //~^ WARN unused label + break; + } + + // Make sure unused block labels give warnings... + 'unused_block_label: { + //~^ WARN unused label + } + + // ...and that used ones don't: + 'used_block_label: { + break 'used_block_label; } } diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr index 425b0b1769dc7..d09209853e3a3 100644 --- a/src/test/ui/lint/unused_labels.stderr +++ b/src/test/ui/lint/unused_labels.stderr @@ -1,5 +1,5 @@ warning: unused label - --> $DIR/unused_labels.rs:18:5 + --> $DIR/unused_labels.rs:20:5 | LL | 'unused_while_label: while 0 == 0 { | ^^^^^^^^^^^^^^^^^^^ @@ -7,31 +7,31 @@ LL | 'unused_while_label: while 0 == 0 { = note: #[warn(unused_labels)] on by default warning: unused label - --> $DIR/unused_labels.rs:23:5 + --> $DIR/unused_labels.rs:25:5 | LL | 'unused_while_let_label: while let Some(_) = opt { | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:27:5 + --> $DIR/unused_labels.rs:29:5 | LL | 'unused_for_label: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:43:9 + --> $DIR/unused_labels.rs:45:9 | LL | 'unused_loop_label_inner_2: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:49:5 + --> $DIR/unused_labels.rs:51:5 | LL | 'unused_loop_label_outer_3: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:58:5 + --> $DIR/unused_labels.rs:60:5 | LL | 'many_used_shadowed: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^ @@ -42,8 +42,14 @@ warning: unused label LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ +warning: unused label + --> $DIR/unused_labels.rs:78:5 + | +LL | 'unused_block_label: { + | ^^^^^^^^^^^^^^^^^^^ + warning: label name `'many_used_shadowed` shadows a label name that is already in scope - --> $DIR/unused_labels.rs:60:9 + --> $DIR/unused_labels.rs:62:9 | LL | 'many_used_shadowed: for _ in 0..10 { | ------------------- first declared here From f488d2b3930c6ef07313373c119318aa509610c4 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Thu, 17 May 2018 17:58:16 -0700 Subject: [PATCH 11/15] Remove unused label in mir --- src/librustc_mir/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 03137619edaf4..7b6cee96a875c 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1705,7 +1705,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let mut trace_text = "\n\nAn error occurred in miri:\n".to_string(); backtrace.resolve(); write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap(); - 'frames: for (i, frame) in backtrace.frames().iter().enumerate() { + for (i, frame) in backtrace.frames().iter().enumerate() { if frame.symbols().is_empty() { write!(trace_text, "{}: no symbols\n", i).unwrap(); } From a336aa91db3a21dbbe5d281ece712535b1c9ed7d Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Thu, 17 May 2018 22:17:06 -0700 Subject: [PATCH 12/15] Allow `unused_labels` in some compile-fail tests --- src/test/compile-fail/associated-types-outlives.rs | 1 + src/test/compile-fail/hygienic-label-1.rs | 1 + src/test/compile-fail/hygienic-label-2.rs | 5 ++++- src/test/compile-fail/hygienic-label-3.rs | 1 + src/test/compile-fail/hygienic-label-4.rs | 5 ++++- src/test/compile-fail/issue-27042.rs | 1 + src/test/compile-fail/issue-46311.rs | 1 + src/test/compile-fail/loop-break-value.rs | 1 + src/test/compile-fail/loop-proper-liveness.rs | 1 + src/test/compile-fail/resolve-label.rs | 1 + 10 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/associated-types-outlives.rs b/src/test/compile-fail/associated-types-outlives.rs index f070ab6799c08..1b255c149ccd0 100644 --- a/src/test/compile-fail/associated-types-outlives.rs +++ b/src/test/compile-fail/associated-types-outlives.rs @@ -27,6 +27,7 @@ fn denormalise<'a, T>(t: &'a T) -> >::Bar { pub fn free_and_use Foo<'a>, F: for<'a> FnOnce(>::Bar)>(x: T, f: F) { let y; + #[allow(unused_labels)] 'body: loop { // lifetime annotations added for clarity 's: loop { y = denormalise(&x); break } drop(x); //~ ERROR cannot move out of `x` because it is borrowed diff --git a/src/test/compile-fail/hygienic-label-1.rs b/src/test/compile-fail/hygienic-label-1.rs index 305b43402da0b..f2b8b79b099e2 100644 --- a/src/test/compile-fail/hygienic-label-1.rs +++ b/src/test/compile-fail/hygienic-label-1.rs @@ -13,5 +13,6 @@ macro_rules! foo { } pub fn main() { + #[allow(unused_labels)] 'x: loop { foo!() } } diff --git a/src/test/compile-fail/hygienic-label-2.rs b/src/test/compile-fail/hygienic-label-2.rs index 24194d7bbe970..554dc190fcd3a 100644 --- a/src/test/compile-fail/hygienic-label-2.rs +++ b/src/test/compile-fail/hygienic-label-2.rs @@ -9,7 +9,10 @@ // except according to those terms. macro_rules! foo { - ($e: expr) => { 'x: loop { $e } } + ($e: expr) => { + #[allow(unused_labels)] + 'x: loop { $e } + } } pub fn main() { diff --git a/src/test/compile-fail/hygienic-label-3.rs b/src/test/compile-fail/hygienic-label-3.rs index b107b71024dad..0f819b7c6bb8e 100644 --- a/src/test/compile-fail/hygienic-label-3.rs +++ b/src/test/compile-fail/hygienic-label-3.rs @@ -13,6 +13,7 @@ macro_rules! foo { } pub fn main() { + #[allow(unused_labels)] 'x: for _ in 0..1 { foo!() }; diff --git a/src/test/compile-fail/hygienic-label-4.rs b/src/test/compile-fail/hygienic-label-4.rs index 5bfcb6360e452..9936699cb466c 100644 --- a/src/test/compile-fail/hygienic-label-4.rs +++ b/src/test/compile-fail/hygienic-label-4.rs @@ -9,7 +9,10 @@ // except according to those terms. macro_rules! foo { - ($e: expr) => { 'x: for _ in 0..1 { $e } } + ($e: expr) => { + #[allow(unused_labels)] + 'x: for _ in 0..1 { $e } + } } pub fn main() { diff --git a/src/test/compile-fail/issue-27042.rs b/src/test/compile-fail/issue-27042.rs index 23afa4b629636..79ce9fb784961 100644 --- a/src/test/compile-fail/issue-27042.rs +++ b/src/test/compile-fail/issue-27042.rs @@ -10,6 +10,7 @@ // Regression test for #27042. Test that a loop's label is included in its span. +#[allow(unused_labels)] fn main() { let _: i32 = 'a: // in this case, the citation is just the `break`: diff --git a/src/test/compile-fail/issue-46311.rs b/src/test/compile-fail/issue-46311.rs index 82f55f2c14241..0815712f0670a 100644 --- a/src/test/compile-fail/issue-46311.rs +++ b/src/test/compile-fail/issue-46311.rs @@ -9,6 +9,7 @@ // except according to those terms. fn main() { + #[allow(unused_labels)] 'break: loop { //~ ERROR invalid label name `'break` } } diff --git a/src/test/compile-fail/loop-break-value.rs b/src/test/compile-fail/loop-break-value.rs index 938f7fba2a032..60478974e8042 100644 --- a/src/test/compile-fail/loop-break-value.rs +++ b/src/test/compile-fail/loop-break-value.rs @@ -77,6 +77,7 @@ fn main() { } let _: i32 = 'a: loop { + #[allow(unused_labels)] let _: () = 'b: loop { break ('c: loop { break; diff --git a/src/test/compile-fail/loop-proper-liveness.rs b/src/test/compile-fail/loop-proper-liveness.rs index e411313c273b7..b53b48ee5ed93 100644 --- a/src/test/compile-fail/loop-proper-liveness.rs +++ b/src/test/compile-fail/loop-proper-liveness.rs @@ -32,6 +32,7 @@ fn test2() { fn test3() { let x: i32; // Similarly, the use of variable `x` is unreachable. + #[allow(unused_labels)] 'a: loop { x = loop { return }; } diff --git a/src/test/compile-fail/resolve-label.rs b/src/test/compile-fail/resolve-label.rs index 6695e972f3337..3d6616edbb576 100644 --- a/src/test/compile-fail/resolve-label.rs +++ b/src/test/compile-fail/resolve-label.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(unused_labels)] fn f() { 'l: loop { fn g() { From 335f91fd69d70ac9c5414d310a8342daed456df3 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Fri, 18 May 2018 07:11:44 -0700 Subject: [PATCH 13/15] Revert "Allow `unused_labels` in some compile-fail tests" This reverts commit b9257e2ca161b1bf5aae9d6b667f4d0c6b8d7be6. --- src/test/compile-fail/associated-types-outlives.rs | 1 - src/test/compile-fail/hygienic-label-1.rs | 1 - src/test/compile-fail/hygienic-label-2.rs | 5 +---- src/test/compile-fail/hygienic-label-3.rs | 1 - src/test/compile-fail/hygienic-label-4.rs | 5 +---- src/test/compile-fail/issue-27042.rs | 1 - src/test/compile-fail/issue-46311.rs | 1 - src/test/compile-fail/loop-break-value.rs | 1 - src/test/compile-fail/loop-proper-liveness.rs | 1 - src/test/compile-fail/resolve-label.rs | 1 - 10 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/test/compile-fail/associated-types-outlives.rs b/src/test/compile-fail/associated-types-outlives.rs index 1b255c149ccd0..f070ab6799c08 100644 --- a/src/test/compile-fail/associated-types-outlives.rs +++ b/src/test/compile-fail/associated-types-outlives.rs @@ -27,7 +27,6 @@ fn denormalise<'a, T>(t: &'a T) -> >::Bar { pub fn free_and_use Foo<'a>, F: for<'a> FnOnce(>::Bar)>(x: T, f: F) { let y; - #[allow(unused_labels)] 'body: loop { // lifetime annotations added for clarity 's: loop { y = denormalise(&x); break } drop(x); //~ ERROR cannot move out of `x` because it is borrowed diff --git a/src/test/compile-fail/hygienic-label-1.rs b/src/test/compile-fail/hygienic-label-1.rs index f2b8b79b099e2..305b43402da0b 100644 --- a/src/test/compile-fail/hygienic-label-1.rs +++ b/src/test/compile-fail/hygienic-label-1.rs @@ -13,6 +13,5 @@ macro_rules! foo { } pub fn main() { - #[allow(unused_labels)] 'x: loop { foo!() } } diff --git a/src/test/compile-fail/hygienic-label-2.rs b/src/test/compile-fail/hygienic-label-2.rs index 554dc190fcd3a..24194d7bbe970 100644 --- a/src/test/compile-fail/hygienic-label-2.rs +++ b/src/test/compile-fail/hygienic-label-2.rs @@ -9,10 +9,7 @@ // except according to those terms. macro_rules! foo { - ($e: expr) => { - #[allow(unused_labels)] - 'x: loop { $e } - } + ($e: expr) => { 'x: loop { $e } } } pub fn main() { diff --git a/src/test/compile-fail/hygienic-label-3.rs b/src/test/compile-fail/hygienic-label-3.rs index 0f819b7c6bb8e..b107b71024dad 100644 --- a/src/test/compile-fail/hygienic-label-3.rs +++ b/src/test/compile-fail/hygienic-label-3.rs @@ -13,7 +13,6 @@ macro_rules! foo { } pub fn main() { - #[allow(unused_labels)] 'x: for _ in 0..1 { foo!() }; diff --git a/src/test/compile-fail/hygienic-label-4.rs b/src/test/compile-fail/hygienic-label-4.rs index 9936699cb466c..5bfcb6360e452 100644 --- a/src/test/compile-fail/hygienic-label-4.rs +++ b/src/test/compile-fail/hygienic-label-4.rs @@ -9,10 +9,7 @@ // except according to those terms. macro_rules! foo { - ($e: expr) => { - #[allow(unused_labels)] - 'x: for _ in 0..1 { $e } - } + ($e: expr) => { 'x: for _ in 0..1 { $e } } } pub fn main() { diff --git a/src/test/compile-fail/issue-27042.rs b/src/test/compile-fail/issue-27042.rs index 79ce9fb784961..23afa4b629636 100644 --- a/src/test/compile-fail/issue-27042.rs +++ b/src/test/compile-fail/issue-27042.rs @@ -10,7 +10,6 @@ // Regression test for #27042. Test that a loop's label is included in its span. -#[allow(unused_labels)] fn main() { let _: i32 = 'a: // in this case, the citation is just the `break`: diff --git a/src/test/compile-fail/issue-46311.rs b/src/test/compile-fail/issue-46311.rs index 0815712f0670a..82f55f2c14241 100644 --- a/src/test/compile-fail/issue-46311.rs +++ b/src/test/compile-fail/issue-46311.rs @@ -9,7 +9,6 @@ // except according to those terms. fn main() { - #[allow(unused_labels)] 'break: loop { //~ ERROR invalid label name `'break` } } diff --git a/src/test/compile-fail/loop-break-value.rs b/src/test/compile-fail/loop-break-value.rs index 60478974e8042..938f7fba2a032 100644 --- a/src/test/compile-fail/loop-break-value.rs +++ b/src/test/compile-fail/loop-break-value.rs @@ -77,7 +77,6 @@ fn main() { } let _: i32 = 'a: loop { - #[allow(unused_labels)] let _: () = 'b: loop { break ('c: loop { break; diff --git a/src/test/compile-fail/loop-proper-liveness.rs b/src/test/compile-fail/loop-proper-liveness.rs index b53b48ee5ed93..e411313c273b7 100644 --- a/src/test/compile-fail/loop-proper-liveness.rs +++ b/src/test/compile-fail/loop-proper-liveness.rs @@ -32,7 +32,6 @@ fn test2() { fn test3() { let x: i32; // Similarly, the use of variable `x` is unreachable. - #[allow(unused_labels)] 'a: loop { x = loop { return }; } diff --git a/src/test/compile-fail/resolve-label.rs b/src/test/compile-fail/resolve-label.rs index 3d6616edbb576..6695e972f3337 100644 --- a/src/test/compile-fail/resolve-label.rs +++ b/src/test/compile-fail/resolve-label.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(unused_labels)] fn f() { 'l: loop { fn g() { From 5586cd80e244936283b913ab3cf0f3626eec3136 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Fri, 18 May 2018 07:12:19 -0700 Subject: [PATCH 14/15] Revert "Remove unused label in mir" This reverts commit b2a2450cf2925498e1c3bdd781aa1978f9eb00e5. --- src/librustc_mir/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 7b6cee96a875c..03137619edaf4 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1705,7 +1705,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let mut trace_text = "\n\nAn error occurred in miri:\n".to_string(); backtrace.resolve(); write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap(); - for (i, frame) in backtrace.frames().iter().enumerate() { + 'frames: for (i, frame) in backtrace.frames().iter().enumerate() { if frame.symbols().is_empty() { write!(trace_text, "{}: no symbols\n", i).unwrap(); } From 6da64a7666e89b39b99d728aaa3a40c124f31563 Mon Sep 17 00:00:00 2001 From: Kyle Stachowicz Date: Fri, 18 May 2018 16:53:39 -0700 Subject: [PATCH 15/15] Default `unused_labels` to allow, move to "unused" --- src/librustc/lint/builtin.rs | 2 +- src/librustc_lint/lib.rs | 1 + src/test/ui/lint/unused_labels.rs | 10 ++++++++++ src/test/ui/lint/unused_labels.stderr | 24 ++++++++++++++---------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 71eefec2210e4..79b4ec61bd081 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -281,7 +281,7 @@ declare_lint! { declare_lint! { pub UNUSED_LABELS, - Warn, + Allow, "detects labels that are never used" } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0ae133640fad9..69825027b052b 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -177,6 +177,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_DOC_COMMENT, UNUSED_EXTERN_CRATES, UNUSED_FEATURES, + UNUSED_LABELS, UNUSED_PARENS); add_lint_group!(sess, diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index 22b7ad4e6a7c9..23add604da6ab 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -15,6 +15,7 @@ // compile-pass #![feature(label_break_value)] +#![warn(unused_labels)] fn main() { 'unused_while_label: while 0 == 0 { @@ -55,6 +56,15 @@ fn main() { } } + // You should be able to break the same label many times + 'many_used: loop { + if true { + break 'many_used; + } else { + break 'many_used; + } + } + // Test breaking many times with the same inner label doesn't break the // warning on the outer label 'many_used_shadowed: for _ in 0..10 { diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr index d09209853e3a3..825f5e281f0b9 100644 --- a/src/test/ui/lint/unused_labels.stderr +++ b/src/test/ui/lint/unused_labels.stderr @@ -1,55 +1,59 @@ warning: unused label - --> $DIR/unused_labels.rs:20:5 + --> $DIR/unused_labels.rs:21:5 | LL | 'unused_while_label: while 0 == 0 { | ^^^^^^^^^^^^^^^^^^^ | - = note: #[warn(unused_labels)] on by default +note: lint level defined here + --> $DIR/unused_labels.rs:18:9 + | +LL | #![warn(unused_labels)] + | ^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:25:5 + --> $DIR/unused_labels.rs:26:5 | LL | 'unused_while_let_label: while let Some(_) = opt { | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:29:5 + --> $DIR/unused_labels.rs:30:5 | LL | 'unused_for_label: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:45:9 + --> $DIR/unused_labels.rs:46:9 | LL | 'unused_loop_label_inner_2: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:51:5 + --> $DIR/unused_labels.rs:52:5 | LL | 'unused_loop_label_outer_3: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:60:5 + --> $DIR/unused_labels.rs:70:5 | LL | 'many_used_shadowed: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:72:5 + --> $DIR/unused_labels.rs:82:5 | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:78:5 + --> $DIR/unused_labels.rs:88:5 | LL | 'unused_block_label: { | ^^^^^^^^^^^^^^^^^^^ warning: label name `'many_used_shadowed` shadows a label name that is already in scope - --> $DIR/unused_labels.rs:62:9 + --> $DIR/unused_labels.rs:72:9 | LL | 'many_used_shadowed: for _ in 0..10 { | ------------------- first declared here