-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix TreeMap's transformTerm wrt UnApply #7503
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
Conversation
41f1d30
to
7171f6a
Compare
@@ -157,7 +157,7 @@ trait TreeUtils | |||
} | |||
} | |||
|
|||
def transformTerm(tree: Term)(given ctx: Context): Term = { | |||
def transformTerm(tree: Term)(given ctx: Context): Term = if IsTerm.unapply(tree).isEmpty then tree else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't correct, if tree
is a Term
then IsTerm.unapply(tree)
should never be empty. Where did that tree come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for this is (at least) the UnApply
type. Technically it is <: Term
but for the purposes of Tasty reflect we do not treat it as such since it cannot appear in a term position.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed earlier the failing example that this PR fixes:
Macro:
import scala.quoted.{ given, _ }
inline def mcr(x: => Unit): Unit = ${mcrImpl('x)}
def mcrImpl(x: Expr[Unit])(given ctx: QuoteContext): Expr[Unit] =
import ctx.tasty.{ given, _ }
val tr: Term = x.unseal
object m extends TreeMap
m.transformTerm(tr).seal.cast[Unit]
Test:
@main def Test = mcr {
val (a, b) = ???
}
7171f6a
to
3e15605
Compare
@nicolasstucki the problem seems to be with this method: https://github.com/lampepfl/dotty/blob/04a68b8df2c8f0bfe2f6fc41a7722b63a6dc4098/library/src-bootstrapped/scala/tasty/reflect/TreeUtils.scala#L113
RepresentationInlined(
EmptyTree,List(
),Block(
List(
ValDef(
$1$,TypeTree[AppliedType(
TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Tuple2
),List(
TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
), TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)
)
)],Match(
Typed(
Ident(
???
),TypeTree[AnnotatedType(
TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
),ConcreteAnnotation(
New(
TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class unchecked
)]
)
)
)]
),List(
CaseDef(
Typed(
UnApply(
TypeApply(
Select(
Ident(
Tuple2
),unapply
),List(
TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)], TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)]
)
),List(
),List(
Bind(
a,Ident(
_
)
), Bind(
b,Ident(
_
)
)
)
),TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)]
),EmptyTree,Apply(
TypeApply(
Select(
Ident(
Tuple2
),apply
),List(
TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)], TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)]
)
),List(
Ident(
a
), Ident(
b
)
)
)
)
)
)
), ValDef(
a,TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)],Select(
Ident(
$1$
),_1
)
), ValDef(
b,TypeTree[TypeRef(
ThisType(
TypeRef(
NoPrefix,module class scala
)
),class Nothing
)],Select(
Ident(
$1$
),_2
)
)
),Literal(
Constant(
(
)
)
)
)
) But |
The `IsStatement` test before this commit treated `Typed(Unapply)` nodes as statements, which is not correct since they are patterns. They must pass the `IsUnapply` test and fail `IsStatement` test. However since they do not fail `IsStatement` test, the `transformTree` method of `TreeMap` incorrectly calls `transformStatement` on a `Typed(Unapply)`. This commit makes the `IsStatement` test treat the trees in question correctly.
3e15605
to
f97461f
Compare
UnApply <: Term however it cannot appear where
a term can. Hence we do not transform it from
transformTerm and guard against it getting into
transformTerm to prevent MatchErrors.