Skip to content

Commit e22dfcc

Browse files
committed
Fix #5948: Tighten rule in hasMatchingMember
This is a partial fix only. We still have to tighten rules around capture to flag the original example as erroneous.
1 parent 4141bd2 commit e22dfcc

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
11321132
/*>|>*/ trace(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}), mbr: ${tp1.member(name).info}", subtyping) /*<|<*/ {
11331133
val rinfo2 = tp2.refinedInfo
11341134

1135-
// If the member is an abstract type, compare the member itself
1135+
// If the member is an abstract type and the prefix is a path, compare the member itself
11361136
// instead of its bounds. This case is needed situations like:
11371137
//
11381138
// class C { type T }
@@ -1148,7 +1148,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
11481148
def matchAbstractTypeMember(info1: Type) = info1 match {
11491149
case TypeBounds(lo, hi) if lo ne hi =>
11501150
tp2.refinedInfo match {
1151-
case rinfo2: TypeBounds =>
1151+
case rinfo2: TypeBounds if tp1.widenExpr.isSingleton =>
11521152
val ref1 = tp1.widenExpr.select(name)
11531153
isSubType(rinfo2.lo, ref1) && isSubType(ref1, rinfo2.hi)
11541154
case _ =>

tests/neg/i5948.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
abstract class Foo {
2+
type A
3+
var elem: A
4+
}
5+
6+
object Test {
7+
def setFirstInList[T](list: List[Foo { type A = T }]) = {
8+
list(0).elem = list(1).elem
9+
}
10+
11+
def main(args: Array[String]): Unit = {
12+
val fooInt = new Foo { type A = Int; var elem = 1 }
13+
val fooString = new Foo { type A = String; var elem = "" }
14+
15+
val list: List[Foo] = List(fooInt, fooString)
16+
setFirstInList[Foo#A](list) // error
17+
setFirstInList(list) // error
18+
println(fooInt.elem + 1)
19+
}
20+
}

tests/neg/i5948a.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
trait Bar {
2+
type A
3+
}
4+
5+
object Test {
6+
def test0: Unit = {
7+
val b1: Bar = new Bar {}
8+
val b2: Bar { type A = Bar#A } = b1 // error
9+
}
10+
def test1: Unit = {
11+
val b1: List[Bar] = List(new Bar {})
12+
val b2: List[Bar { type A = Bar#A }] = b1 // error
13+
}
14+
}

0 commit comments

Comments
 (0)