Search code examples
scalapattern-matchingcompiler-flagsscala-3non-exhaustive-patterns

Make Compile Fail on Non-Exhaustive Match in Scala 3


Since Scala 2.13, -Wconf compiler flag allows to precisely control over which warnings should be handled as errors. The configuration string for -Wconf however is not always the same when migrating to Scala 3.

In particular, I'm struggling to find how to make the compilation fail on non-exhaustive pattern matches in Scala 3. In Scala 2.13 I was used to rely on

-Wconf:cat=other-match-analysis:error

but the same string is not recognised in Scala 3:

 Failed to parse `-Wconf` configuration: cat=other-match-analysis:error

The documentation https://docs.scala-lang.org/scala3/guides/migration/options-lookup.html does not seem to cover this case, unless I've missed it.

It's always possible to turn all warnings into errors, but it would be great to have the same degree of granularity that Scala 2.13 offers.

Would anyone be able to point me to how to configure Scala 3 compiler to fail the compilation when a pattern match is non-exhaustive, without turning all other warnings into errors?

Similar question for Scala 2.13 Make Compile Fail on Non-Exhaustive Match in SBT


Solution

  • I think Scala 3 is well behind in regards to detecting warnings and categorize them in comparison with Scala 2.13. I could not find the exact documentation for -Wconf for scala 3 to reference it here but the following might be useful.

    Here's how scala 2.13 shows what it supports in -Wconf format

    scala -Wconf help
    

    It produces help message with following part related to categories of error/warning as

    Full list of message categories:
     - deprecation
     - feature, feature-dynamics, feature-existentials, feature-higher-kinds, feature-implicit-conversions, feature-macros, feature-postfix-ops, feature-reflective-calls
     - java-source
     - lint, lint-adapted-args, lint-byname-implicit, lint-constant, lint-delayedinit-select, lint-deprecation, lint-doc-detached, lint-eta-sam, lint-eta-zero, lint-implicit-not-found, lint-inaccessible, lint-infer-any, lint-int-div-to-float, lint-missing-interpolator, lint-multiarg-infix, lint-nonlocal-return, lint-nullary-unit, lint-numeric-methods, lint-option-implicit, lint-package-object-classes, lint-performance, lint-poly-implicit-overload, lint-private-shadow, lint-recurse-with-default, lint-serial, lint-stars-align, lint-type-parameter-shadow, lint-unit-specialization, lint-universal-methods
     - optimizer
     - other, other-debug, other-implicit-type, other-match-analysis, other-migration, other-non-cooperative-equals, other-nullary-override, other-pure-statement, other-shadowing
     - scaladoc
     - unchecked
     - unused, unused-imports, unused-locals, unused-nowarn, unused-params, unused-pat-vars, unused-privates
     - w-flag, w-flag-dead-code, w-flag-extra-implicit, w-flag-numeric-widen, w-flag-self-implicit, w-flag-value-discard
    

    Same command doesn't work in scala 3.3 and the closest I can get to some sorts of documentation is following

    scala -W
    

    An interesting part of warnings configuration is following

         -Wunused  Enable or disable specific `unused` warnings
                     Choices :
                     - nowarn,
                     - all,
                     - imports :
                        Warn if an import selector is not referenced.
                        NOTE : overrided by -Wunused:strict-no-implicit-warn,
                     - privates :
                        Warn if a private member is unused,
                     - locals :
                        Warn if a local definition is unused,
                     - explicits :
                        Warn if an explicit parameter is unused,
                     - implicits :
                        Warn if an implicit parameter is unused,
                     - params :
                        Enable -Wunused:explicits,implicits,
                     - linted :
                        Enable -Wunused:imports,privates,locals,implicits,
                     - strict-no-implicit-warn :
                        Same as -Wunused:import, only for imports of explicit named
                     members.
                        NOTE : This overrides -Wunused:imports and NOT set by
                     -Wunused:all,
                     - unsafe-warn-patvars :
                        (UNSAFE) Warn if a variable bound in a pattern is unused.
                        This warning can generate false positive, as warning cannot be
                        suppressed yet.