Skip to content

Commit f561301

Browse files
authored
Merge pull request #2927 from dotty-staging/fix-Ycheck-erasure
Fix #2430: Make Erasure pass Ycheck
2 parents a2a41ac + 05ffaac commit f561301

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,26 +239,44 @@ object Erasure {
239239
* Casts from and to ErasedValueType are special, see the explanation
240240
* in ExtensionMethods#transform.
241241
*/
242-
def cast(tree: Tree, pt: Type)(implicit ctx: Context): Tree = {
242+
def cast(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"cast ${tree.tpe.widen} --> $pt", show = true) {
243+
def wrap(tycon: TypeRef) =
244+
ref(u2evt(tycon.typeSymbol.asClass)).appliedTo(tree)
245+
def unwrap(tycon: TypeRef) =
246+
ref(evt2u(tycon.typeSymbol.asClass)).appliedTo(tree)
247+
248+
243249
assert(!pt.isInstanceOf[SingletonType], pt)
244250
if (pt isRef defn.UnitClass) unbox(tree, pt)
245-
else (tree.tpe, pt) match {
251+
else (tree.tpe.widen, pt) match {
246252
case (JavaArrayType(treeElem), JavaArrayType(ptElem))
247253
if treeElem.widen.isPrimitiveValueType && !ptElem.isPrimitiveValueType =>
248254
// See SI-2386 for one example of when this might be necessary.
249255
cast(ref(defn.runtimeMethodRef(nme.toObjectArray)).appliedTo(tree), pt)
250-
case (_, ErasedValueType(tycon, _)) =>
251-
ref(u2evt(tycon.symbol.asClass)).appliedTo(tree)
252-
case _ =>
253-
tree.tpe.widen match {
254-
case ErasedValueType(tycon, _) =>
255-
ref(evt2u(tycon.symbol.asClass)).appliedTo(tree)
256-
case _ =>
257-
if (pt.isPrimitiveValueType)
258-
primitiveConversion(tree, pt.classSymbol)
259-
else
260-
tree.asInstance(pt)
256+
257+
// When casting between two EVTs, we need to check which one underlies the other to determine
258+
// wheter u2evt or evt2u should be used.
259+
case (tp1 @ ErasedValueType(tycon1, underlying1), tp2 @ ErasedValueType(tycon2, underlying2)) =>
260+
if (tp1 <:< underlying2)
261+
// Cast EVT(tycon1, underlying1) to EVT(tycon2, EVT(tycon1, underlying1))
262+
wrap(tycon2)
263+
else {
264+
assert(underlying1 <:< tp2, i"Non-sensical cast between unrelated types $tp1 and $tp2")
265+
// Cast EVT(tycon1, EVT(tycon2, underlying2)) to EVT(tycon2, underlying2)
266+
unwrap(tycon1)
261267
}
268+
269+
// When only one type is an EVT then we already know that the other one is the underlying
270+
case (_, ErasedValueType(tycon2, _)) =>
271+
wrap(tycon2)
272+
case (ErasedValueType(tycon1, _), _) =>
273+
unwrap(tycon1)
274+
275+
case _ =>
276+
if (pt.isPrimitiveValueType)
277+
primitiveConversion(tree, pt.classSymbol)
278+
else
279+
tree.asInstance(pt)
262280
}
263281
}
264282

compiler/test/dotc/tests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class tests extends CompilerTest {
6868
}
6969

7070
implicit val defaultOptions: List[String] = noCheckOptions ++ {
71-
if (dotty.Properties.isRunByDrone) List("-Ycheck:tailrec,resolveSuper,mixin,getClass,restoreScopes,labelDef") // should be Ycheck:all, but #725
71+
if (dotty.Properties.isRunByDrone) List("-Ycheck:tailrec,resolveSuper,erasure,mixin,getClass,restoreScopes,labelDef") // should be Ycheck:all, but #725
7272
else List("-Ycheck:tailrec,resolveSuper,mixin,restoreScopes,labelDef,simplify")
7373
} ++ checkOptions ++ classPath
7474

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ object TestConfiguration {
5050
Array("-classpath", paths)
5151
}
5252

53-
private val yCheckOptions = Array("-Ycheck:tailrec,resolveSuper,mixin,getClass,restoreScopes,labelDef")
53+
private val yCheckOptions = Array("-Ycheck:tailrec,resolveSuper,erasure,mixin,getClass,restoreScopes,labelDef")
5454

5555
val defaultUnoptimised = noCheckOptions ++ checkOptions ++ yCheckOptions ++ classPath
5656
val defaultOptimised = defaultUnoptimised :+ "-optimise"

0 commit comments

Comments
 (0)