@@ -337,6 +337,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
337337 case tp1 @ OrType (tp11, tp12) =>
338338 def joinOK = tp2.dealias match {
339339 case tp2 : AppliedType if ! tp2.tycon.typeSymbol.isClass =>
340+ // If we apply the default algorithm for `A[X] | B[Y] <: C[Z]` where `C` is a
341+ // type parameter, we will instantiate `C` to `A` and then fail when comparing
342+ // with `B[Y]`. To do the right thing, we need to instantiate `C` to the
343+ // common superclass of `A` and `B`.
340344 isSubType(tp1.join, tp2)
341345 case _ =>
342346 false
@@ -366,7 +370,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
366370 if (cls2.isClass) {
367371 val base = tp1.baseType(cls2)
368372 if (base.exists) {
369- if (cls2.is(JavaDefined )) return base.typeSymbol == cls2
373+ if (cls2.is(JavaDefined ))
374+ // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol
375+ return base.typeSymbol == cls2
370376 if (base ne tp1) return isSubType(base, tp2)
371377 }
372378 if (cls2 == defn.SingletonClass && tp1.isStable) return true
@@ -689,14 +695,14 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
689695 *
690696 * Returns `true` iff `d >= 0` and `tycon2` can be instantiated to
691697 *
692- * [tparams1_d, ... tparams1_n-1] -> tycon1a [args_1, ..., args_d-1, tparams_d, ... tparams_n-1]
698+ * [tparams1_d, ... tparams1_n-1] -> tycon1 [args_1, ..., args_d-1, tparams_d, ... tparams_n-1]
693699 *
694700 * such that the resulting type application is a supertype of `tp1`.
695701 */
696702 def appOK (tp1base : Type ) = tp1base match {
697703 case tp1base : AppliedType =>
698704 var tycon1 = tp1base.tycon
699- var args1 = tp1base.args
705+ val args1 = tp1base.args
700706 val tparams1all = tycon1.typeParams
701707 val lengthDiff = tparams1all.length - tparams.length
702708 lengthDiff >= 0 && {
@@ -1244,14 +1250,22 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12441250 final def lub (tps : List [Type ]): Type =
12451251 ((defn.NothingType : Type ) /: tps)(lub(_,_, canConstrain = false ))
12461252
1253+ /** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using
1254+ * the following strategies:
1255+ *
1256+ * - if arguments are the same, that argument.
1257+ * - if corresponding parameter variance is co/contra-variant, the lub/glb.
1258+ * - otherwise a TypeBounds containing both arguments
1259+ */
12471260 def lubArgs (args1 : List [Type ], args2 : List [Type ], tparams : List [TypeParamInfo ], canConstrain : Boolean = false ): List [Type ] =
12481261 tparams match {
12491262 case tparam :: tparamsRest =>
12501263 val arg1 :: args1Rest = args1
12511264 val arg2 :: args2Rest = args2
12521265 val v = tparam.paramVariance
12531266 val lubArg =
1254- if (v > 0 ) lub(arg1.hiBound, arg2.hiBound, canConstrain)
1267+ if (isSameTypeWhenFrozen(arg1, arg2)) arg1
1268+ else if (v > 0 ) lub(arg1.hiBound, arg2.hiBound, canConstrain)
12551269 else if (v < 0 ) glb(arg1.loBound, arg2.loBound)
12561270 else TypeBounds (glb(arg1.loBound, arg2.loBound),
12571271 lub(arg1.hiBound, arg2.hiBound, canConstrain))
@@ -1263,8 +1277,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12631277 /** Try to produce joint arguments for a glb `A[T_1, ..., T_n] & A[T_1', ..., T_n']` using
12641278 * the following strategies:
12651279 *
1266- * - if corresponding parameter variance is co/contra-variant, the glb/lub.
12671280 * - if arguments are the same, that argument.
1281+ * - if corresponding parameter variance is co/contra-variant, the glb/lub.
12681282 * - if at least one of the arguments if a TypeBounds, the union of
12691283 * the bounds.
12701284 * - if homogenizeArgs is set, and arguments can be unified by instantiating
@@ -1435,7 +1449,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
14351449 private def distributeAnd (tp1 : Type , tp2 : Type ): Type = tp1 match {
14361450 case tp1 @ AppliedType (tycon1, args1) =>
14371451 tp2 match {
1438- case AppliedType (tycon2, args2) if tycon1.typeSymbol == tycon2.typeSymbol =>
1452+ case AppliedType (tycon2, args2)
1453+ if tycon1.typeSymbol == tycon2.typeSymbol && tycon1 =:= tycon2 =>
14391454 val jointArgs = glbArgs(args1, args2, tycon1.typeParams)
14401455 if (jointArgs.forall(_.exists)) (tycon1 & tycon2).appliedTo(jointArgs)
14411456 else NoType
0 commit comments