diff options
-rw-r--r-- | src/dotty/tools/dotc/config/Config.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 17 |
2 files changed, 21 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala index c247699da..906d17380 100644 --- a/src/dotty/tools/dotc/config/Config.scala +++ b/src/dotty/tools/dotc/config/Config.scala @@ -27,7 +27,7 @@ object Config { /** Show subtype traces for all deep subtype recursions */ final val traceDeepSubTypeRecursions = false - final val verboseExplainSubtype = true + final val verboseExplainSubtype = false /** When set, use new signature-based matching. * Advantantage of doing so: It's supposed to be faster @@ -43,4 +43,9 @@ object Config { * for large constraints. */ final val trackConstrDeps = true + + /** Check that variances of lambda arguments match the + * variance of the underlying lambda class. + */ + final val checkLambdaVariance = false }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index dda5134c1..24586f412 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1420,6 +1420,19 @@ object Types { override def underlying(implicit ctx: Context) = parent + private def checkInst(implicit ctx: Context): this.type = { + if (Config.checkLambdaVariance) + refinedInfo match { + case refinedInfo: TypeBounds if refinedInfo.variance != 0 && refinedName.isLambdaArgName => + val cls = parent.LambdaClass(forcing = false) + if (cls.exists) + assert(refinedInfo.variance == cls.typeParams.apply(refinedName.lambdaArgIndex).variance, + s"variance mismatch for $this, $cls, ${cls.typeParams}, ${cls.typeParams.apply(refinedName.lambdaArgIndex).variance}, ${refinedInfo.variance}") + case _ => + } + this + } + /** Derived refined type, with a twist: A refinement with a higher-kinded type param placeholder * is transformed to a refinement of the original type parameter if that one exists. */ @@ -1476,10 +1489,10 @@ object Types { else make(RefinedType(parent, names.head, infoFns.head), names.tail, infoFns.tail) def apply(parent: Type, name: Name, infoFn: RefinedType => Type)(implicit ctx: Context): RefinedType = - ctx.base.uniqueRefinedTypes.enterIfNew(new CachedRefinedType(parent, name, infoFn)) + ctx.base.uniqueRefinedTypes.enterIfNew(new CachedRefinedType(parent, name, infoFn)).checkInst def apply(parent: Type, name: Name, info: Type)(implicit ctx: Context): RefinedType = { - ctx.base.uniqueRefinedTypes.enterIfNew(parent, name, info) + ctx.base.uniqueRefinedTypes.enterIfNew(parent, name, info).checkInst } } |