Skip to content

Pattern matching enums: adjust warning #652

@charlesroddie

Description

@charlesroddie

Pattern matching enums: adjust warning

Enums are important for interop with non-F# .Net code. Currently, pattern matching an Enum gives a warning:

type E =
    | A = 0

let f =
    function // "FS0025 Incomplete pattern matches on this expression".
    | E.A -> "A"

I suggest that a different warning be given where:

  • The pattern match is complete, assuming that the code knows the definition of the enum and all enums are valid, AND
  • There are invalid enums (such as enum<E>(1) ) that the pattern match would not handle.

In this case the warning should be "FS**** Enums may take values outside of known cases." Edit: this is now implemented as FS0104

Current problem

To avoid seeing the FS0025 warning, a user must reduce compile-time safety:

  • Disable FS0025 which is extremely unsafe.
  • Use wildcards which eliminate the benefits of the FS0025 warning locally, leading to runtime misbehavior if the pattern match is genuinely incomplete:
let g : E -> unit =
    function
    | _ -> "A"
  • Handle invalid cases explicitly, which requires extra code and again eliminates the benefits of FS0025 locally, causing runtime errors instead of a compile-time warning:
let h =
    function
    | E.A -> "A"
    | _ -> failwith "I didn't want to see a warning so I am failing at runtime."

Pros of change

The change will distinguish between incompleteness resulting from the user failing to match all known enums, which is highly likely to lead to runtime failure, and incompleteness resulting from invalid enums, which is much less likely and indicates a problem with other code, not the code that gives the warning.

With the change, to avoid seeing the warning, a user may simply disable the [Edit: FS0104] warning. This will preserve the safety of exhaustive pattern matching. The user will be warned about additions to the enum for example with an FS0025 warning.

This is with the proviso that you are relying on other code not to be using invalid Enums, and that you have the correct enumeration of the enum at compile time. Both of which are reasonable assumptions.

Cons of change

A small amount of extra code would be needed in the pattern match exhaustiveness check.

Extra information

There are people who think there should be a warning. This is why this suggestion is to change the warning rather than eliminate it (which would have been my personal preference).

Estimated cost (XS, S, M, L, XL, XXL):

M

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions