aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala7
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala19
-rw-r--r--src/dotty/tools/dotc/core/Types.scala1
-rw-r--r--tests/pos/nestedLambdas.scala12
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]
+
}