augustjune / context-applied

Compiler plugin for intuitive tagless final
MIT License
128 stars 8 forks source link

Unused import warning #14

Open steinybot opened 2 years ago

steinybot commented 2 years ago

I have a strange problem when using context-applied with Slinky.

Given the following:

client/src/main/Foo.scala:

import slinky.core.FunctionalComponent
import slinky.core.annotations.react

trait Bar[A] {
  def bar: A
}

object Bar {
  implicit object StringBar extends Bar[String] {
    override def bar: String = "Hello"
  }
}

@react
object Foo {
  val component: FunctionalComponent[Unit] = FunctionalComponent[Unit] { _ => bar[String] }
  private def bar[A](implicit b: Bar[A]): A = b.bar
}

build.sbt:

ThisBuild / scalaVersion := "2.13.7"

lazy val root =
  project
    .in(file("."))
    .aggregate(client)

lazy val client = project
  .enablePlugins(ScalaJSPlugin)
  .settings(
    addCompilerPlugin("org.augustjune" %% "context-applied" % "0.1.4"),
    libraryDependencies += "me.shadaj" %%% "slinky-core" % "0.6.8",
    scalacOptions ++= Seq("-Werror", "-Xlint:unused", "-Ymacro-annotations")
  )

project/plugins.sbt:

addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.1")

It fails with:

[error] /Users/jason/source/bug-reports/client/src/main/scala/Foo.scala:14:2: Unused import
[error] @react
[error]  ^
[error] one error found
[error] (client / Compile / compileIncremental) Compilation failed
[error] Total time: 0 s, completed 12/11/2021, 9:10:01 PM

The @react macro really doesn't do much. It should just expand it to:

object Foo {
  val component: FunctionalComponent[Unit] = FunctionalComponent[Unit] { _ => bar[String] }
  private def bar[A](implicit b: Bar[A]): A = b.bar
  def apply(props: component.Props) = component.apply(props)
}

With -Ymacro-debug-lite I get:

performing macro expansion new react().macroTransform(object Foo extends scala.AnyRef {
  def <init>() = {
    super.<init>();
    ()
  };
  val component: FunctionalComponent[Unit] = FunctionalComponent[Unit](((x$1) => bar[String]));
  private def bar[A](implicit b: Bar[A]): A = {
    abstract <synthetic> <artifact> protected class E$A$Def extends AnyRef;
    <synthetic> <artifact> object Bar$A extends AnyRef {
      <synthetic> <artifact> def <init>() = {
        super.<init>();
        ()
      };
      implicit <synthetic> <artifact> def E$A$Def$Bar(e: E$A$Def): Bar[A] = b
    };
    import Bar$A._;
    <synthetic> <artifact> val A: E$A$Def = null;
    b.bar
  }
}) at RangePosition(/Users/jason/source/bug-reports/client/src/main/scala/Foo.scala, 218, 218, 223)
{
  object Foo extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    val component: FunctionalComponent[Unit] = FunctionalComponent[Unit](((x$1) => bar[String]));
    private def bar[A](implicit b: Bar[A]): A = {
      abstract <synthetic> <artifact> protected class E$A$Def extends AnyRef;
      <synthetic> <artifact> object Bar$A extends AnyRef {
        <synthetic> <artifact> def <init>() = {
          super.<init>();
          ()
        };
        implicit <synthetic> <artifact> def E$A$Def$Bar(e: E$A$Def): Bar[A] = b
      };
      import Bar$A._;
      <synthetic> <artifact> val A: E$A$Def = null;
      b.bar
    };
    def apply(props: component.Props) = component.apply(props)
  };
  ()
}

So I'm pretty sure it is the import Bar$A._; that it is complaining about.

What's weird is that without the react macro it seems to work fine.

You can see a full reproduction here https://github.com/steinybot/bug-reports/tree/context-applied/unused-import