You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Irrefutable if let on a single-variant enum only produces () value #61788
enumEnum{Variant(i32),}fnstuff(x:Enum) -> i32{ifletEnum::Variant(value) = x {
value
}}
gives the following error:
Compiling playground v0.0.1(/playground)
error[E0317]:if may be missing an else clause
--> src/lib.rs:6:5
|
6 | / ifletEnum::Variant(value) = x {7 | | value
8 | | }
| |_____^ expected (), found i32
|
= note: expected type `()`
found type `i32`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0317`.
error:Could not compile `playground`.
which is weird, since the else clause would never be visited even if it was present.
The equivalent one-arm match
enumEnum{Variant(i32),}fnstuff(x:Enum) -> i32{match x {Enum::Variant(value) => value,}}
compiles just fine (expectedly).
Adding an else { unreachable!() } branch to the if let is, of course, possible, but unelegant, and really shouldn't be needed, as it can be inferred at compile time.
I think this is too niche to deserve a special diagnostics (and I don't think we should substantially work on diagnostics for if until let_chains is implemented).
which is weird, since the else clause would never be visited even if it was present.
I didn't know let Enum::Variant(value) = x; was a valid syntax. If I did, I probably wouldn't have filed the issue, because of course, in hindsight, that's how you write an infallible if let.
(With that knowledge in mind) I agree that it's only a diagnostics issue and no language change is needed here.
And I fully agree that it's a niche low-priority quirk that should maybe be fixed "someday". (I don't know what let_chains but even then I'd guess that this one is lower priority than that).
But we do only after typechecking, and we don't if there are any errors before then. Quite a few lints have similar issues related to not happening early enough.
You can't, but you can write the lint in such a way that it triggers regardless. We're getting to typechecking, we should be able to detect irrefutability by then. It just can't use the standard linting machinery (like a few other lints already do to avoid being silenced by accident).
Activity
varkor commentedon Jun 12, 2019
You can match irrefutably without
ifin this case:though maybe we should give this special diagnostics.
Centril commentedon Jun 12, 2019
I think this is too niche to deserve a special diagnostics (and I don't think we should substantially work on diagnostics for
ifuntil let_chains is implemented).if letis defined by a desugaring:becomes:
so what you really wrote is:
The block
{}is typed at()which does not unify withvalueunless it is also typed at().moxian commentedon Jun 14, 2019
I didn't know
let Enum::Variant(value) = x;was a valid syntax. If I did, I probably wouldn't have filed the issue, because of course, in hindsight, that's how you write an infallibleif let.(With that knowledge in mind) I agree that it's only a diagnostics issue and no language change is needed here.
And I fully agree that it's a niche low-priority quirk that should maybe be fixed "someday". (I don't know what
let_chainsbut even then I'd guess that this one is lower priority than that).estebank commentedon Jul 25, 2019
I think the appropriate thing to do here would be to lint on
if let Irrefutable = foo {}, which would have clarified things.Centril commentedon Jul 25, 2019
@estebank We already do. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f95c48ce63d45bebaa45ca2cab5641fb
estebank commentedon Jul 25, 2019
But we do only after typechecking, and we don't if there are any errors before then. Quite a few lints have similar issues related to not happening early enough.
Centril commentedon Jul 25, 2019
@estebank How do you know that the pattern is irrefutable before match checking in HAIR?
estebank commentedon Jul 25, 2019
You can't, but you can write the lint in such a way that it triggers regardless. We're getting to typechecking, we should be able to detect irrefutability by then. It just can't use the standard linting machinery (like a few other lints already do to avoid being silenced by accident).
Suggest turnging `if let` into irrefutable `let` if appropriate
Suggest turnging `if let` into irrefutable `let` if appropriate
Suggest turnging `if let` into irrefutable `let` if appropriate
Rollup merge of rust-lang#120479 - estebank:issue-61788, r=wesleywiser
Rollup merge of rust-lang#120479 - estebank:issue-61788, r=wesleywiser
Unrolled build for rust-lang#120479