Description
Compiler version
3.3.2-RC1-bin-20230630-c629090-NIGHTLY and before
Minimized code
The following snippet contains multiple cases obtained by uncommenting one of the commented lines at a time.
object Test {
def foo(xs: Int*)(ys: xs.type) = ys
def bar(xs: Int*)(ys: xs.type*) = ys
val ints = Seq(1)
// val f1 = foo()()
// val f2 = foo(1)(1)
// val f3 = foo(1)(1, 1)
// val f4 = foo(1, 1)(1, 1)
// val f5 = foo(1, 2)(1, 2)
// val f6 = foo(1, 2)(Seq(1, 2): _*)
// val f7 = foo(ints: _*)(ints)
// val f8 = foo(ints: _*)(ints: _*)
// val b1 = bar()()
// val b2 = bar(1)(1)
// val b3 = bar(1)(1, 1)
// val b4 = bar(1, 1)(1, 1)
// val b5 = bar(1, 2)(1, 2)
// val b6 = bar(1, 2)(Seq(1, 2): _*)
// val b7 = bar(ints: _*)(ints)
// val b8 = bar(ints: _*)(ints: _*)
}
Output
case | scala 3.nightly | scala 2.13.11 |
---|---|---|
f1 | crash | error |
f2 | crash | success |
f3 | crash | error |
f4 | crash | error |
f5 | crash | error |
f6 | error | error |
f7 | crash | error |
f8 | error | error |
b1 | success | crash |
b2 | error | success |
b3 | error | success |
b4 | error | crash |
b5 | error | crash |
b6 | error | crash |
b7 | error | error |
b8 | error | error |
Stack trace for a crash in 3.3.2-RC1-bin-20230630-c629090-NIGHTLY (taking f2
as example):
Exception in thread "main" java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:662)
at scala.collection.immutable.Nil$.head(List.scala:661)
at dotty.tools.dotc.typer.Applications$Application.matchArgs(Applications.scala:638)
at dotty.tools.dotc.typer.Applications$Application.init(Applications.scala:492)
at dotty.tools.dotc.typer.Applications$TypedApply.<init>(Applications.scala:777)
at dotty.tools.dotc.typer.Applications$ApplyToUntyped.<init>(Applications.scala:894)
at dotty.tools.dotc.typer.Applications.ApplyTo(Applications.scala:1124)
at dotty.tools.dotc.typer.Applications.ApplyTo$(Applications.scala:352)
at dotty.tools.dotc.typer.Typer.ApplyTo(Typer.scala:116)
at dotty.tools.dotc.typer.Applications.simpleApply$1(Applications.scala:967)
at dotty.tools.dotc.typer.Applications.realApply$1$$anonfun$2(Applications.scala:1050)
at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:3392)
at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:1061)
at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:1099)
at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:352)
at dotty.tools.dotc.typer.Typer.typedApply(Typer.scala:116)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3109)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3176)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3252)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3256)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3368)
at dotty.tools.dotc.typer.Namer.typedAheadExpr$$anonfun$1(Namer.scala:1656)
at dotty.tools.dotc.typer.Namer.typedAhead(Namer.scala:1646)
at dotty.tools.dotc.typer.Namer.typedAheadExpr(Namer.scala:1656)
at dotty.tools.dotc.typer.Namer.typedAheadRhs$1$$anonfun$1(Namer.scala:1915)
at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:243)
at dotty.tools.dotc.typer.Namer.typedAheadRhs$1(Namer.scala:1915)
at dotty.tools.dotc.typer.Namer.rhsType$1(Namer.scala:1923)
at dotty.tools.dotc.typer.Namer.cookedRhsType$1(Namer.scala:1941)
at dotty.tools.dotc.typer.Namer.lhsType$1(Namer.scala:1942)
at dotty.tools.dotc.typer.Namer.inferredResultType(Namer.scala:1953)
at dotty.tools.dotc.typer.Namer.inferredType$1(Namer.scala:1694)
at dotty.tools.dotc.typer.Namer.valOrDefDefSig(Namer.scala:1700)
at dotty.tools.dotc.typer.Namer$Completer.typeSig(Namer.scala:787)
at dotty.tools.dotc.typer.Namer$Completer.completeInCreationContext(Namer.scala:934)
at dotty.tools.dotc.typer.Namer$Completer.complete(Namer.scala:814)
at dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:174)
at dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:187)
at dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:189)
at dotty.tools.dotc.core.SymDenotations$SymDenotation.ensureCompleted(SymDenotations.scala:393)
at dotty.tools.dotc.typer.Typer.retrieveSym(Typer.scala:3050)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3075)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3175)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3252)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3256)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3278)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3324)
at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2742)
at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3097)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3101)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3175)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3252)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3256)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3278)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3324)
at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2873)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3143)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3176)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3252)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3256)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3368)
at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$1(TyperPhase.scala:44)
at dotty.tools.dotc.typer.TyperPhase.typeCheck$$anonfun$adapted$1(TyperPhase.scala:50)
at scala.Function0.apply$mcV$sp(Function0.scala:42)
at dotty.tools.dotc.core.Phases$Phase.monitor(Phases.scala:440)
at dotty.tools.dotc.typer.TyperPhase.typeCheck(TyperPhase.scala:50)
at dotty.tools.dotc.typer.TyperPhase.runOn$$anonfun$3(TyperPhase.scala:84)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.immutable.List.foreach(List.scala:333)
at dotty.tools.dotc.typer.TyperPhase.runOn(TyperPhase.scala:84)
at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:246)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
at dotty.tools.dotc.Run.runPhases$1(Run.scala:262)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:270)
at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:279)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
at dotty.tools.dotc.Run.compileUnits(Run.scala:279)
at dotty.tools.dotc.Run.compileSources(Run.scala:194)
at dotty.tools.dotc.Run.compile(Run.scala:179)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:37)
at dotty.tools.dotc.Driver.process(Driver.scala:197)
at dotty.tools.dotc.Driver.process(Driver.scala:165)
at dotty.tools.dotc.Driver.process(Driver.scala:177)
at dotty.tools.dotc.Driver.main(Driver.scala:207)
at dotty.tools.dotc.Main.main(Main.scala)
Expectation
For sure the compiler should not crash but I'm not really sure which of the cases (if any) should compile successfully.
The semantics of singleton vararg types in general are quite unclear. E.g. they cannot be used as declared return types. Successfully compiling b3
in scala 2.13 seems to suggest that xs.type
is a subtype of Int
rather than Int*
or Seq[Int]
.
@odersky should we disallow singleton vararg types at all to prevent such strange corner cases? Alternatively which of the cases should compile?