You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
objectTest:// give a Block(...) to the macroMacro.impl:vala=3
a
Macro.scala
importquoted.*objectMacro:inlinedefimpl(inlineexpr: Any):Any=${implImpl('expr)}
defimplImpl(expr: Expr[Any])(usingq: Quotes):Expr[Any] =importq.reflect.*
expr.asTerm.asInstanceOf[Inlined].body match// this should not fail with a MatchError// but it does because `TypeBlock(_, _)` matches the block// of the `expr`, but of course `val a = ...` is not a `TypeDef`,// which the `unapply` of `TypeBlock` assumes.caseTypeBlock(_, _) =>'{ "TypeBlock" }
case _ =>'{ "Nothing" }
Output
[error] --Error:/home/felher/tmp/macrotest/src/main/scala/Main.scala:3:4-------------
[error] 2|Macro.impl:
[error] 3|vala=3
[error] |^
[error] |Exception occurred while executing macro expansion.
[error] |scala.MatchError:ValDef(a,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module classscala)),classInt)],Literal(Constant(3))) (of classdotty.tools.dotc.ast.Trees$ValDef)
[error] | at scala.quoted.runtime.impl.QuotesImpl.scala$quoted$runtime$impl$QuotesImpl$reflect$TypeBlockMethods$$$_$aliases$$anonfun$1(QuotesImpl.scala:1431)
[error] | at scala.collection.immutable.List.map(List.scala:247)
[error] | at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeBlockMethods$.aliases(QuotesImpl.scala:1431)
[error] | at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeBlock$.unapply(QuotesImpl.scala:1426)
[error] | at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeBlock$.unapply(QuotesImpl.scala:1425)
[error] | at Macro$.implImpl(Impl.scala:10)
[error] |
[error] 4| a
[error] |-----------------------------------------------------------------------------
[error] |Inline stack trace
[error] |---------------------------------------
[error] |This location contains code that was inlined from Impl.scala:5
[error] 5|${implImpl('expr)}
[error] |^^^^^^^^^^^^^^^^^^
[error] -----------------------------------------------------------------------------
[error] one error found
Expectation
There should be no match error here. It should just compile fine.
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)
`TypeBlock`s are represented as normal `Blocks` in the Quotes API's
implementation. 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 of the block, trying to turn it into a
`TypeDef` by using a match with the pattern
```scala
case alias: TypeDef => alias
```
This seems fine since `TypeBlock`s are supposed to be just a list of
`TypeDefs` followed by a type as the last expression. Since the
`TypeTest` matches any `Block` and not only `Blocks` that are
`TypeBlocks`, the statements can be anything, not just `TypeDef`s, which
lets the whole `case TypeBlock(_, _)` pattern die 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 `Block`s expression
is a type)
Closes#21721
Compiler version
3.5.1 (and way before, as far as I can see)
Minimized code
Test.scala
Macro.scala
Output
Expectation
There should be no match error here. It should just compile fine.
PR
PR attempt for a fix here: #21722
The text was updated successfully, but these errors were encountered: