Skip to content

Commit

Permalink
Fix upper bound constraints, that are higher-kinded (#16744)
Browse files Browse the repository at this point in the history
When recording an upper bound, when it's a some higher-kinded type
variable applied to some type arguments, TypeComparer was re-applying
the type arguments to the type parameter (the type variable's origin).
Meaning that the instantiation of the type variable won't reflect in the
upper bound.

See the error message: `F$1[Int]` correctly appears as the lower bound,
but `F$1[Int]` isn't the upper bound, `F[Int]` is, which is the original
type parameter, in `Foo.Bar.apply[F](..)`.

-- [E007] Type Mismatch Error: i12478.scala:8:13
-------------------------------
    8 |      Foo.Bar(fu1)
      |      ^^^^^^^^^^^^
      |Found:    Foo.Bar[F$1]
      |Required: Foo[T1]
      |
      |where:    F$1 is a type in method id1 with bounds <: [_] =>> Any
| T1 is a type in method id1 with bounds >: F$1[Int] and <: F[Int]
      |
      | longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: i12478.scala:18:13
------------------------------
    18 |      Foo.Bar(fu3)
       |      ^^^^^^^^^^^^
       |Found:    Foo.Bar[F$2]
       |Required: Foo[T3]
       |
       |where:    F$2 is a type in method id3 with bounds <: [_] =>> Any
| T3 is a type in method id3 with bounds >: F$2[Int] and <: F[Int]
       |
       | longer explanation available when compiling with `-explain`
  • Loading branch information
odersky authored Jan 23, 2023
2 parents 23febb8 + c73c47a commit 3800c91
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1338,8 +1338,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
}
} || tryLiftedToThis2

case _: TypeVar =>
recur(tp1, tp2.superType)
case tv: TypeVar =>
if tv.isInstantiated then
recur(tp1, tp2.superType)
else
compareAppliedType2(tp2, tv.origin, args2)
case tycon2: AnnotatedType if !tycon2.isRefining =>
recur(tp1, tp2.superType)
case tycon2: AppliedType =>
Expand Down
19 changes: 19 additions & 0 deletions tests/pos/i12478.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
sealed trait Foo[T]

object Foo:
case class Bar[F[_]](fu: List[F[Unit]]) extends Foo[F[Unit]]

class Test:
def id1[T1](foo1: Foo[T1]): Foo[T1] = foo1 match
case Foo.Bar(fu) =>
Foo.Bar(fu)

def id2[T2](foo2: Foo[T2]): Foo[T2] = foo2 match
case bar2 @ (_: Foo.Bar[f]) =>
val fu2 = bar2.fu
Foo.Bar(fu2)

def id3[T3](foo3: Foo[T3]): Foo[T3] = foo3 match
case bar3 @ Foo.Bar(_) =>
val fu3 = bar3.fu
Foo.Bar(fu3)

0 comments on commit 3800c91

Please sign in to comment.