Macro-generated match gives an exhaustivity warning, even though it shouldn't
See original GitHub issueCompiler version
3.0.0-RC3
Minimized example
In a macro, I want to generate a pattern match for a sealed trait/enum, covering each case and performing some actions. The code I’ve got is the following:
import scala.quoted.*
object MatchTest {
inline def test[T](inline obj: T): Unit = ${testImpl('obj)}
def testImpl[T](objExpr: Expr[T])(using qctx: Quotes, t: Type[T]): Expr[Unit] = {
import qctx.reflect.*
val obj = objExpr.asTerm
val cases = obj.tpe.typeSymbol.children.map { child =>
val subtype = TypeIdent(child)
val bind = Symbol.newBind(Symbol.spliceOwner, "c", Flags.EmptyFlags, subtype.tpe)
CaseDef(Bind(bind, Typed(Ref(bind), subtype)), None, '{()}.asTerm)
}
val bind = Symbol.newBind(Symbol.spliceOwner, "o", Flags.EmptyFlags, obj.tpe)
val result = Match(obj, cases)
println(result.show(using Printer.TreeAnsiCode))
result.asExprOf[Unit]
}
}
Tested using:
sealed trait P
case class PC1(a: String) extends P
case class PC2(b: Int) extends P
MatchTest.test(PC2(10): P)
Output
(PC2.apply(10): P) match {
case c @ (c: PC1) =>
()
case c @ (`c₂`: PC2) =>
()
}
[warn] -- [E029] Pattern Match Exhaustivity Warning: Test.scala:25:17
[warn] 25 | MatchTest.test(PC2(10): P)
[warn] | ^^^^^^^^^^
[warn] | match may not be exhaustive.
[warn] |
[warn] | It would fail on pattern case: PC1(_), PC2(_)
[warn] | This location contains code that was inlined from Test.scala:25
Expectation
I wouldn’t expect an exhaustivity warning, as all cases are covered.
I know that the match isn’t perfect, but I don’t know how to generate a better one. Specifically, instead of c @ (c: PC1)
, I’d like to generate c @ (_: PC1)
, but I can’t find a way to create a _
using the current macro API. A candidate would be Ident(TermRef(NoPrefix, "_"))
, but then I don’t know how to get a NoPrefix
instance.
I also tried adding a third branch with an : Any
case, but this didn’t help - got the same exhaustivity warning
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (9 by maintainers)
Top Results From Across the Web
Solving warnings like match non exhaustive and calling ...
You obviously forgot two base cases when only one in two lists is empty. Since these cases are malformed inputs, you can use...
Read more >compiler/rustc_lint_defs/src/builtin.rs - toolchain/rustc
macro with a file that contains more than one expression. ... The `must_not_suspend` lint guards against values that shouldn't be held across suspend...
Read more >Invalid "may not be exhaustive" compiler warning ... - GitHub
problem. No such warning occurred on 2.13.3, which I've just upgraded from, and the match is exhaustive, as the ClassTag prevents erasure ...
Read more >Trouble with 2.13.4 exhaustivity checking being too strict
Even with the strict-unsealed-patmat turned off, the compiler complains that: match ... It can match a warning by message, category, site.
Read more >automake - GNU.org
The build tree is rooted in the current directory at the time configure was run, and is populated with all object files, programs,...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@nicolasstucki Thanks! Changed in quicklens 😃
Ah, I see, thanks 😃 I’ll try rewriting that to if-else then