wartremoverのOrTypeLeastUpperBoundとscalacOptionsの-Wconfを組み合わせる例

数年前に作った以下のwartremoverの話

xuwei-k.hatenablog.com

これの存在自体知らない人は、先にそちら読んでください。

これを使うと、他の手段では見つけにくいミスも、結構効率よく検知出来て、今でも実際に割と使っています。

ただし、これで検知される箇所を全部直すのは、不可能ではないけれど少し厳し過ぎるかなぁ、という微妙な感じです。

例えば

Int | Unit

Seq[Unit] | Unit

などになって、その値を捨てていても、(以下で例を出すものと比較したら)そこまでバグになる可能性は低くて許容範囲かなぁ、と思う一方、例えば

Future[Int] | Unit

cats.effect.IO[Int] | Int

のような状態になっていて、FutureやIOを捨てていたら、先に出したIntなどを捨てているよりは明らかにヤバそうですよね?

しかし、これ書いている最新のwartremover 3.4.1時点のOrTypeLeastUpperBoundには、それ以上細かく制御する機能はありません。

https://github.com/wartremover/wartremover/blob/v3.4.1/core/src/main/scala-3/org/wartremover/warts/OrTypeLeastUpperBound.scala

綺麗な形でそういう汎用的なfilterを入れることが可能ならwartremoverに直接入れるか・・・?と少し考えましたが、綺麗な形で入れるの面倒そうだなぁ、と思って何もやっていません。

しかし、wartremoverは良くも悪くもScalaのcompiler pluginとしてwarnやerrorを出すので、そのエラーメッセージに対して -Wconf などが使える、というメリットがあります。

そこで、例えば

「OrTypeLeastUpperBoundの中でもFutureが出てきた場合だけ検知して、他は許可」

という設定は以下のように書くと可能です

scalacOptions +=
  """-Wconf:msg=least upper bound is `(?!.*scala\.concurrent\.Future).*`:silent"""

やった〜。

単にこれをメモしておくだけのエントリでした。

wartremoverが出すものに対して -Wconf 使えるのは、こういう時に便利なので、覚えておいて使いこなせるようになりましょう。