Skip to content

Commit 147f562

Browse files
committed
Fix #21721: make case TypeBlock(_, _) not match non-type Block
TypeBlocks are represented as normal Blocks in the Quotes API. The current TypeTest for TypeBlock is exactly the same as the TypeTest for Block, which means that case TypeBlock(_, _) matches every block. The implementation of unapply on TypeBlockModule, however, gives back (List[TypeDef], TypeTree). It constructs the List[TypeDef] by mapping over every statement, turning it into a TypeDef by using a match with the pattern case alias: TypeDef => alias Since the TypeTest matches any Block and not only Blocks that are TypeBlocks, the statemnts can be anything, not just TypeDefs, which lets the whole case TypeBlock(_, _) pattern fail with a MatchError. This commit fixes the problem by making the TypeTest check whether the Block is a type (which in turns checks whether the blocks expression is a type)
1 parent 6fa81cf commit 147f562

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Diff for: compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
14131413

14141414
object TypeBlockTypeTest extends TypeTest[Tree, TypeBlock]:
14151415
def unapply(x: Tree): Option[TypeBlock & x.type] = x match
1416-
case tpt: (tpd.Block & x.type) => Some(tpt)
1416+
case tpt: (tpd.Block & x.type) if x.isType => Some(tpt)
14171417
case _ => None
14181418
end TypeBlockTypeTest
14191419

Diff for: tests/pos/i21721/Macro.scala

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import quoted.*
2+
3+
object Macro:
4+
inline def impl(inline expr: Any): Any =
5+
${implImpl('expr)}
6+
7+
def implImpl(expr: Expr[Any])(using q: Quotes): Expr[Any] =
8+
import q.reflect.*
9+
expr.asTerm.asInstanceOf[Inlined].body match
10+
// this should not fail with a MatchError
11+
case TypeBlock(_, _) => '{ "TypeBlock" }
12+
case _ => '{ "Nothing" }

Diff for: tests/pos/i21721/Test.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test:
2+
// give a Block(...) to the macro
3+
Macro.impl:
4+
val a = 3
5+
a

0 commit comments

Comments
 (0)