Skip to content

NoSuchElementException when passing implicit dependently typed function to method #3692

Closed
@Jasper-M

Description

@Jasper-M
class C { type T }

object Main {
  def main(args: Array[String]): Unit = {
    val choose: implicit (c: C) => Set[Int] = Set.empty
    def applyF(f: (c: C) => Set[Int]) = f(new C{type T=Int})
    applyF(choose)
  }
}

Crashes with:

Exception in thread "main" java.util.NoSuchElementException
	at scala.collection.LinearSeqOptimized.last(LinearSeqOptimized.scala:146)
	at scala.collection.LinearSeqOptimized.last$(LinearSeqOptimized.scala:145)
	at scala.collection.immutable.List.last(List.scala:86)
	at dotty.tools.dotc.typer.ProtoTypes$.$anonfun$normalize$1(ProtoTypes.scala:473)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.ProtoTypes$.normalize(ProtoTypes.scala:450)
	at dotty.tools.dotc.typer.ErrorReporting$Errors.typeMismatch(ErrorReporting.scala:108)
	at dotty.tools.dotc.typer.Typer.recover$1(Typer.scala:2336)
	at dotty.tools.dotc.typer.Typer.adaptToSubType$1(Typer.scala:2347)
	at dotty.tools.dotc.typer.Typer.adaptNoArgsOther$1(Typer.scala:2240)
	at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:2285)
	at dotty.tools.dotc.typer.Typer.adaptInterpolated(Typer.scala:2408)
	at dotty.tools.dotc.typer.Typer.$anonfun$adapt$3(Typer.scala:1934)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.$anonfun$adapt$1(Typer.scala:1927)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:1927)
	at dotty.tools.dotc.typer.ProtoTypes$FunProto.typedArg(ProtoTypes.scala:244)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:639)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.typedArg(Applications.scala:637)
	at dotty.tools.dotc.typer.Applications$Application.addTyped$1(Applications.scala:412)
	at dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:451)
	at dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:233)
	at dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:543)
	at dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:638)
	at dotty.tools.dotc.typer.Applications.simpleApply$1(Applications.scala:694)
	at dotty.tools.dotc.typer.Applications.$anonfun$typedApply$7(Applications.scala:719)
	at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:1830)
	at dotty.tools.dotc.typer.Applications.$anonfun$typedApply$1(Applications.scala:720)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:664)
	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:764)
	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:662)
	at dotty.tools.dotc.typer.Typer.typedApply(Typer.scala:69)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:1698)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1748)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:1822)
	at dotty.tools.dotc.typer.Typer.$anonfun$typedBlock$1(Typer.scala:634)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:626)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:1705)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1748)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:1822)
	at dotty.tools.dotc.typer.Typer.$anonfun$typedDefDef$1(Typer.scala:1378)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:1360)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:1686)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1747)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:1787)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:1810)
	at dotty.tools.dotc.typer.Typer.$anonfun$typedClassDef$1(Typer.scala:1471)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1401)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:1689)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1747)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:1787)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:1810)
	at dotty.tools.dotc.typer.Typer.$anonfun$typedClassDef$1(Typer.scala:1471)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1401)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:1689)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1747)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:1787)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:1810)
	at dotty.tools.dotc.typer.Typer.$anonfun$typedPackageDef$1(Typer.scala:1584)
	at dotty.tools.dotc.util.Stats$.track(Stats.scala:35)
	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:1571)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:1729)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1748)
	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1765)
	at dotty.tools.dotc.reporting.trace$.op1$2(trace.scala:25)
	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:26)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1761)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:1822)
	at dotty.tools.dotc.typer.FrontEnd.$anonfun$typeCheck$1(FrontEnd.scala:66)
	at dotty.tools.dotc.typer.FrontEnd.monitor(FrontEnd.scala:34)
	at dotty.tools.dotc.typer.FrontEnd.typeCheck(FrontEnd.scala:64)
	at dotty.tools.repl.REPLFrontEnd.runOn(ReplFrontEnd.scala:25)
	at dotty.tools.dotc.Run.$anonfun$compileUnits$3(Run.scala:125)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.util.Stats$.trackTime(Stats.scala:47)
	at dotty.tools.dotc.Run.$anonfun$compileUnits$2(Run.scala:123)
	at dotty.tools.dotc.Run.$anonfun$compileUnits$2$adapted(Run.scala:121)
	at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:32)
	at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:29)
	at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:191)
	at dotty.tools.dotc.Run.runPhases$1(Run.scala:121)
	at dotty.tools.dotc.Run.$anonfun$compileUnits$1(Run.scala:141)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:88)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:107)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:99)
	at dotty.tools.repl.ReplCompiler.runCompilationUnit(ReplCompiler.scala:188)
	at dotty.tools.repl.ReplCompiler.compile(ReplCompiler.scala:197)
	at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:223)
	at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:196)
	at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:149)
	at dotty.tools.repl.Main$.main(Main.scala:6)
	at dotty.tools.repl.Main.main(Main.scala)

I tried to minimize as much as possible. Replace Int with c.T and the crash remains the same. Giving f an implicit function type doesn't make a difference.
If you replace (c: C) with C the crash goes away.

I would also like to add that I think there's an inconsistency lurking behind this issue. Judging from the stack trace it appears the compiler wants to issue an error message for this code, however the following code compiles without error:

val choose: implicit (c: C) => Set[Int] = implicit c => Set.empty
def applyF(f: C => Set[Int]) = f(new C{type T=Int})
applyF(choose)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions