Skip to content

Commit ac14b5d

Browse files
committed
Force cast, to avoid lubbing problems
1 parent 1c16873 commit ac14b5d

File tree

3 files changed

+10
-2
lines changed

3 files changed

+10
-2
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ class ArrayApply extends MiniPhase {
4040
case StripAscription(Apply(wrapArrayMeth, List(StripAscription(rest: JavaSeqLiteral)))) :: Nil
4141
if defn.WrapArrayMethods().contains(wrapArrayMeth.symbol) &&
4242
rest.elems.lengthIs < transformListApplyLimit =>
43-
rest.elems.foldRight(ref(defn.NilModule)): (elem, acc) =>
43+
val consed = rest.elems.foldRight(ref(defn.NilModule)): (elem, acc) =>
4444
New(defn.ConsType, List(elem.ensureConforms(defn.ObjectType), acc))
45+
consed.cast(tree.tpe)
4546

4647
case _ =>
4748
tree

compiler/test/dotty/tools/backend/jvm/ArrayApplyOptTest.scala

+2
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ class ArrayApplyOptTest extends DottyBytecodeTest {
213213
val meth2 = getMethod(clsNode, "meth2")
214214

215215
val instructions1 = instructionsFromMethod(meth1) match
216+
case instr :+ TypeOp(CHECKCAST, _) :+ TypeOp(CHECKCAST, _) :+ (ret @ Op(ARETURN)) =>
217+
instr :+ ret
216218
case instr :+ TypeOp(CHECKCAST, _) :+ (ret @ Op(ARETURN)) =>
217219
// List.apply[?A] doesn't, strictly, return List[?A],
218220
// because it cascades to its definition on IterableFactory

tests/run/list-apply-eval.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object Test:
66
counter += 1
77
counter.toString
88

9-
def main(args: Array[String]): Unit =
9+
def main(args: Array[String]): Unit =
1010
//List.apply is subject to an optimisation in cleanup
1111
//ensure that the arguments are evaluated in the currect order
1212
// Rewritten to:
@@ -26,3 +26,8 @@ object Test:
2626
// test for the cast instruction described in checkApplyAvoidsIntermediateArray
2727
def lub(b: Boolean): List[(String, String)] =
2828
if b then List(("foo", "bar")) else Nil
29+
30+
// from minimising CI failure in oslib
31+
// again, the lub of :: and Nil is Product, which breaks ++ (which requires IterableOnce)
32+
def lub2(b: Boolean): Unit =
33+
Seq(1) ++ (if (b) Seq(2) else Nil)

0 commit comments

Comments
 (0)