scalafix icon indicating copy to clipboard operation
scalafix copied to clipboard

Explicit result breaks when using `this.type`.

Open ckipp01 opened this issue 2 years ago • 3 comments

I encountered this when writing a Mill plugin. When creating an ExternalModule you'll have code that looks like this:

import mill._
import mill.define.Command
import mill.define.ExternalModule
import mill.eval.Evaluator
import mill.main.EvaluatorScopt

object Example extends ExternalModule {

  def foo(ev: Evaluator): Command[Unit] = T.command {}

  implicit def millScoptEvaluatorReads[T]: EvaluatorScopt[T] =
    new mill.main.EvaluatorScopt[T]()

  lazy val millDiscover = mill.define.Discover[this.type]

}

If you run scalafix against this wanting ExplicitResultTypes you'll end up with broken code since the final lazy vall millDiscover will turn into:

  lazy val millDiscover: Discover[Example] = mill.define.Discover[this.type]

Which will error with:

not found: type Example

I'd expect running this rule not to break my code.

You can reproduce this with the Scala file up above placed in a foo/src/Example.scala and the following files:

// build.sc
import mill._
import scalalib._
import mill.scalalib.api.ZincWorkerUtil
import $ivy.`com.goyeau::mill-scalafix::0.2.8`
import com.goyeau.mill.scalafix.ScalafixModule

object foo extends ScalaModule with ScalafixModule {

  def scalaVersion = "2.13.8"

  def scalafixScalaBinaryVersion =
    ZincWorkerUtil.scalaBinaryVersion(scalaVersion())

  override def compileIvyDeps = super.compileIvyDeps() ++ Agg(
    ivy"com.lihaoyi::mill-scalalib:0.10.5"
  )
}
// .scalafix.conf
rules = [
  ExplicitResultTypes
]

Then you can either run them ~via Mill or~ Metals.

ckipp01 avatar Jul 14 '22 11:07 ckipp01

Actually hold on. Running this will mill foo.fix doesn't actually apply the patch, but running it with Metals does. I wonder why there is a difference there. This might be something funky going on with Metals.

ckipp01 avatar Jul 14 '22 11:07 ckipp01

Thanks for reporting!

I guess there is something fishy in https://github.com/scalacenter/scalafix/blob/449a06a03d2595a1ec6f44201353881b3edc4aee/scalafix-rules/src/main/scala-2/scalafix/internal/rule/CompilerTypePrinter.scala#L299-L389

I wonder why there is a difference there. This might be something funky going on with Metals.

Probably related to https://github.com/scalacenter/scalafix/issues/1534?

bjaglin avatar Sep 20 '22 23:09 bjaglin

Actually hold on. Running this will mill foo.fix doesn't actually apply the patch, but running it with Metals does. I wonder why there is a difference there. This might be something funky going on with Metals.

This might be an issue with mill-scalafix: https://github.com/joan38/mill-scalafix/issues/174

lefou avatar Jan 05 '24 15:01 lefou