Skip to content

Commit bbd0c5f

Browse files
authored
Merge pull request #8130 from dotty-staging/fix-#8067
Fix #8067: Don't constrain with types of wrong kinds
2 parents f833baa + 8624c61 commit bbd0c5f

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,13 +524,22 @@ trait ConstraintHandling[AbstractContext] {
524524
pruneLambdaParams(bound)
525525
}
526526

527+
def kindCompatible(tp1: Type, tp2: Type): Boolean =
528+
val tparams1 = tp1.typeParams
529+
val tparams2 = tp2.typeParams
530+
tparams1.corresponds(tparams2)((p1, p2) => kindCompatible(p1.paramInfo, p2.paramInfo))
531+
&& (tparams1.isEmpty || kindCompatible(tp1.hkResult, tp2.hkResult))
532+
|| tp1.hasAnyKind
533+
|| tp2.hasAnyKind
534+
527535
try bound match {
528536
case bound: TypeParamRef if constraint contains bound =>
529537
addParamBound(bound)
530538
case _ =>
531539
val pbound = prune(bound)
532-
pbound.exists && (
533-
if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound))
540+
pbound.exists
541+
&& kindCompatible(param, pbound)
542+
&& (if fromBelow then addLowerBound(param, pbound) else addUpperBound(param, pbound))
534543
}
535544
finally addConstraintInvocations -= 1
536545
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ class TypeApplications(val self: Type) extends AnyVal {
250250
/** Convert a type constructor `TC` which has type parameters `X1, ..., Xn`
251251
* to `[X1, ..., Xn] -> TC[X1, ..., Xn]`.
252252
*/
253-
def EtaExpand(tparams: List[TypeSymbol])(implicit ctx: Context): Type =
254-
HKTypeLambda.fromParams(tparams, self.appliedTo(tparams.map(_.typeRef)))
253+
def EtaExpand(tparams: List[TypeParamInfo])(implicit ctx: Context): Type =
254+
HKTypeLambda.fromParams(tparams, self.appliedTo(tparams.map(_.paramRef)))
255255
//.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
256256

257257
/** If self is not lambda-bound, eta expand it. */
@@ -361,7 +361,7 @@ class TypeApplications(val self: Type) extends AnyVal {
361361
}
362362

363363
/** Turns non-bounds types to type bounds.
364-
* A (possible lambda abstracted) match type is turned into an abstract type.
364+
* A (possible lambda abstracted) match type is turned into a match alias.
365365
* Every other type is turned into a type alias
366366
*/
367367
final def toBounds(implicit ctx: Context): TypeBounds = self match {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -602,10 +602,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
602602
case _ =>
603603
val tparams1 = tp1.typeParams
604604
if (tparams1.nonEmpty)
605-
return recur(
606-
HKTypeLambda.fromParams(tparams1, tp1.appliedTo(tparams1.map(_.paramRef))),
607-
tp2) || fourthTry
608-
else tp2 match {
605+
return recur(tp1.EtaExpand(tparams1), tp2) || fourthTry
606+
tp2 match {
609607
case EtaExpansion(tycon2) if tycon2.symbol.isClass =>
610608
return recur(tp1, tycon2)
611609
case _ =>

tests/pos/i8067.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
object Test {
2+
3+
trait Tc[F[_]]
4+
type OfString[G[_]] = G[String]
5+
6+
def foo[A[_]](fs: A[String])(implicit f: Tc[A]): A[String] = ???
7+
def bar[B[_]](fs: OfString[B]): B[String] = foo(fs)(new Tc[B] {})
8+
9+
}

0 commit comments

Comments
 (0)