Skip to content

Instantly share code, notes, and snippets.

@dcsobral
Created April 15, 2020 23:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dcsobral/903602e82deacb55192fe8910bb14a07 to your computer and use it in GitHub Desktop.
Save dcsobral/903602e82deacb55192fe8910bb14a07 to your computer and use it in GitHub Desktop.
Scala Configurable Warnings

Pull request #8373 implementing issue 333 (but please note differences).

Pull request description follows:

This PR adds a -Wconf compiler flag that allows filtering and configuring compiler warnings (silence them, or turn them into errors).

It also integrates the fantastic silencer compiler plugin by @ghik into the compiler, which allows suppressing warnings locally using the @nowarn annotation.

Configurable Warnings

Warnings are assigned a category.

Warnings can be filtered by category, by message regex, by site where they are issued, and by source path. Deprecations can additionally be filtered by origin (deprecated definition) and since version.

Filtered warnings can be reported as error, warning, info, summary (like deprecations) or silent.

Local Suppression

The @nowarn annotation suppresses warnings within the scope covered by the annotation.

  • @nowarn def foo = ..., @nowarn class C { ... }: suppress warnings in a definition
  • expression: @nowarn: suppress warnings in a specific expression The annotation can be configured to filter selected warnings, for example @nowarn("cat=deprecation") only suppresses deprecation warnings. The filter configuration syntax is the same as in -Wconf.

Help Text

$> scalac -Wconf:help
Configure compiler warnings.
Syntax: -Wconf:<filters>:<action>,<filters>:<action>,...
multiple <filters> are combined with &, i.e., <filter>&...&<filter>

Note: Run with `-Wconf:any:warning-verbose` to print warnings with their category, site,
and (for deprecations) origin and since-version.

<filter>
  - Any message: any

  - Message categories: cat=deprecation, cat=lint, cat=lint-infer-any
    The full list of warning categories is shown at the end of this help text.

  - Message content: msg=regex
    The regex need only match some part of the message, not all of it.

  - Site where the warning is triggered: site=my\.package\..*
    The regex must match the full name (`package.Class.method`) of the warning position.

  - Source file name: src=src_managed/.*
    If `-rootdir` is specified, the regex must match the canonical path relative to the
    root directory. Otherwise, the regex must match the canonical path relative to any
    path segment (`b/.*Test.scala` matches `/a/b/XTest.scala` but not `/ab/Test.scala`).
    Use unix-style paths, separated by `/`.

  - Origin of deprecation: origin=external\.package\..*
    The regex must match the full name (`package.Class.method`) of the deprecated entity.

  - Since of deprecation: since<1.24
    Valid operators: <, =, >, valid versions: N, N.M, N.M.P. Compares against the first
    version of the form N, N.M or N.M.P found in the `since` parameter of the deprecation,
    for example `1.2.3` in `@deprecated("", "some lib 1.2.3-foo")`.

<action>
  - error / e
  - warning / w
  - warning-summary / ws (summary with the number of warnings, like for deprecations)
  - warning-verbose / wv (show warning category and site)
  - info / i             (infos are not counted as warnings and don't affect `-Werror`)
  - info-summary / is
  - info-verbose / iv
  - silent / s

The default configuration is:
  -Wconf:cat=deprecation:ws,cat=feature:ws,cat=optimizer:ws

User-defined configurations are added to the left. The leftmost rule matching
a warning message defines the action.

Examples:
  - change every warning into an error: -Wconf:any:error
  - silence certain deprecations: -Wconf:origin=some\.lib\..*&since>2.2:s

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-missing-interpolator, lint-nonlocal-return, lint-nullary-override, lint-nullary-unit, lint-option-implicit, lint-package-object-classes, lint-poly-implicit-overload, lint-private-shadow, lint-recurse-with-default, lint-serial, lint-stars-align, lint-type-parameter-shadow, lint-unit-specialization
 - optimizer
 - other, other-debug, other-match-analysis, other-migration, 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

To suppress warnings locally, use the `scala.annotation.nowarn` annotation.

Note: on the command-line you might need to quote configurations containing `*` or `&`
to prevent the shell from expanding patterns.

Significant changes

  • What's described above in the PR description
  • MiMa exception for addition of scala.annotation.nowarn
  • Adds a -rootdir compiler flag. It is used to relativize file paths when using source filters (-Wconf:src=some/source/File.scala:s), there might be other uses for it in the future.
  • Compiler API changes
    • warning methods in currentRun.reporting and context reporter take new Category parameter. The global.reporter is unchanged, warnings reported through it are not filtered by Wconf.
    • Removed a few deprecated methods (compilationUnit.error/warning)
  • Reporting warnings is now delayed until after typer, because the typer collects @nowarn annotations.
  • If we stop before typer (e.g., because there are errors in the parser), all warnings are shown, even if they are enclosed in @nowarn
  • If a phase before typer has both errors and warnings, all errors are printed before the warnings.
  • Unchecked warnings are now all shown by default (they were summarized like deprecations before)
  • The -deprecation, -feature and -unchecked settings are no longer directly used in the compiler, they are shortcuts for specific Wconf configurations. the compiler only looks at -Wconf.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment