Skip to content

Commit 8e6a37d

Browse files
felhertgodzik
authored andcommitted
Fix scala#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) [Cherry-picked 147f562]
1 parent 504574d commit 8e6a37d

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
13901390

13911391
object TypeBlockTypeTest extends TypeTest[Tree, TypeBlock]:
13921392
def unapply(x: Tree): Option[TypeBlock & x.type] = x match
1393-
case tpt: (tpd.Block & x.type) => Some(tpt)
1393+
case tpt: (tpd.Block & x.type) if x.isType => Some(tpt)
13941394
case _ => None
13951395
end TypeBlockTypeTest
13961396

tests/pos/i21721/Macro.scala

Lines changed: 12 additions & 0 deletions
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" }

tests/pos/i21721/Test.scala

Lines changed: 5 additions & 0 deletions
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)