Skip to content

Commit

Permalink
Fix widen types before checking an implicit view exists
Browse files Browse the repository at this point in the history
It's not possible to convert a method, such as a polymorphic method,
such as `makeChurch`, into another type - we need to widen out the
TermRef to discover the underlying PolyType which isn't a value type.
Failing to do so will create a dummyTreeOfType, which will then be
attempted to be applied, which eventually causes an assertion crash
while building the tpd.TypeApply.

[Cherry-picked 8a2773f]
  • Loading branch information
dwijnand authored and Kordyjan committed Nov 28, 2023
1 parent 809dd78 commit 2bc32a4
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ trait Implicits:
&& !to.isError
&& !ctx.isAfterTyper
&& ctx.mode.is(Mode.ImplicitsEnabled)
&& from.isValueType
&& from.widen.isValueType
&& ( from.isValueSubType(to)
|| inferView(dummyTreeOfType(from), to)
(using ctx.fresh.addMode(Mode.ImplicitExploration).setExploreTyperState()).isSuccess
Expand Down
8 changes: 8 additions & 0 deletions tests/neg/i18650.min.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Church[B]:
type Nat = Tuple1[B]

class Test:
given makeChurch[C]: Church[C] = ??? // necessary to cause crash

def churchTest(c: Church[Int]): Unit =
val res1 = summon[c.Nat =:= Int] // error (not a compiler crash)
8 changes: 8 additions & 0 deletions tests/neg/i18650.min2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Church[B]:
type Nat = Tuple1[B]

class Test2:
given makeChurch2[C](using DummyImplicit): Church[C] = ???

def churchTest2(c: Church[Int]): Unit =
val res2 = summon[c.Nat =:= Int] // error (not a compiler crash)
26 changes: 26 additions & 0 deletions tests/neg/i18650.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
trait Lam:
type F[_]
extension [A, B](f: F[A => B]) def apply(arg: F[A]): F[B]
def lam[A, B](f: F[A] => F[B]): F[A => B]
final def id[A]: F[A => A] = lam(identity[F[A]])

object LamInterpreter extends Lam:
type F[t] = t
def lam[A, B](f: F[A] => F[B]): F[A => B] = f
extension [A, B](f: F[A => B]) def apply(arg: F[A]): F[B] = f(arg)


class Church[A](using val l: Lam):
import l.*
type Nat = F[(A => A) => (A => A)]
def zero: Nat = id
extension (n: Nat) def suc: Nat = lam(f => lam(x => f(n(f)(x))))

given [A](using l: Lam): Church[A] = Church()


@main
def churchTest =
given Lam = LamInterpreter
val c: Church[Int] = summon
summon[c.Nat =:= ((Int => Int) => (Int => Int))] // error (not a compiler crash)

0 comments on commit 2bc32a4

Please sign in to comment.