-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3.4.0 breaks match exhaustive checking of a macros #22212
Comments
seems like this is the cause, what can we do in this situation? |
I can understand why you wouldn't want the compiler generating warnings for macro code that you don't necessarily have any control over as a user, but that could be done by macro authors with an |
while looking into this I used the (I cleaned up parts of the printed code to make it more legible, so it might not be 100% accurate, but it shows the idea): Source: enum Test {
case Case1
case Case2
case Case3(value: String)
}
val s: Signal[Test] = Val(Test.Case2)
// ...
s.splitMatchOne
.handleType[Test.Case3].apply { (init, sig) =>
// ...
}
.toSignal
Scala MyModule.s.map[
(Int, Any)](
{
def $anonfun(
i: MyModule.Test)
: (Int, Any) =
i match // a REAL match
{
case t @_: MyModule.Test.Case3 =>
{
val res: Any =
t:
MyModule
.Test.Case3
Tuple2.apply[Int, Any](0,res)
}
}
closure($anonfun)
} Scala def $anonfun(
i: MyModule.Test
): (Int, Any) =
matchResult5[(Int, Any)]:
{
case val x6:
(i : MyModule.Test) = i
if // an if-else instead of a match
x6.$isInstanceOf[MyModule.Test.Case3]
then
{
case val t: MyModule.Test.Case3
= x6.$asInstanceOf[MyModule.Test.Case3]
return[matchResult5]
{
val res: Any =
t:
MyModule
.Test.
Case3
Tuple2.apply[Int, Any](0, res)
}
}
else ()
throw new MatchError(x6)
}
closure($anonfun) |
Seems to me (from the debug) that a desugaring stage is being ran sooner than we'd like on the match modes... The splicing of a quote should always produce legal scala code, but this clearly isn't ( |
I also tried adding more "cases" to make sure it's not an edge case optimization - and no, it just results in more case val x6:
(i : MyModule.Test) = i
if x6.$isInstanceOf[MyModule.Test.Case3]
then
// ...
return // ...
else ()
if x6.eq(MyModule.Test.Case1)
then
// ...
return // ...
else ()
throw new MatchError(x6) P.S. |
Ugh. 😕 Also, please provide the definition of the dependencies/build when raising issues. //> using dep com.raquo::airstream::17.2.0
//> using dep com.raquo::laminar::17.2.0
//> using platform js
import com.raquo.laminar.api.L.*
object Main {
sealed abstract class Page {}
sealed abstract class ToolPage extends Page {}
case object CompilePage extends ToolPage {}
case object AsmEmulatePage extends ToolPage {}
case object BugHuntersPage extends Page {}
def testSignal(pageSignal: Signal[ToolPage]): Unit = {
pageSignal
.splitMatchOne
.handleValue(CompilePage)(())
.toSignal
}
def main(args: Array[String]): Unit = ()
} |
We did reenable exhaustivity checks for 3.5.1 onwards (in #20403, leaving reachability warnings turned off), so some of that back and forth is expected, but it should work for 3.6, so I will investigate that further |
Minimised: import scala.quoted._
sealed trait Foo
case object Bar extends Foo
case object Baz extends Foo
object Macro {
inline def makeMatch() = ${makeMatchImpl}
def makeMatchImpl(using Quotes) = {
'{
(_: Foo) match
case Bar => ()
}
}
} @main def main() = Macro.makeMatch() |
Compiler version
Airstream released v17.2.0, which introduce a macro that help users to "split" signal of a ADT into signal of its children.
This macros re-arranges
case
blocks and create amatch
expr out of it, there for leverages the compiler's exhaustive checking.It works on
3.3.4
, but stop working on>=3.4.0
Minimized code (required Airstream v17.2.0)
Expectation
on scala
3.3.4 LTS
, compiler will warn "match may not exhaustive".it should remains so on
>=3.4
UPDATED: further checking yields the following results:
3.3.4 works, 3.4.0 doesn't, 3.5.0 doesn't, 3.5.1 works, 3.5.2 works, 3.6.2 doesn't
The text was updated successfully, but these errors were encountered: