Auto merge of #77341 - davidtwco:issue-73427-you-might-have-meant-variant, r=estebank
resolve: improve "try using the enum's variant" Fixes #73427. This PR improves the "try using the enum's variant" suggestion: - Variants in suggestions would not result in more errors (e.g. use of a struct variant is only suggested if the suggestion can trivially construct that variant). Therefore, suggestions are only emitted for variants that have no fields (since the suggestion can't know what value fields would have). - Suggestions include the syntax for constructing the variant. If a struct or tuple variant is suggested, then it is constructed in the suggestion - unless in pattern-matching or when arguments are already provided. - A help message is added which mentions the variants which are no longer suggested. All of the diagnostic logic introduced by this PR is separated from the normal code path for a successful compilation. r? `@estebank`
This commit is contained in:
commit
deec530523
5 changed files with 258 additions and 88 deletions
|
|
@ -2,46 +2,33 @@ error[E0423]: expected function, tuple struct or tuple variant, found enum `Opti
|
|||
--> $DIR/issue-43871-enum-instead-of-variant.rs:19:13
|
||||
|
|
||||
LL | let x = Option(1);
|
||||
| ^^^^^^
|
||||
| ^^^^^^ help: try using one of the enum's variants: `std::option::Option::Some`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let x = std::option::Option::None(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | let x = std::option::Option::Some(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: you might have meant to construct the enum's non-tuple variant
|
||||
|
||||
error[E0532]: expected tuple struct or tuple variant, found enum `Option`
|
||||
--> $DIR/issue-43871-enum-instead-of-variant.rs:21:12
|
||||
|
|
||||
LL | if let Option(_) = x {
|
||||
| ^^^^^^
|
||||
| ^^^^^^ help: try using one of the enum's variants: `std::option::Option::Some`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | if let std::option::Option::None(_) = x {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | if let std::option::Option::Some(_) = x {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: you might have meant to match against the enum's non-tuple variant
|
||||
|
||||
error[E0532]: expected tuple struct or tuple variant, found enum `Example`
|
||||
--> $DIR/issue-43871-enum-instead-of-variant.rs:27:12
|
||||
|
|
||||
LL | if let Example(_) = y {
|
||||
| ^^^^^^^
|
||||
| ^^^^^^^ help: try using one of the enum's variants: `Example::Ex`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | if let Example::Ex(_) = y {
|
||||
| ^^^^^^^^^^^
|
||||
LL | if let Example::NotEx(_) = y {
|
||||
| ^^^^^^^^^^^^^^
|
||||
= help: you might have meant to match against the enum's non-tuple variant
|
||||
|
||||
error[E0423]: expected function, tuple struct or tuple variant, found enum `Void`
|
||||
--> $DIR/issue-43871-enum-instead-of-variant.rs:31:13
|
||||
|
|
||||
LL | let y = Void();
|
||||
| ^^^^
|
||||
|
|
||||
= help: the enum has no tuple variants to construct
|
||||
|
||||
error[E0423]: expected function, tuple struct or tuple variant, found enum `ManyVariants`
|
||||
--> $DIR/issue-43871-enum-instead-of-variant.rs:33:13
|
||||
|
|
@ -49,17 +36,8 @@ error[E0423]: expected function, tuple struct or tuple variant, found enum `Many
|
|||
LL | let z = ManyVariants();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let z = ManyVariants::One();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
LL | let z = ManyVariants::Two();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
LL | let z = ManyVariants::Three();
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
LL | let z = ManyVariants::Four();
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
and 6 other candidates
|
||||
= help: the enum has no tuple variants to construct
|
||||
= help: you might have meant to construct one of the enum's non-tuple variants
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
44
src/test/ui/issues/issue-73427.rs
Normal file
44
src/test/ui/issues/issue-73427.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
enum A {
|
||||
StructWithFields { x: () },
|
||||
TupleWithFields(()),
|
||||
Struct {},
|
||||
Tuple(),
|
||||
Unit,
|
||||
}
|
||||
|
||||
enum B {
|
||||
StructWithFields { x: () },
|
||||
TupleWithFields(()),
|
||||
}
|
||||
|
||||
enum C {
|
||||
StructWithFields { x: () },
|
||||
TupleWithFields(()),
|
||||
Unit,
|
||||
}
|
||||
|
||||
enum D {
|
||||
TupleWithFields(()),
|
||||
Unit,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Only variants without fields are suggested (and others mentioned in a note) where an enum
|
||||
// is used rather than a variant.
|
||||
|
||||
A.foo();
|
||||
//~^ ERROR expected value, found enum `A`
|
||||
B.foo();
|
||||
//~^ ERROR expected value, found enum `B`
|
||||
C.foo();
|
||||
//~^ ERROR expected value, found enum `C`
|
||||
D.foo();
|
||||
//~^ ERROR expected value, found enum `D`
|
||||
|
||||
// Only tuple variants are suggested in calls or tuple struct pattern matching.
|
||||
|
||||
let x = A(3);
|
||||
//~^ ERROR expected function, tuple struct or tuple variant, found enum `A`
|
||||
if let A(3) = x { }
|
||||
//~^ ERROR expected tuple struct or tuple variant, found enum `A`
|
||||
}
|
||||
72
src/test/ui/issues/issue-73427.stderr
Normal file
72
src/test/ui/issues/issue-73427.stderr
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
error[E0423]: expected value, found enum `A`
|
||||
--> $DIR/issue-73427.rs:29:5
|
||||
|
|
||||
LL | A.foo();
|
||||
| ^
|
||||
|
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | (A::Struct {}).foo();
|
||||
| ^^^^^^^^^^^^^^
|
||||
LL | (A::Tuple()).foo();
|
||||
| ^^^^^^^^^^^^
|
||||
LL | A::Unit.foo();
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0423]: expected value, found enum `B`
|
||||
--> $DIR/issue-73427.rs:31:5
|
||||
|
|
||||
LL | B.foo();
|
||||
| ^
|
||||
|
|
||||
= help: you might have meant to use one of the enum's variants
|
||||
|
||||
error[E0423]: expected value, found enum `C`
|
||||
--> $DIR/issue-73427.rs:33:5
|
||||
|
|
||||
LL | C.foo();
|
||||
| ^ help: try using one of the enum's variants: `C::Unit`
|
||||
|
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
|
||||
error[E0423]: expected value, found enum `D`
|
||||
--> $DIR/issue-73427.rs:35:5
|
||||
|
|
||||
LL | D.foo();
|
||||
| ^ help: try using one of the enum's variants: `D::Unit`
|
||||
|
|
||||
= help: you might have meant to use the enum's other variant that has fields
|
||||
|
||||
error[E0423]: expected function, tuple struct or tuple variant, found enum `A`
|
||||
--> $DIR/issue-73427.rs:40:13
|
||||
|
|
||||
LL | let x = A(3);
|
||||
| ^
|
||||
|
|
||||
= help: you might have meant to construct one of the enum's non-tuple variants
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let x = A::TupleWithFields(3);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
LL | let x = A::Tuple(3);
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0532]: expected tuple struct or tuple variant, found enum `A`
|
||||
--> $DIR/issue-73427.rs:42:12
|
||||
|
|
||||
LL | if let A(3) = x { }
|
||||
| ^
|
||||
|
|
||||
= help: you might have meant to match against one of the enum's non-tuple variants
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | if let A::TupleWithFields(3) = x { }
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
LL | if let A::Tuple(3) = x { }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0423, E0532.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
||||
|
|
@ -2,31 +2,17 @@ error[E0423]: expected value, found enum `n::Z`
|
|||
--> $DIR/privacy-enum-ctor.rs:23:9
|
||||
|
|
||||
LL | n::Z;
|
||||
| ^^^^
|
||||
| ^^^^ help: try using one of the enum's variants: `m::Z::Unit`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | m::Z::Fn;
|
||||
| ^^^^^^^^
|
||||
LL | m::Z::Struct;
|
||||
| ^^^^^^^^^^^^
|
||||
LL | m::Z::Unit;
|
||||
| ^^^^^^^^^^
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
|
||||
error[E0423]: expected value, found enum `Z`
|
||||
--> $DIR/privacy-enum-ctor.rs:25:9
|
||||
|
|
||||
LL | Z;
|
||||
| ^
|
||||
| ^ help: try using one of the enum's variants: `m::Z::Unit`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | m::Z::Fn;
|
||||
| ^^^^^^^^
|
||||
LL | m::Z::Struct;
|
||||
| ^^^^^^^^^^^^
|
||||
LL | m::Z::Unit;
|
||||
| ^^^^^^^^^^
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
|
||||
error[E0423]: expected value, found struct variant `Z::Struct`
|
||||
--> $DIR/privacy-enum-ctor.rs:29:20
|
||||
|
|
@ -48,12 +34,9 @@ LL | fn f() {
|
|||
LL | let _: E = m::E;
|
||||
| ^^^^
|
||||
|
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let _: E = E::Fn;
|
||||
| ^^^^^
|
||||
LL | let _: E = E::Struct;
|
||||
| ^^^^^^^^^
|
||||
LL | let _: E = E::Unit;
|
||||
| ^^^^^^^
|
||||
help: a function with a similar name exists
|
||||
|
|
@ -84,12 +67,9 @@ error[E0423]: expected value, found enum `E`
|
|||
LL | let _: E = E;
|
||||
| ^
|
||||
|
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let _: E = E::Fn;
|
||||
| ^^^^^
|
||||
LL | let _: E = E::Struct;
|
||||
| ^^^^^^^^^
|
||||
LL | let _: E = E::Unit;
|
||||
| ^^^^^^^
|
||||
help: consider importing one of these items instead
|
||||
|
|
@ -132,16 +112,9 @@ error[E0423]: expected value, found enum `m::n::Z`
|
|||
--> $DIR/privacy-enum-ctor.rs:57:16
|
||||
|
|
||||
LL | let _: Z = m::n::Z;
|
||||
| ^^^^^^^
|
||||
| ^^^^^^^ help: try using one of the enum's variants: `m::Z::Unit`
|
||||
|
|
||||
help: try using one of the enum's variants
|
||||
|
|
||||
LL | let _: Z = m::Z::Fn;
|
||||
| ^^^^^^^^
|
||||
LL | let _: Z = m::Z::Struct;
|
||||
| ^^^^^^^^^^^^
|
||||
LL | let _: Z = m::Z::Unit;
|
||||
| ^^^^^^^^^^
|
||||
= help: you might have meant to use one of the enum's other variants that have fields
|
||||
|
||||
error[E0412]: cannot find type `Z` in this scope
|
||||
--> $DIR/privacy-enum-ctor.rs:61:12
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue