Skip to content

Commit 24841e1

Browse files
committed
fix #4030: avoid adding duplicate binders
1 parent 02725c6 commit 24841e1

File tree

2 files changed

+37
-11
lines changed

2 files changed

+37
-11
lines changed

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -908,17 +908,21 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
908908
}
909909

910910
/** Add a `Bind` node for each `bound` symbol in a type application `unapp` */
911-
def addBinders(unapp: Tree, bound: List[Symbol]) = unapp match {
912-
case TypeApply(fn, args) =>
913-
def addBinder(arg: Tree) = arg.tpe.stripTypeVar match {
914-
case ref: TypeRef if bound.contains(ref.symbol) =>
915-
tpd.Bind(ref.symbol, Ident(ref))
916-
case _ =>
917-
arg
918-
}
919-
tpd.cpy.TypeApply(unapp)(fn, args.mapConserve(addBinder))
920-
case _ =>
921-
unapp
911+
def addBinders(unapp: Tree, bound: List[Symbol]) = {
912+
var remain = bound.toSet
913+
unapp match {
914+
case TypeApply(fn, args) =>
915+
def addBinder(arg: Tree) = arg.tpe.stripTypeVar match {
916+
case ref: TypeRef if remain.contains(ref.symbol) =>
917+
remain -= ref.symbol
918+
tpd.Bind(ref.symbol, Ident(ref))
919+
case _ =>
920+
arg
921+
}
922+
tpd.cpy.TypeApply(unapp)(fn, args.mapConserve(addBinder))
923+
case _ =>
924+
unapp
925+
}
922926
}
923927

924928
def fromScala2x = unapplyFn.symbol.exists && (unapplyFn.symbol.owner is Scala2x)

tests/pos/i4030.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
sealed trait Root[T]
2+
case object C1 extends Root[Int]
3+
case object C2 extends Root[String]
4+
//case class C3[X, Y]() extends Root[X|Y|(X => X)]
5+
case class C3[X, Y]() extends Root[(X => X)|(Y => Y)|(X => Y)]
6+
case class C4[X, Y]() extends Root[(X => X)|(Y => Y)|(X => Y)]
7+
8+
object TestGADT {
9+
//type Foo // abstract
10+
11+
def f[A <: Seq[_], B, Foo >: A => B](v: Root[Foo], u: Root[Foo]) = (v, u) match {
12+
//case C1 =>
13+
//case C2 =>
14+
case (C3(), C3()) =>
15+
}
16+
//f(C3[Int, Int]())
17+
//implicitly[Int <:< Int|(Int => Int)]
18+
//implicitly[(Int => Int) <:< String|(Int => Int)]//($conforms[Int => Int])
19+
//f[Int, Int, Int|(Int => Int)](C3[Int, Int]())
20+
//f(C3[Int, Int]())
21+
f(C3[Seq[_], Long](), C4[Seq[_], Long]())
22+
}

0 commit comments

Comments
 (0)