Skip to content

Commit 917bc6a

Browse files
committed
[WIP] Take expected type into account when typing a sequence argument
1 parent b0e7e26 commit 917bc6a

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

compiler/src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,11 @@ class TypeApplications(val self: Type) extends AnyVal {
392392
* or, if isJava is true, Array type, else the type itself.
393393
*/
394394
def underlyingIfRepeated(isJava: Boolean)(implicit ctx: Context): Type =
395-
if (self.isRepeatedParam) {
395+
if (self eq WildcardType) {
396+
val seqClass = if (isJava) defn.ArrayClass else defn.SeqClass
397+
seqClass.typeRef.appliedTo(WildcardType)
398+
}
399+
else if (self.isRepeatedParam) {
396400
val seqClass = if (isJava) defn.ArrayClass else defn.SeqClass
397401
// If `isJava` is set, then we want to turn `RepeatedParam[T]` into `Array[? <: T]`,
398402
// since arrays aren't covariant until after erasure. See `tests/pos/i5140`.

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -728,17 +728,13 @@ class Typer extends Namer
728728
def typedWildcardStarArgExpr = {
729729
val ptArg =
730730
if (ctx.mode.is(Mode.QuotedPattern)) pt.underlyingIfRepeated(isJava = false)
731-
else WildcardType
731+
else pt.underlyingIfRepeated(isJava = false) | pt.underlyingIfRepeated(isJava = true)
732732
val tpdExpr = typedExpr(tree.expr, ptArg)
733733
tpdExpr.tpe.widenDealias match {
734734
case defn.ArrayOf(_) =>
735-
val starType = defn.ArrayType.appliedTo(WildcardType)
736-
val exprAdapted = adapt(tpdExpr, starType)
737-
arrayToRepeated(exprAdapted)
735+
arrayToRepeated(tpdExpr)
738736
case _ =>
739-
val starType = defn.SeqType.appliedTo(defn.AnyType)
740-
val exprAdapted = adapt(tpdExpr, starType)
741-
seqToRepeated(exprAdapted)
737+
seqToRepeated(tpdExpr)
742738
}
743739
}
744740
cases(

tests/pos/sequence-argument.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import scala.reflect.ClassTag
2+
import scala.language.implicitConversions
3+
4+
class A
5+
class B
6+
7+
object Test {
8+
def doubleSeq[T](x: T): Seq[T] = Seq(x, x)
9+
def doubleArray[T: ClassTag](x: T): Array[T] = Array(x, x)
10+
11+
def box(x: Integer*): Unit = {}
12+
def widen(x: Long*): Unit = {}
13+
def conv(x: B*): Unit = {}
14+
15+
box(doubleSeq(1): _*)
16+
box(doubleArray(1): _*)
17+
18+
widen(doubleSeq(1): _*)
19+
widen(doubleArray(1): _*)
20+
21+
implicit def aToB(x: A): B = new B
22+
val a: A = new A
23+
conv(doubleSeq(a): _*)
24+
conv(doubleArray(a): _*)
25+
}

0 commit comments

Comments
 (0)