-
Notifications
You must be signed in to change notification settings - Fork 825
Enum match warning #4522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum match warning #4522
Conversation
…match covers all known enum values
:) I think it is. There is this in Symbols.fs:
and the IlxGen.fs just iterates fiels |
What should the behavior be for enums defined with Ideally the new warning would check for exhastivity using every possible combination of the defined enum values, but if this is too hard then the existing warning can be retained. |
@dhwed Yeah that could be done, and it probably should (the original issue specified that the warning should happen when "the pattern match is complete and ... all enums [values] are valid") |
@jwosty Don't forget you can use a task to update XLF, see https://github.com/Microsoft/visualfsharp/blob/master/DEVGUIDE.md#when-modifying-adding-or-removing-keywords-or-compiler-messages |
@dsyme right, only problem is I'm developing on OSX. So no /t:UpdateXlf for me :( |
3a73ba2
to
cae1b3b
Compare
cae1b3b
to
223ee18
Compare
We don't tend to do anything specific for FlagsAttribute in the language or compiler, because you can combine enums that don't have FlagsAttribute (at least F# doesn't enforce the attribute be there). |
@dsyme so should this be the behavior for all of them then? As in, it would consider an enum match "complete" (in that it covers all known values) when all combinations are covered? Or should we just not do this at all? |
I see. Yes, perhaps the use of a different error message should use a different number and appropriate message if the enum has FlagsAttribute? |
@dsyme What do you have in mind? Maybe "Enums may take values outside of known cases. Enums marked with FlagsAttribute also may take any combination of values."? |
c94ec8a
to
141f713
Compare
src/fsharp/xlf/FSStrings.cs.xlf
Outdated
@@ -1422,6 +1422,11 @@ | |||
<target state="translated"> Nespárované prvky se budou ignorovat.</target> | |||
<note /> | |||
</trans-unit> | |||
<trans-unit id="EnumMatchIncomplete1"> | |||
<source>Enums may take values outside known cases.</source> | |||
<target state="translated">Enums may take values outside known cases.</target> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These shouldn't be in the 'translated' state - same for all of the non-English translations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saul Should it be "new"?
582c8d8
to
247b44c
Compare
@dotnet-bot test this please |
c4671ce
to
542ee6e
Compare
542ee6e
to
074f494
Compare
Alright, undid the whitespace changes @dsyme |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more whitespace changes to undo
let flds = tcref |> actualTysOfInstanceRecdFields (mkTyconRefInst tcref tinst) |> mkOneKnown tm j | ||
go p (fun _ -> Expr.Op(TOp.Recd(RecdExpr, tcref),tinst, flds,m)) | ||
let flds, eCoversVals = tcref |> actualTysOfInstanceRecdFields (mkTyconRefInst tcref tinst) |> mkOneKnown tm j | ||
go p (fun _ -> Expr.Op(TOp.Recd(RecdExpr, tcref),tinst, flds,m), eCoversVals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more whitespace changes to undo in this file please
let failingWhenClause = refuted |> List.exists (function RefutedWhenClause -> true | _ -> false) | ||
Some(text,failingWhenClause) | ||
try | ||
let refutations = refuted |> List.collect (function RefutedWhenClause -> [] | (RefutedInvestigation(path,discrim)) -> [RefuteDiscrimSet g m path discrim]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more whitespace changes to undo in this file please
5359b5f
to
83daa81
Compare
83daa81
to
269ef99
Compare
This should satisfy all requested changes now. EDIT: Wait, hold on. I realized I never did anything about the FlagsAttribute thing. I won't be able to get around to this for a little while, but I will at some point (within weeks?). I don't know if it would be best to just wait for me to get around to it in this PR, or accept this one and have me open another PR later (this one is complete in its own right; FlagsAttribute stuff would only add another warning) |
Great work! :) |
@dsyme should this be tagged as |
No, it's just an error/warning improvement not a language change. Warning numbers change in one case but I don't think we need wait for a new language version for that |
and earlier you wrote:
I use the Point I wanted to make is: "testing exhaustively" for all possible combinations. When programmers write something like that, I usually tell them: consider the worst case scenario. Here that would be a 64-bit enum with That is, simply put, 2^64 - 1 possible combinations. That will take longer than one or two cup of coffees ;). Even in a minor case, say, 24 flags, and assuming only the low 24 bits are set, you would still need to check 2^24 -1 combinations, which is considerable. Of course, you could do the reverse: simply count all the pattern match cases, if they do not equal the expected amount of tests, then search for a hint to use in the warning message. But if you do consider an addition to the PR like this, i.e., checking for all possible flags, you should probably create a reasonable upper limit. Actually, I'm not sure it is worth the effort. Enums with So instead of extending this PR with testing all possible combinations, I'd suggest two things (probably to go into a separate PR):
|
@abelbraaksma that's a good point, actually -- I think you're right and it would not be worth the effort to try to make something like this work. As for workarounds, I'm don't feel that there needs to be any standard lib/ compiler work to be done for this. The user should be able to come up with a way to use the type system to produce an incomplete match warning somewhere, e.g. by splitting the number into its bits, mapping them into a set of flags, then pattern matching inside that. Or maybe some clever active pattern use, as you say. |
@jwosty This is working well for me for enums defined in F#. However when consuming standard .Net enums the error is always the new one "FS0104 Enums maytake values outside known cases", even when there are defined cases that are not covered. |
@charlesroddie off the top of my head, my other PR probably doesn't address this. I was not aware of it and hadn't thought to test that out. F# must define enums slightly differently than other languages, as the code I wrote assumes that all the enum fields are |
First attempt at fslang-suggestions #652. It seems to work correctly so far, but tests will be coming soon.
One question -- this can't possibly be the first piece of code to grab all the defined enum values from a Tycon; is there a function that does this already? Currently this fix just looks through all the enum type's static fields (see PatternMatchCompilation.fs changes)