diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 1 | ||||
-rw-r--r-- | tests/pos/nestedLambdas.scala | 12 |
4 files changed, 29 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index cb11d3fdc..af362f4da 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -223,12 +223,12 @@ class TypeApplications(val self: Type) extends AnyVal { self.parent.typeParams.filterNot(_.paramName == self.refinedName) case self: RecType => self.parent.typeParams - case _: HKApply | _: SingletonType => + case _: SingletonType => Nil case self: WildcardType => self.optBounds.typeParams case self: TypeProxy => - self.underlying.typeParams + self.superType.typeParams case _ => Nil } @@ -312,14 +312,13 @@ class TypeApplications(val self: Type) extends AnyVal { case self: TypeRef => self.info.isHK case self: RefinedType => false case self: TypeLambda => true - case self: HKApply => false case self: SingletonType => false case self: TypeVar => // Using `origin` instead of `underlying`, as is done for typeParams, // avoids having to set ephemeral in some cases. self.origin.isHK case self: WildcardType => self.optBounds.isHK - case self: TypeProxy => self.underlying.isHK + case self: TypeProxy => self.superType.isHK case _ => false } diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index e984970b4..18eb424bc 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -665,6 +665,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { } } + /** Fall back to comparing either with `fourthTry` or against the lower + * approximation of the rhs. + * @param tyconLo The type constructor's lower approximation. + */ + def fallback(tyconLo: Type) = + either(fourthTry(tp1, tp2), isSubType(tp1, tyconLo.applyIfParameterized(args2))) + /** Let `tycon2bounds` be the bounds of the RHS type constructor `tycon2`. * Let `app2 = tp2` where the type constructor of `tp2` is replaced by * `tycon2bounds.lo`. @@ -674,13 +681,13 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { * tp1 <:< tp2 using fourthTry (this might instantiate params in tp1) * tp1 <:< app2 using isSubType (this might instantiate params in tp2) */ - def compareLower(tycon2bounds: TypeBounds, tyconIsTypeRef: Boolean): Boolean = { - def app2 = tycon2bounds.lo.applyIfParameterized(args2) + def compareLower(tycon2bounds: TypeBounds, tyconIsTypeRef: Boolean): Boolean = if (tycon2bounds.lo eq tycon2bounds.hi) - isSubType(tp1, if (tyconIsTypeRef) tp2.superType else app2) + isSubType(tp1, + if (tyconIsTypeRef) tp2.superType + else tycon2bounds.lo.applyIfParameterized(args2)) else - either(fourthTry(tp1, tp2), isSubType(tp1, app2)) - } + fallback(tycon2bounds.lo) tycon2 match { case param2: PolyParam => @@ -693,6 +700,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { compareLower(tycon2.info.bounds, tyconIsTypeRef = true) case _: TypeVar | _: AnnotatedType => isSubType(tp1, tp2.superType) + case tycon2: HKApply => + fallback(tycon2.lowerBound) case _ => false } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 11da27265..bbb23d32f 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2653,7 +2653,6 @@ object Types { cachedSuper } - /* (Not needed yet) */ def lowerBound(implicit ctx: Context) = tycon.stripTypeVar match { case tycon: TypeRef => tycon.info match { diff --git a/tests/pos/nestedLambdas.scala b/tests/pos/nestedLambdas.scala index 0e186d193..58be1ae2f 100644 --- a/tests/pos/nestedLambdas.scala +++ b/tests/pos/nestedLambdas.scala @@ -6,4 +6,16 @@ class Test { type B[X] = (X, X) + val x: T[Int][Boolean] = ??? + + val y: A[Int][Boolean] = x + + def f[X <: T[Int]] = ??? + + f[A[Int]] + + def g[X <: T] = ??? + + g[A] + } |