Merge pull request #1671 from Manishearth/eq_op

Fix op_ref false positives
This commit is contained in:
Oliver Schneider 2017-04-10 16:45:32 +02:00 committed by GitHub
commit 5ae57c55fd
13 changed files with 408 additions and 159 deletions

View file

@ -1,6 +1,6 @@
use rustc::hir::*;
use rustc::lint::*;
use utils::{SpanlessEq, span_lint, span_lint_and_then, multispan_sugg, snippet};
use utils::{SpanlessEq, span_lint, span_lint_and_then, multispan_sugg, snippet, implements_trait};
use utils::sugg::Sugg;
/// **What it does:** Checks for equal operands to comparison, logical and
@ -60,53 +60,88 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
e.span,
&format!("equal expressions as operands to `{}`", op.node.as_str()));
} else {
match (&left.node, &right.node) {
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of both operands, which is done automatically by the operator anyway",
|db| {
let lsnip = snippet(cx, l.span, "...").to_string();
let rsnip = snippet(cx, r.span, "...").to_string();
multispan_sugg(db,
"use the values directly".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
let trait_id = match op.node {
BiAdd => cx.tcx.lang_items.add_trait(),
BiSub => cx.tcx.lang_items.sub_trait(),
BiMul => cx.tcx.lang_items.mul_trait(),
BiDiv => cx.tcx.lang_items.div_trait(),
BiRem => cx.tcx.lang_items.rem_trait(),
BiAnd |
BiOr => None,
BiBitXor => cx.tcx.lang_items.bitxor_trait(),
BiBitAnd => cx.tcx.lang_items.bitand_trait(),
BiBitOr => cx.tcx.lang_items.bitor_trait(),
BiShl => cx.tcx.lang_items.shl_trait(),
BiShr => cx.tcx.lang_items.shr_trait(),
BiNe |
BiEq => cx.tcx.lang_items.eq_trait(),
BiLt |
BiLe |
BiGe |
BiGt => cx.tcx.lang_items.ord_trait(),
};
if let Some(trait_id) = trait_id {
#[allow(match_same_arms)]
match (&left.node, &right.node) {
// do not suggest to dereference literals
(&ExprLit(..), _) |
(_, &ExprLit(..)) => {},
// &foo == &bar
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
if implements_trait(cx, cx.tables.expr_ty(l), trait_id, &[cx.tables.expr_ty(r)], None) {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of both operands, which is done automatically by the operator anyway",
|db| {
let lsnip = snippet(cx, l.span, "...").to_string();
let rsnip = snippet(cx, r.span, "...").to_string();
multispan_sugg(db,
"use the values directly".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
}
)
}
)
}
(&ExprAddrOf(_, ref l), _) => {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of left operand",
|db| {
let lsnip = snippet(cx, l.span, "...").to_string();
let rsnip = Sugg::hir(cx, right, "...").deref().to_string();
multispan_sugg(db,
"dereference the right operand instead".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
}
// &foo == bar
(&ExprAddrOf(_, ref l), _) => {
if implements_trait(cx, cx.tables.expr_ty(l), trait_id, &[cx.tables.expr_ty(right)], None) {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of left operand",
|db| {
let lsnip = snippet(cx, l.span, "...").to_string();
let rsnip = Sugg::hir(cx, right, "...").deref().to_string();
multispan_sugg(db,
"dereference the right operand instead".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
}
)
}
)
}
(_, &ExprAddrOf(_, ref r)) => {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of right operand",
|db| {
let lsnip = Sugg::hir(cx, left, "...").deref().to_string();
let rsnip = snippet(cx, r.span, "...").to_string();
multispan_sugg(db,
"dereference the left operand instead".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
}
// foo == &bar
(_, &ExprAddrOf(_, ref r)) => {
if implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[cx.tables.expr_ty(r)], None) {
span_lint_and_then(cx,
OP_REF,
e.span,
"taken reference of right operand",
|db| {
let lsnip = Sugg::hir(cx, left, "...").deref().to_string();
let rsnip = snippet(cx, r.span, "...").to_string();
multispan_sugg(db,
"dereference the left operand instead".to_string(),
vec![(left.span, lsnip),
(right.span, rsnip)]);
}
)
}
)
}
_ => {}
}
_ => {}
}
}
}

View file

@ -99,7 +99,7 @@ pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Exp
/// Checks if the expressions matches
/// ```rust
/// { static __STATIC_FMTSTR: … = &["…", "…", …]; __STATIC_FMTSTR }
/// { static __STATIC_FMTSTR: s = &["a", "b", c]; __STATIC_FMTSTR }
/// ```
fn check_static_str(cx: &LateContext, expr: &Expr) -> bool {
if let Some(expr) = get_argument_fmtstr_parts(cx, expr) {
@ -110,10 +110,10 @@ fn check_static_str(cx: &LateContext, expr: &Expr) -> bool {
}
/// Checks if the expressions matches
/// ```rust
/// ```rust,ignore
/// &match (&42,) {
/// (__arg0,) => [::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Display::fmt)],
/// })
/// }
/// ```
fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
if_let_chain! {[

View file

@ -6,8 +6,7 @@ error: this if statement can be collapsed
9 | |
10 | |
11 | |
12 | | if y == "world" {
13 | | println!("Hello world!");
... |
14 | | }
15 | | }
| |_____^ ...ending here
@ -30,8 +29,7 @@ error: this if statement can be collapsed
18 | |
19 | |
20 | |
21 | | if y == "world" || y == "hello" {
22 | | println!("Hello world!");
... |
23 | | }
24 | | }
| |_____^ ...ending here
@ -49,8 +47,7 @@ error: this if statement can be collapsed
27 | |
28 | |
29 | |
30 | | if y == "world" || y == "hello" {
31 | | println!("Hello world!");
... |
32 | | }
33 | | }
| |_____^ ...ending here
@ -68,8 +65,7 @@ error: this if statement can be collapsed
36 | |
37 | |
38 | |
39 | | if y == "world" && y == "hello" {
40 | | println!("Hello world!");
... |
41 | | }
42 | | }
| |_____^ ...ending here
@ -87,8 +83,7 @@ error: this if statement can be collapsed
45 | |
46 | |
47 | |
48 | | if y == "world" && y == "hello" {
49 | | println!("Hello world!");
... |
50 | | }
51 | | }
| |_____^ ...ending here
@ -106,8 +101,7 @@ error: this if statement can be collapsed
54 | |
55 | |
56 | |
57 | | if 'a' != 'A' {
58 | | println!("world!")
... |
59 | | }
60 | | }
| |_____^ ...ending here
@ -125,8 +119,7 @@ error: this `else { if .. }` block can be collapsed
66 | |
67 | |
68 | |
69 | | if y == "world" {
70 | | println!("world!")
... |
71 | | }
72 | | }
| |_____^ ...ending here
@ -144,8 +137,7 @@ error: this `else { if .. }` block can be collapsed
77 | |
78 | |
79 | |
80 | | if let Some(42) = Some(42) {
81 | | println!("world!")
... |
82 | | }
83 | | }
| |_____^ ...ending here
@ -158,8 +150,15 @@ help: try
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:87:12
|
87 | } else {
| ^
87 | } else {
| ____________^ starting here...
88 | |
89 | |
90 | |
... |
96 | | }
97 | | }
| |_____^ ...ending here
|
help: try
| } else if y == "world" {
@ -172,8 +171,15 @@ help: try
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:101:12
|
101 | } else {
| ^
101 | } else {
| ____________^ starting here...
102 | |
103 | |
104 | |
... |
110 | | }
111 | | }
| |_____^ ...ending here
|
help: try
| } else if let Some(42) = Some(42) {
@ -186,8 +192,15 @@ help: try
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:115:12
|
115 | } else {
| ^
115 | } else {
| ____________^ starting here...
116 | |
117 | |
118 | |
... |
124 | | }
125 | | }
| |_____^ ...ending here
|
help: try
| } else if let Some(42) = Some(42) {
@ -200,8 +213,15 @@ help: try
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:129:12
|
129 | } else {
| ^
129 | } else {
| ____________^ starting here...
130 | |
131 | |
132 | |
... |
138 | | }
139 | | }
| |_____^ ...ending here
|
help: try
| } else if x == "hello" {
@ -214,8 +234,15 @@ help: try
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:143:12
|
143 | } else {
| ^
143 | } else {
| ____________^ starting here...
144 | |
145 | |
146 | |
... |
152 | | }
153 | | }
| |_____^ ...ending here
|
help: try
| } else if let Some(42) = Some(42) {

View file

@ -6,9 +6,7 @@ error: this `if` has identical blocks
41 | | Foo { bar: 42 };
42 | | 0..10;
43 | | ..;
44 | | 0..;
45 | | ..10;
46 | | 0...10;
... |
47 | | foo();
48 | | }
| |_____^ ...ending here
@ -21,8 +19,15 @@ note: lint level defined here
note: same as this
--> $DIR/copies.rs:30:13
|
30 | if true {
| ^
30 | if true {
| _____________^ starting here...
31 | |
32 | | Foo { bar: 42 };
33 | | 0..10;
... |
38 | | foo();
39 | | }
| |_____^ ...ending here
error: this `match` has identical arm bodies
--> $DIR/copies.rs:91:14
@ -32,9 +37,7 @@ error: this `match` has identical arm bodies
92 | | foo();
93 | | let mut a = 42 + [23].len() as i32;
94 | | if true {
95 | | a += 7;
96 | | }
97 | | a = -31-a;
... |
98 | | a
99 | | }
| |_________^ ...ending here
@ -47,13 +50,27 @@ note: lint level defined here
note: same as this
--> $DIR/copies.rs:80:15
|
80 | 42 => {
| ^
80 | 42 => {
| _______________^ starting here...
81 | |
82 | |
83 | | foo();
... |
89 | | a
90 | | }
| |_________^ ...ending here
note: `42` has the same arm body as the `_` wildcard, consider removing it`
--> $DIR/copies.rs:80:15
|
80 | 42 => {
| ^
80 | 42 => {
| _______________^ starting here...
81 | |
82 | |
83 | | foo();
... |
89 | | a
90 | | }
| |_________^ ...ending here
error: this `match` has identical arm bodies
--> $DIR/copies.rs:107:14
@ -94,26 +111,54 @@ note: same as this
error: this `if` has identical blocks
--> $DIR/copies.rs:133:10
|
133 | else {
| ^
133 | else {
| __________^ starting here...
134 | | for _ in &[42] {
135 | | let foo: &Option<_> = &Some::<u8>(42);
136 | | if true {
... |
141 | | }
142 | | }
| |_____^ ...ending here
|
note: same as this
--> $DIR/copies.rs:122:13
|
122 | if true {
| ^
122 | if true {
| _____________^ starting here...
123 | |
124 | | for _ in &[42] {
125 | | let foo: &Option<_> = &Some::<u8>(42);
... |
131 | | }
132 | | }
| |_____^ ...ending here
error: this `if` has identical blocks
--> $DIR/copies.rs:156:10
|
156 | else {
| ^
156 | else {
| __________^ starting here...
157 | | let bar = if true {
158 | | 42
159 | | }
... |
165 | | bar + 1;
166 | | }
| |_____^ ...ending here
|
note: same as this
--> $DIR/copies.rs:144:13
|
144 | if true {
| ^
144 | if true {
| _____________^ starting here...
145 | |
146 | | let bar = if true {
147 | | 42
... |
154 | | bar + 1;
155 | | }
| |_____^ ...ending here
error: this `if` has identical blocks
--> $DIR/copies.rs:180:19
@ -123,8 +168,7 @@ error: this `if` has identical blocks
181 | | let _ = match 42 {
182 | | 42 => 1,
183 | | a if a > 0 => 2,
184 | | 10...15 => 3,
185 | | _ => 4,
... |
186 | | };
187 | | }
| |_____^ ...ending here
@ -137,9 +181,7 @@ note: same as this
169 | |
170 | | let _ = match 42 {
171 | | 42 => 1,
172 | | a if a > 0 => 2,
173 | | 10...15 => 3,
174 | | _ => 4,
... |
175 | | };
176 | | }
| |_____^ ...ending here

View file

@ -1,8 +1,15 @@
error: the function has a cyclomatic complexity of 28
--> $DIR/cyclomatic_complexity.rs:7:1
|
7 | fn main() {
| ^
7 | fn main() {
| _^ starting here...
8 | | if true {
9 | | println!("a");
10 | | }
... |
88 | | }
89 | | }
| |_^ ...ending here
|
note: lint level defined here
--> $DIR/cyclomatic_complexity.rs:4:9
@ -14,8 +21,15 @@ note: lint level defined here
error: the function has a cyclomatic complexity of 7
--> $DIR/cyclomatic_complexity.rs:92:1
|
92 | fn kaboom() {
| ^
92 | fn kaboom() {
| _^ starting here...
93 | | let n = 0;
94 | | 'a: for i in 0..20 {
95 | | 'b: for j in i..20 {
... |
110 | | }
111 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -44,8 +58,15 @@ error: the function has a cyclomatic complexity of 1
error: the function has a cyclomatic complexity of 2
--> $DIR/cyclomatic_complexity.rs:148:1
|
148 | fn baa() {
| ^
148 | fn baa() {
| _^ starting here...
149 | | let x = || match 99 {
150 | | 0 => 0,
151 | | 1 => 1,
... |
162 | | }
163 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -57,9 +78,7 @@ error: the function has a cyclomatic complexity of 2
150 | | 0 => 0,
151 | | 1 => 1,
152 | | 2 => 2,
153 | | 4 => 4,
154 | | 6 => 6,
155 | | 9 => 9,
... |
156 | | _ => 42,
157 | | };
| |_____^ ...ending here
@ -88,8 +107,7 @@ error: the function has a cyclomatic complexity of 2
186 | | match 99 {
187 | | 0 => println!("hi"),
188 | | 1 => println!("bla"),
189 | | 2 | 3 => println!("blub"),
190 | | _ => println!("bye"),
... |
191 | | }
192 | | }
| |_^ ...ending here
@ -99,8 +117,15 @@ error: the function has a cyclomatic complexity of 2
error: the function has a cyclomatic complexity of 3
--> $DIR/cyclomatic_complexity.rs:195:1
|
195 | fn barr2() {
| ^
195 | fn barr2() {
| _^ starting here...
196 | | match 99 {
197 | | 0 => println!("hi"),
198 | | 1 => println!("bla"),
... |
207 | | }
208 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -112,8 +137,7 @@ error: the function has a cyclomatic complexity of 2
212 | | match 99 {
213 | | 0 => println!("hi"),
214 | | 1 => panic!("bla"),
215 | | 2 | 3 => println!("blub"),
216 | | _ => println!("bye"),
... |
217 | | }
218 | | }
| |_^ ...ending here
@ -123,8 +147,15 @@ error: the function has a cyclomatic complexity of 2
error: the function has a cyclomatic complexity of 3
--> $DIR/cyclomatic_complexity.rs:221:1
|
221 | fn barrr2() {
| ^
221 | fn barrr2() {
| _^ starting here...
222 | | match 99 {
223 | | 0 => println!("hi"),
224 | | 1 => panic!("bla"),
... |
233 | | }
234 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -136,8 +167,7 @@ error: the function has a cyclomatic complexity of 2
238 | | match 99 {
239 | | 0 => println!("hi"),
240 | | 1 => println!("bla"),
241 | | 2 | 3 => panic!("blub"),
242 | | _ => println!("bye"),
... |
243 | | }
244 | | }
| |_^ ...ending here
@ -147,8 +177,15 @@ error: the function has a cyclomatic complexity of 2
error: the function has a cyclomatic complexity of 3
--> $DIR/cyclomatic_complexity.rs:247:1
|
247 | fn barrrr2() {
| ^
247 | fn barrrr2() {
| _^ starting here...
248 | | match 99 {
249 | | 0 => println!("hi"),
250 | | 1 => println!("bla"),
... |
259 | | }
260 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -160,8 +197,7 @@ error: the function has a cyclomatic complexity of 2
264 | | if 4 == 5 {
265 | | println!("yea");
266 | | } else {
267 | | panic!("meh");
268 | | }
... |
269 | | println!("whee");
270 | | }
| |_^ ...ending here
@ -171,8 +207,15 @@ error: the function has a cyclomatic complexity of 2
error: the function has a cyclomatic complexity of 4
--> $DIR/cyclomatic_complexity.rs:274:1
|
274 | pub fn read_file(input_path: &str) -> String {
| ^
274 | pub fn read_file(input_path: &str) -> String {
| _^ starting here...
275 | | use std::fs::File;
276 | | use std::io::{Read, Write};
277 | | use std::path::Path;
... |
299 | | }
300 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
@ -207,24 +250,45 @@ error: the function has a cyclomatic complexity of 1
error: the function has a cyclomatic complexity of 1
--> $DIR/cyclomatic_complexity.rs:327:1
|
327 | fn try_again() -> Result<i32, &'static str> {
| ^
327 | fn try_again() -> Result<i32, &'static str> {
| _^ starting here...
328 | | let _ = try!(Ok(42));
329 | | let _ = try!(Ok(43));
330 | | let _ = try!(Ok(44));
... |
339 | | }
340 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
error: the function has a cyclomatic complexity of 1
--> $DIR/cyclomatic_complexity.rs:343:1
|
343 | fn early() -> Result<i32, &'static str> {
| ^
343 | fn early() -> Result<i32, &'static str> {
| _^ starting here...
344 | | return Ok(5);
345 | | return Ok(5);
346 | | return Ok(5);
... |
352 | | return Ok(5);
353 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions
error: the function has a cyclomatic complexity of 8
--> $DIR/cyclomatic_complexity.rs:356:1
|
356 | fn early_ret() -> i32 {
| ^
356 | fn early_ret() -> i32 {
| _^ starting here...
357 | | let a = if true { 42 } else { return 0; };
358 | | let a = if a < 99 { 42 } else { return 0; };
359 | | let a = if a < 99 { 42 } else { return 0; };
... |
372 | | }
373 | | }
| |_^ ...ending here
|
= help: you could split it up into multiple smaller functions

View file

@ -579,9 +579,7 @@ error: you seem to want to iterate on a map's values
454 | |
455 | |
456 | |
457 | |
458 | | let _v = v;
459 | | // Here the `*` is not actually necesarry, but the test tests that we don't suggest
... |
460 | | // `in *m.values()` as we used to
461 | | }
| |_____^ ...ending here

View file

@ -32,9 +32,7 @@ error: item `HasIsEmpty` has a public `len` method but a private `is_empty` meth
90 | | pub fn len(self: &Self) -> isize {
91 | | 1
92 | | }
93 | |
94 | | fn is_empty(self: &Self) -> bool {
95 | | false
... |
96 | | }
97 | | }
| |_^ ...ending here
@ -47,9 +45,7 @@ error: item `HasWrongIsEmpty` has a public `len` method but no corresponding `is
119 | | pub fn len(self: &Self) -> isize {
120 | | 1
121 | | }
122 | |
123 | | pub fn is_empty(self: &Self, x : u32) -> bool {
124 | | false
... |
125 | | }
126 | | }
| |_^ ...ending here

View file

@ -23,8 +23,15 @@ help: it is more idiomatic to write
error: `if _ { .. } else { .. }` is an expression
--> $DIR/let_if_seq.rs:65:5
|
65 | let mut bar = 0;
| ^
65 | let mut bar = 0;
| _____^ starting here...
66 | |
67 | |
68 | |
... |
74 | | f();
75 | | }
| |_____^ ...ending here
|
help: it is more idiomatic to write
| let <mut> bar = if f() { ..; 42 } else { ..; 0 };
@ -33,8 +40,15 @@ help: it is more idiomatic to write
error: `if _ { .. } else { .. }` is an expression
--> $DIR/let_if_seq.rs:77:5
|
77 | let quz;
| ^
77 | let quz;
| _____^ starting here...
78 | |
79 | |
80 | |
... |
85 | | quz = 0;
86 | | }
| |_____^ ...ending here
|
help: it is more idiomatic to write
| let quz = if f() { 42 } else { 0 };

View file

@ -190,8 +190,7 @@ error: you seem to be trying to match on a boolean expression
148 | |
149 | |
150 | |
151 | |
152 | | false => { println!("Noooo!"); }
... |
153 | | _ => (),
154 | | };
| |_____^ ...ending here

View file

@ -236,8 +236,15 @@ error: missing documentation for a static
error: missing documentation for a module
--> $DIR/missing-doc.rs:180:1
|
180 | mod internal_impl {
| ^
180 | mod internal_impl {
| _^ starting here...
181 | | /// dox
182 | | pub fn documented() {}
183 | | pub fn undocumented1() {}
... |
192 | | }
193 | | }
| |_^ ...ending here
error: missing documentation for a function
--> $DIR/missing-doc.rs:183:5

24
tests/ui/op_ref.rs Normal file
View file

@ -0,0 +1,24 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(unused_variables, blacklisted_name)]
use std::collections::HashSet;
fn main() {
let tracked_fds: HashSet<i32> = HashSet::new();
let new_fds = HashSet::new();
let unwanted = &tracked_fds - &new_fds;
let foo = &5 - &6;
let bar = String::new();
let bar = "foo" == &bar;
let a = "a".to_string();
let b = "a";
if b < &a {
println!("OK");
}
}

10
tests/ui/op_ref.stderr Normal file
View file

@ -0,0 +1,10 @@
warning: taken reference of both operands, which is done automatically by the operator anyway
--> $DIR/op_ref.rs:13:15
|
13 | let foo = &5 - &6;
| ^^^^^^^
|
= note: #[warn(op_ref)] on by default
help: use the values directly
| let foo = 5 - 6;

View file

@ -1,8 +1,15 @@
error: this loop could be written as a `while let` loop
--> $DIR/while_loop.rs:9:5
|
9 | loop {
| ^
9 | loop {
| _____^ starting here...
10 | |
11 | |
12 | |
... |
17 | | }
18 | | }
| |_____^ ...ending here
|
note: lint level defined here
--> $DIR/while_loop.rs:4:9
@ -20,9 +27,7 @@ error: this loop could be written as a `while let` loop
26 | |
27 | |
28 | |
29 | | match y {
30 | | Some(_x) => true,
31 | | None => break
... |
32 | | };
33 | | }
| |_____^ ...ending here
@ -33,8 +38,15 @@ help: try
error: this loop could be written as a `while let` loop
--> $DIR/while_loop.rs:34:5
|
34 | loop {
| ^
34 | loop {
| _____^ starting here...
35 | |
36 | |
37 | |
... |
43 | | let _str = "foo";
44 | | }
| |_____^ ...ending here
|
help: try
| while let Some(x) = y { .. }
@ -42,8 +54,15 @@ help: try
error: this loop could be written as a `while let` loop
--> $DIR/while_loop.rs:45:5
|
45 | loop {
| ^
45 | loop {
| _____^ starting here...
46 | |
47 | |
48 | |
... |
54 | | { let _b = "foobar"; }
55 | | }
| |_____^ ...ending here
|
help: try
| while let Some(x) = y { .. }
@ -51,8 +70,15 @@ help: try
error: this loop could be written as a `while let` loop
--> $DIR/while_loop.rs:70:5
|
70 | loop {
| ^
70 | loop {
| _____^ starting here...
71 | |
72 | |
73 | |
... |
79 | | let _ = (e, l);
80 | | }
| |_____^ ...ending here
|
help: try
| while let Some(word) = "".split_whitespace().next() { .. }
@ -104,8 +130,15 @@ help: try
error: this loop could be written as a `while let` loop
--> $DIR/while_loop.rs:142:5
|
142 | loop {
| ^
142 | loop {
| _____^ starting here...
143 | |
144 | |
145 | |
... |
150 | | loop {}
151 | | }
| |_____^ ...ending here
|
help: try
| while let Some(ele) = iter.next() { .. }