-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Avoid erasure/preErasure issues around Any in transformIsInstanceOf #21647
Conversation
The testType Any is erased to Object, but the expr type Int isn't erased to Integer, so then it fails as Int !<: Object. We avoid the problem by feeding in AnyVal, leading to a (possibly elided) non-null test only.
if testType.isAny && expr.tpe.isPrimitiveValueType then | ||
defn.AnyValType |
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.
Isn't that going to trigger with the same issue with any other type that erases to Object
? Like ... AnyVal
itself?
There's supposed to already be logic in transformIsInstanceOf
to avoid a type test when expr.tpe <:< testType
:
scala3/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
Lines 259 to 261 in 9961e70
if (expr.tpe <:< testType) && inMatch then | |
if expr.tpe.isNotNull then constant(expr, Literal(Constant(true))) | |
else expr.testNotNull |
The problem is that it tests on erased types, instead of the original types. Addressing that at the root should be more robust, shouldn't it?
class Test(): | ||
def m1(xs: List[Boolean]) = for (x: Any) <- xs yield x | ||
def m2(xs: List[Boolean]) = for (x: AnyVal) <- xs yield x | ||
def m3(xs: List[Boolean]) = for (x: Matchable) <- xs yield x |
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.
A few more suggestions for tests:
def m1(xs: List[AnyVal]) = for (x: Any) <- xs yield x
def m1(xs: List[AnyVal]) = for (x: Matchable) <- xs yield x
def m1(xs: List[Matchable]) = for (x: Any) <- xs yield x
def m1(xs: List[Any]) = for (x: Any) <- xs yield x
The testType Any is erased to Object, but the expr type Int isn't erased
to Integer, so then it fails as Int
!<:
Object. We avoid the problem byfeeding in AnyVal, leading to a (possibly elided) non-null test only.
Fixes #21544