Closed jilen closed 12 months ago
The change in question is scala/scala#10083. /cc @som-snytt
Can you give an example of what you can't do now?
Can the macro emit @annotation.nowarn("cat=other-implicit-type")
?
This is pre-second-coffee, but you can always write : Any
and the whitebox macro produces a narrower type.
@som-snytt any advice we have for macro authors would be good to add to the PR description
I added a line to the PR without thinking about it, but please add a use case here if necessary.
@SethTisue
Can you give an example of what you can't do now?
The case for me is defining quill's QueryMeta
implicit val personMeta = materializedQueryMeta[Person]
Quill will use the concrete type info later. If specify type to QueryMeta[Person]
it will become dynamic query.
@jilen Does that mean implicit val personMeta: Any = materializedQueryMeta[Person]
does not work? I looked briefly at quill last year in the context of a bug related to macro and result inference, but I don't remember much about it.
@som-snytt Confirmed adding : Any
gets things done. Thanks
My bad, just find Any
not working
//> using lib org.scala-lang:scala-reflect:2.13.11
//> using scala "2.13.11"
//> using options -Xsource:3
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
class FooMacroImpl(val c: Context) {
import c.universe._
def fooImpl: Tree = {
val c = Constant("foo")
q"${c}"
}
}
object Foo {
def foo: String = macro FooMacroImpl.fooImpl
}
Then
scala> implicit val foo: Any = Foo.foo
val foo: Any = foo
@jilen what behavior did you expect, there?
@jilen what behavior did you expect, there?
implicit val foo: Any = Foo.foo
I thought the type of foo
should be String
(returned by whitebox macro)
I'll take a look today. I don't want anything to spoil Seth's Scala Days. Because really, how many Scala Days do have in this life? Every Scala Day is precious.
I thought the type of foo should be String (returned by whitebox macro)
Ah, I had misunderstood Som's suggestion, but I understand better now.
I'm surprised to learn that that would be expected behavior. when I write implicit val foo: Any = ...
, I would not have expected anything I could substitute for ...
to have any influence on what type foo
gets, give that I explicitly asked for the type to be Any
.
@som-snytt you're sure that's expected...?
I guess in Scala 3 this issue can't arise because there aren't whitebox macros...? Perhaps one possible resolution here would be to say that it's expected for -Xsource:3
to complain when you're doing something that isn't even possible in Scala 3 at all?
perhaps @guizmaii could enlighten us on how people using Scala 3 with Quill would be expected to write this code?
@SethTisue Yes, it's fundamental to whiteboxness and also works that way in Scala 3 via transparent inline
.
Oh wait, sorry lack of sleep, the implicit is in the wrong place.
implicit def myimplicit: Any = macro mywhitebox
lets the type of myimplicit expansion get refined.
I'll take a look at how the behavior is relied upon in quill.
implicit def myimplicit: Any = macro mywhitebox
lets the type of myimplicit expansion get refined.
Okay, that makes more sense.
But it doesn't seem to help OP. Their desire to have an implicit val
with an inferred type is fundamentally at odds with the explicit-type requirement.
also works that way in Scala 3 via
transparent inline
I'd like to see a spelled-out example of that; in Scala 3, can I have a given
whose type isn't written, but comes from a transparent inline
?
@som-snytt One thing I don't know here is whether the @nowarn
mechanism is sufficiently powerful to convert an error (at least some kind of errors, I mean) into a warning, or to silence it altogether? Or does the way scala/scala#10083 is implemented prevent that?
They call it issueNormalTypeError
. So it means no soup for you. Now we also know why it's called quill, it's not the writing implement but the porcupine defense mechanism. I would have named it sharpie to make the dual metaphor explicit.
I'd like to see a spelled-out example of that; in Scala 3, can I have a
given
whose type isn't written, but comes from atransparent inline
?
It's written but it's also transparent: https://dotty.epfl.ch/docs/reference/contextual/givens.html#given-macros-1
We cannot update to 2.13.11 because of this issue and the fact we cannot add explicit types for Quill. We use -Xsource:3
and I see -Wconf:cat=other-implicit-type:s
is simply being ignored with that option together.
Not sure if this is clear from the discussion, sorry if I'm just adding noise; the static type of an implicit whitebox macro def defines what type can be summoned:
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
class A
class B extends A
class FooMacroImpl(val c: Context) {
import c.universe._
def fooImpl: Tree = {
q"new B()"
}
}
object Foo {
implicit def foo: A = macro FooMacroImpl.fooImpl
}
scala> import Foo._
import Foo._
scala> foo
val res0: B = B@49005dc4
scala> implicitly[B]
^
error: could not find implicit value for parameter e: B
scala> implicitly[A]
val res2: A = B@a1e578f
A good approach to migration errors under -Xsource:3
could be to make them fatal warnings instead, and allow users to override that default using -Wconf
/ @nowarn
.
I'll pursue that approach: instead of knobs to enable migration behaviors, -Wconf
provides levers for the warnings, and for behaviors such as override inference, emit warnings. The implicit search change was split out, and never received subsequent attention. The are a handful of behaviors which are not mere syntax or checks.
Note to self: one way to simplify -Xlint/-Wconf
is instead of enabling lints, you silence their output. (Internally, silencing a lint category could just turn off the lint.)
Bottom line what do I do with scala 2.13.12?
Top line, the idiom of the title is -Wconf:cat=scala3-migration:s
.
Sample potential dogfooding at https://github.com/scala/scala/pull/10551/files#diff-5634c415cd8c8504fdb973a3ed092300b43c4b8fc1e184f7249eb29a55511f91R417
compile / scalacOptions ++= Seq("-Wconf:cat=scala3-migration&msg=elidable&site=scala.Predef:s"),
The wconf is :e
by default to error, so :s
silences it and :w
dials it back to warning, etc.
The scala
2.13.11
version requires explicit type of implicit definition. Then it become impossible to usewhitebox macro
to return the narrowed type.