Skip to content

Commit c49d6c0

Browse files
authored
Merge pull request #11242 from dotty-staging/fix-11236
Improve variable instantiation when member is missing
2 parents 081fbc6 + 32676de commit c49d6c0

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,23 @@ object Inferencing {
9999
&& tvar.hasLowerBound =>
100100
tvar.instantiate(fromBelow = true)
101101
true
102-
case AppliedType(tycon, _) =>
102+
case AppliedType(tycon, args) =>
103+
// The argument in `args` that may potentially appear directly as result
104+
// and thereby influence the members of this type
105+
def argsInResult: List[Type] = tycon match
106+
case tycon: TypeRef =>
107+
tycon.info match
108+
case MatchAlias(_) => args
109+
case TypeBounds(_, upper: TypeLambda) =>
110+
upper.resultType match
111+
case ref: TypeParamRef if ref.binder == upper =>
112+
args.lazyZip(upper.paramRefs).collect {
113+
case (arg, pref) if pref eq ref => arg
114+
}.toList
115+
case _ => Nil
116+
case _ => Nil
103117
couldInstantiateTypeVar(tycon)
118+
|| argsInResult.exists(couldInstantiateTypeVar)
104119
case RefinedType(parent, _, _) =>
105120
couldInstantiateTypeVar(parent)
106121
case tp: AndOrType =>

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ i7868.scala
3232
i7872.scala
3333
6709.scala
3434
6687.scala
35+
i11236.scala
3536

3637
# Opaque type
3738
i5720.scala

tests/pos/i11236.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Test {
2+
val tup: Char #: Int #: String #: TupleK = ???
3+
val x: String #: TupleK = (tup.tail: Int #: String #: TupleK).tail
4+
val a = tup.tail
5+
val b = a.tail
6+
val y: String #: TupleK = tup.tail.tail
7+
val z: Unit = tup.tail.tail
8+
}
9+
10+
trait TupleK
11+
12+
object TupleK {
13+
type Tail[X <: NonEmptyTupleK] <: TupleK = X match {
14+
case _ #: xs => xs
15+
}
16+
}
17+
18+
trait NonEmptyTupleK extends TupleK {
19+
/*inline*/ def tail[This >: this.type <: NonEmptyTupleK]: TupleK.Tail[This] = ???
20+
}
21+
22+
abstract class #:[+H, +T <: TupleK] extends NonEmptyTupleK

tests/pos/i9567.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
// val x: Int => Int = identity
33
// }
44

5-
trait Foo[F[_]] {
5+
trait Foo[F[_], I[X] <: X] {
6+
type Id[X] <: X
67
def foo[G[x] >: F[x]]: G[Unit]
8+
def foo2[X >: F[String]]: Id[X]
9+
def foo3[X >: F[String]]: I[X]
710
}
811

912
trait M[A] {
@@ -12,11 +15,10 @@ trait M[A] {
1215
}
1316

1417
object Test {
15-
def bar(x: Foo[M]): Unit = {
16-
// error: value bla is not a member of G[Unit], where: G is a type variable with constraint >: M and <: [x] =>> Any
18+
def bar(x: Foo[M, [X] =>> X]): Unit = {
1719
x.foo.bla
18-
19-
// error: value bla is not a member of G[Unit], where: G is a type variable with constraint >: M and <: [x] =>> Any
2020
x.foo.baz(x => x)
21+
x.foo2.bla
22+
x.foo3.bla
2123
}
2224
}

0 commit comments

Comments
 (0)