Rollup merge of #68108 - varkor:chained-comparison-suggestions, r=Centril

Add suggestions when encountering chained comparisons

Ideally, we'd also prevent the type error, which is just extra noise, but that will require moving the error from the parser, and I think the suggestion makes things clear enough for now.

Fixes https://github.com/rust-lang/rust/issues/65659.
This commit is contained in:
Mazdak Farrokhzad 2020-01-12 03:28:02 +01:00 committed by GitHub
commit 82c19b4388
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 335 additions and 49 deletions

View file

@ -1,8 +1,8 @@
fn main() {
(0..13).collect<Vec<i32>>();
//~^ ERROR chained comparison
//~^ ERROR comparison operators cannot be chained
Vec<i32>::new();
//~^ ERROR chained comparison
//~^ ERROR comparison operators cannot be chained
(0..13).collect<Vec<i32>();
//~^ ERROR chained comparison
//~^ ERROR comparison operators cannot be chained
}

View file

@ -1,15 +1,23 @@
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/issue-40396.rs:2:20
|
LL | (0..13).collect<Vec<i32>>();
| ^^^^^
|
help: split the comparison into two...
|
LL | (0..13).collect < Vec && Vec <i32>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | ((0..13).collect < Vec) <i32>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: use `::<...>` instead of `<...>` to specify type arguments
|
LL | (0..13).collect::<Vec<i32>>();
| ^^
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/issue-40396.rs:4:8
|
LL | Vec<i32>::new();
@ -20,12 +28,20 @@ help: use `::<...>` instead of `<...>` to specify type arguments
LL | Vec::<i32>::new();
| ^^
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/issue-40396.rs:6:20
|
LL | (0..13).collect<Vec<i32>();
| ^^^^^
|
help: split the comparison into two...
|
LL | (0..13).collect < Vec && Vec <i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | ((0..13).collect < Vec) <i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
help: use `::<...>` instead of `<...>` to specify type arguments
|
LL | (0..13).collect::<Vec<i32>();

View file

@ -0,0 +1,40 @@
// Check that we get nice suggestions when attempting a chained comparison.
fn comp1() {
1 < 2 <= 3; //~ ERROR comparison operators cannot be chained
//~^ ERROR mismatched types
}
fn comp2() {
1 < 2 < 3; //~ ERROR comparison operators cannot be chained
}
fn comp3() {
1 <= 2 < 3; //~ ERROR comparison operators cannot be chained
//~^ ERROR mismatched types
}
fn comp4() {
1 <= 2 <= 3; //~ ERROR comparison operators cannot be chained
//~^ ERROR mismatched types
}
fn comp5() {
1 > 2 >= 3; //~ ERROR comparison operators cannot be chained
//~^ ERROR mismatched types
}
fn comp6() {
1 > 2 > 3; //~ ERROR comparison operators cannot be chained
}
fn comp7() {
1 >= 2 > 3; //~ ERROR comparison operators cannot be chained
}
fn comp8() {
1 >= 2 >= 3; //~ ERROR comparison operators cannot be chained
//~^ ERROR mismatched types
}
fn main() {}

View file

@ -0,0 +1,159 @@
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:4:7
|
LL | 1 < 2 <= 3;
| ^^^^^^
|
help: split the comparison into two...
|
LL | 1 < 2 && 2 <= 3;
| ^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 < 2) <= 3;
| ^^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:9:7
|
LL | 1 < 2 < 3;
| ^^^^^
|
= help: use `::<...>` instead of `<...>` to specify type arguments
= help: or use `(...)` if you meant to specify fn arguments
help: split the comparison into two...
|
LL | 1 < 2 && 2 < 3;
| ^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 < 2) < 3;
| ^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:13:7
|
LL | 1 <= 2 < 3;
| ^^^^^^
|
help: split the comparison into two...
|
LL | 1 <= 2 && 2 < 3;
| ^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 <= 2) < 3;
| ^^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:18:7
|
LL | 1 <= 2 <= 3;
| ^^^^^^^
|
help: split the comparison into two...
|
LL | 1 <= 2 && 2 <= 3;
| ^^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 <= 2) <= 3;
| ^^^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:23:7
|
LL | 1 > 2 >= 3;
| ^^^^^^
|
help: split the comparison into two...
|
LL | 1 > 2 && 2 >= 3;
| ^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 > 2) >= 3;
| ^^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:28:7
|
LL | 1 > 2 > 3;
| ^^^^^
|
= help: use `::<...>` instead of `<...>` to specify type arguments
= help: or use `(...)` if you meant to specify fn arguments
help: split the comparison into two...
|
LL | 1 > 2 && 2 > 3;
| ^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 > 2) > 3;
| ^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:32:7
|
LL | 1 >= 2 > 3;
| ^^^^^^
|
= help: use `::<...>` instead of `<...>` to specify type arguments
= help: or use `(...)` if you meant to specify fn arguments
help: split the comparison into two...
|
LL | 1 >= 2 && 2 > 3;
| ^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 >= 2) > 3;
| ^^^^^^^^^^
error: comparison operators cannot be chained
--> $DIR/chained-comparison-suggestion.rs:36:7
|
LL | 1 >= 2 >= 3;
| ^^^^^^^
|
help: split the comparison into two...
|
LL | 1 >= 2 && 2 >= 3;
| ^^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (1 >= 2) >= 3;
| ^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/chained-comparison-suggestion.rs:4:14
|
LL | 1 < 2 <= 3;
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> $DIR/chained-comparison-suggestion.rs:13:14
|
LL | 1 <= 2 < 3;
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> $DIR/chained-comparison-suggestion.rs:18:15
|
LL | 1 <= 2 <= 3;
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> $DIR/chained-comparison-suggestion.rs:23:14
|
LL | 1 > 2 >= 3;
| ^ expected `bool`, found integer
error[E0308]: mismatched types
--> $DIR/chained-comparison-suggestion.rs:36:15
|
LL | 1 >= 2 >= 3;
| ^ expected `bool`, found integer
error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -3,24 +3,26 @@ struct X;
fn main() {
false == false == false;
//~^ ERROR chained comparison operators require parentheses
//~^ ERROR comparison operators cannot be chained
false == 0 < 2;
//~^ ERROR chained comparison operators require parentheses
//~^ ERROR comparison operators cannot be chained
//~| ERROR mismatched types
//~| ERROR mismatched types
f<X>();
//~^ ERROR chained comparison operators require parentheses
//~^ ERROR comparison operators cannot be chained
//~| HELP use `::<...>` instead of `<...>` to specify type arguments
f<Result<Option<X>, Option<Option<X>>>(1, 2);
//~^ ERROR chained comparison operators require parentheses
//~^ ERROR comparison operators cannot be chained
//~| HELP split the comparison into two...
//~| ...or parenthesize one of the comparisons
//~| HELP use `::<...>` instead of `<...>` to specify type arguments
use std::convert::identity;
let _ = identity<u8>;
//~^ ERROR chained comparison operators require parentheses
//~^ ERROR comparison operators cannot be chained
//~| HELP use `::<...>` instead of `<...>` to specify type arguments
//~| HELP or use `(...)` if you meant to specify fn arguments
}

View file

@ -1,16 +1,16 @@
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:5:11
|
LL | false == false == false;
| ^^^^^^^^^^^
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:8:11
|
LL | false == 0 < 2;
| ^^^^^^
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:13:6
|
LL | f<X>();
@ -21,19 +21,27 @@ help: use `::<...>` instead of `<...>` to specify type arguments
LL | f::<X>();
| ^^
error: chained comparison operators require parentheses
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:17:6
|
LL | f<Result<Option<X>, Option<Option<X>>>(1, 2);
| ^^^^^^^^
|
help: split the comparison into two...
|
LL | f < Result && Result <Option<X>, Option<Option<X>>>(1, 2);
| ^^^^^^^^^^^^^^^^^^^^^^
help: ...or parenthesize one of the comparisons
|
LL | (f < Result) <Option<X>, Option<Option<X>>>(1, 2);
| ^^^^^^^^^^^^^^
help: use `::<...>` instead of `<...>` to specify type arguments
|
LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2);
| ^^
error: chained comparison operators require parentheses
--> $DIR/require-parens-for-chained-comparison.rs:22:21
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:24:21
|
LL | let _ = identity<u8>;
| ^^^^