以下のこれ
機能としては、詳細を省略してすごく雑に説明すると
TableQuery[A]
と書いたら
TableQuery[A](tag => new A(tag))
と展開してくれるだけだと思います。
「そんなのわざわざマクロとして提供する必要ある?」
みたいな気持ちになる可能性はありますが、その話は置いておくとして、Scala 2ではcompile通るのに、Scala 3では通らないパターンがあることがわかりました。
詳細はこっちにも書いたので、それ見てもらってもいいのですが、
https://github.com/scala/scala3/issues/19933#issuecomment-2816881828
動かないパターンとは
「TableQueryに渡す型の定義が内部classで、かつ、それの定義とTableQueryのmacro呼び出しが、継承関係がある別のsub class内の場合」
です。言葉よりコードの方がわかりやすい気がしますが、つまりこう
import slick.jdbc.JdbcProfile case class C(x: Int) trait A { protected val profile: JdbcProfile import profile.api.* protected class B(tag: Tag) extends Table[C](tag, "my_table") { override def * = ??? } } trait D extends A { import profile.api.* val query = TableQuery[B] }
これをやると、macro展開内部でtype errorになって、Scala詳しくない人にとっては「は???何これ???」となります
[error] 18 | val query = TableQuery[B] [error] | ^^^^^^^^^^^^^ [error] | Found: A.this.B [error] | Required: D.this.B
-Xprint:all
するなどして内部の途中のTreeを見ると以下のようになってました
val query: slick.lifted.TableQuery[D.this.B] = slick.lifted.TableQuery.apply[D.this.B]( (tag: slick.lifted.Tag) => new A.this.B(tag)): slick.lifted.TableQuery[D.this.B]
new
してる部分だけ A.this.B
になっていて、他は D.this.B
なので、確かに型が合っていませんね。
そして適当に検索したらScala 3本体の上記のissueに辿り着きました。
このblog書いてる時点でコメントしたばかりなので、特にまだ反応かえってきてませんが、おそらくissueのタイトルと、slickのコードを見る限り、同じ問題・・・?
対策として思いつくものを3つくらいissueに書いておきましたが、どの方法がいいんでしょうかね。
単に new
するコード書くだけなら、大抵scalafixで全自動書き換え可能だし、macro使わないものに書き換えてしまおうかなぁ、どうしようかなぁ・・・
追記: