From c90d779a53755075b8a1cb06cb5540b2ff52cc74 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 22 Aug 2021 18:56:06 +0100 Subject: [PATCH] Avoid crash by handling by-names under Typed --- .../dotc/transform/TransformByNameApply.scala | 3 +- tests/pos/i13349.scala | 31 +++++++++++++++++++ tests/pos/i13349min.scala | 3 ++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i13349.scala create mode 100644 tests/pos/i13349min.scala diff --git a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala index dab1d8f25ca2..af0998293904 100644 --- a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala +++ b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala @@ -45,7 +45,8 @@ abstract class TransformByNameApply extends MiniPhase { thisPhase: DenotTransfor if (argType.isBottomType) argType = formal.widenExpr def wrap(arg: Tree) = ref(defn.cbnArg).appliedToType(argType).appliedTo(arg).withSpan(arg.span) - arg match { + def unTyped(t: Tree): Tree = t match { case Typed(expr, _) => unTyped(expr) case _ => t } + unTyped(arg) match { case Apply(Select(qual, nme.apply), Nil) if qual.tpe.derivesFrom(defn.Function0) && (isPureExpr(qual) || qual.symbol.isAllOf(Inline | Param)) => wrap(qual) diff --git a/tests/pos/i13349.scala b/tests/pos/i13349.scala new file mode 100644 index 000000000000..e4048424db24 --- /dev/null +++ b/tests/pos/i13349.scala @@ -0,0 +1,31 @@ +sealed trait Stream[+A]{ + import Stream.*; + + def foldRight[B](z: => B)(f: (A, => B) => B): B = + this match { + case Cons(h,t) => f(h(), t().foldRight(z)(f)) + case _ => z + } + + def append[B >: A](other : => Stream[B]) : Stream[B] = + foldRight(other : Stream[B])((elem, stream) => cons(elem, stream)) + +} + +case object Empty extends Stream[Nothing] +case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A] + +object Stream { + + def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = { + lazy val head = hd + lazy val tail = tl + Cons(() => head, () => tail) + } + + def empty[A]: Stream[A] = Empty + + def apply[A](as: A*): Stream[A] = + if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*)) + +} diff --git a/tests/pos/i13349min.scala b/tests/pos/i13349min.scala new file mode 100644 index 000000000000..da434744b638 --- /dev/null +++ b/tests/pos/i13349min.scala @@ -0,0 +1,3 @@ +class Foo: + def foo(x: => Foo) = bar(x: Foo) + def bar(x: => Foo) = x