diff options
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/config/Config.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 45 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 19 |
4 files changed, 30 insertions, 46 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala index 0fad2e105..a50945108 100644 --- a/src/dotty/tools/dotc/config/Config.scala +++ b/src/dotty/tools/dotc/config/Config.scala @@ -72,10 +72,9 @@ object Config { /** If this flag is set, take the fast path when comparing same-named type-aliases and types */ final val fastPathForRefinedSubtype = true - /** If this flag is set, $apply projections are checked that they apply to a - * higher-kinded type. + /** If this flag is set, higher-kinded applications are checked for validity */ - final val checkProjections = false + final val checkHKApplications = false /** The recursion depth for showing a summarized string */ final val summarizeDepth = 2 diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index ef241cb66..314233709 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -338,13 +338,12 @@ class TypeApplications(val self: Type) extends AnyVal { * * TODO: Handle parameterized lower bounds */ - def LambdaAbstract(tparams: List[Symbol])(implicit ctx: Context): Type = { + def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = { def expand(tp: Type) = TypeLambda( - tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.variance))( + tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.paramVariance))( tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds), tl => tl.lifted(tparams, tp)) - assert(!isHK, self) self match { case self: TypeAlias => self.derivedTypeAlias(expand(self.alias)) @@ -489,6 +488,8 @@ class TypeApplications(val self: Type) extends AnyVal { } else dealiased.resType match { case AppliedType(tycon, args1) if tycon.safeDealias ne tycon => + // In this case we should always dealias since we cannot handle + // higher-kinded applications to wildcard arguments. dealiased .derivedTypeLambda(resType = tycon.safeDealias.appliedTo(args1)) .appliedTo(args) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 1bfe9cbd1..fa402f9fc 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -517,7 +517,7 @@ object Types { def goApply(tp: HKApply) = tp.tycon match { case tl: TypeLambda => go(tl.resType).mapInfo(info => - tl.derivedTypeLambda(tl.paramNames, tl.paramBounds, info).appliedTo(tp.args)) + tl.derivedLambdaAbstraction(tl.paramNames, tl.paramBounds, info).appliedTo(tp.args)) case _ => go(tp.superType) } @@ -879,12 +879,6 @@ object Types { case _ => this } - /** If this is a TypeAlias type, its alias, otherwise this type itself */ - final def followTypeAlias(implicit ctx: Context): Type = this match { - case TypeAlias(alias) => alias - case _ => this - } - /** If this is a (possibly aliased, annotated, and/or parameterized) reference to * a class, the class type ref, otherwise NoType. * @param refinementOK If `true` we also skip non-parameter refinements. @@ -1923,13 +1917,9 @@ object Types { } object TypeRef { - def checkProjection(prefix: Type, name: TypeName)(implicit ctx: Context) = () - /** Create type ref with given prefix and name */ - def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef = { - if (Config.checkProjections) checkProjection(prefix, name) + def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef = ctx.uniqueNamedTypes.enterIfNew(prefix, name).asInstanceOf[TypeRef] - } /** Create type ref to given symbol */ def apply(prefix: Type, sym: TypeSymbol)(implicit ctx: Context): TypeRef = @@ -1938,10 +1928,8 @@ object Types { /** Create a non-member type ref (which cannot be reloaded using `member`), * with given prefix, name, and symbol. */ - def withFixedSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef = { - if (Config.checkProjections) checkProjection(prefix, name) + def withFixedSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef = unique(new TypeRefWithFixedSym(prefix, name, sym)) - } /** Create a type ref referring to given symbol with given name. * This is very similar to TypeRef(Type, Symbol), @@ -2057,9 +2045,7 @@ object Types { private def badInst = throw new AssertionError(s"bad instantiation: $this") - def checkInst(implicit ctx: Context): this.type = { - this - } + def checkInst(implicit ctx: Context): this.type = this // debug hook def derivedRefinedType(parent: Type, refinedName: Name, refinedInfo: Type)(implicit ctx: Context): Type = if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) this @@ -2139,7 +2125,7 @@ object Types { override def computeHash = doHash(parent) override def toString = s"RecType($parent | $hashCode)" - private def checkInst(implicit ctx: Context): this.type = this + private def checkInst(implicit ctx: Context): this.type = this // debug hook } object RecType { @@ -2550,8 +2536,8 @@ object Types { case _ => false } - def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context) = - derivedGenericType(paramNames, paramBounds, resType) + def derivedPolyType(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): PolyType = + derivedGenericType(paramNames, paramBounds, resType).asInstanceOf[PolyType] def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): PolyType = PolyType(paramNames)( @@ -2591,7 +2577,7 @@ object Types { lazy val typeParams: List[LambdaParam] = paramNames.indices.toList.map(new LambdaParam(this, _)) - def derivedTypeLambda(paramNames: List[TypeName] = paramNames, paramBounds: List[TypeBounds] = paramBounds, resType: Type)(implicit ctx: Context): Type = + def derivedLambdaAbstraction(paramNames: List[TypeName], paramBounds: List[TypeBounds], resType: Type)(implicit ctx: Context): Type = resType match { case resType @ TypeAlias(alias) => resType.derivedTypeAlias(duplicate(paramNames, paramBounds, alias)) @@ -2600,9 +2586,12 @@ object Types { if (lo.isRef(defn.NothingClass)) lo else duplicate(paramNames, paramBounds, lo), duplicate(paramNames, paramBounds, hi)) case _ => - derivedGenericType(paramNames, paramBounds, resType) + derivedTypeLambda(paramNames, paramBounds, resType) } + def derivedTypeLambda(paramNames: List[TypeName] = paramNames, paramBounds: List[TypeBounds] = paramBounds, resType: Type)(implicit ctx: Context): TypeLambda = + derivedGenericType(paramNames, paramBounds, resType).asInstanceOf[TypeLambda] + def duplicate(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, resType: Type)(implicit ctx: Context): TypeLambda = TypeLambda(paramNames, variances)( x => paramBounds mapConserve (_.subst(this, x).bounds), @@ -2664,6 +2653,7 @@ object Types { cachedSuper } + /* (Not needed yet) */ def lowerBound(implicit ctx: Context) = tycon.stripTypeVar match { case tycon: TypeRef => tycon.info match { @@ -2676,13 +2666,6 @@ object Types { NoType } -/* - def lowerBound(implicit ctx: Context): Type = tycon.stripTypeVar match { - case tp: TypeRef => - val lb = tp.info.bounds.lo.typeParams.length == args.lengt - case _ => defn.NothingType - } -*/ def typeParams(implicit ctx: Context): List[TypeParamInfo] = { val tparams = tycon.typeParams if (tparams.isEmpty) TypeLambda.any(args.length).typeParams else tparams @@ -2705,7 +2688,7 @@ object Types { case _ => assert(false, s"illegal type constructor in $this") } - check(tycon) + if (Config.checkHKApplications) check(tycon) this } } diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 9e55216c1..b1cceea88 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -83,15 +83,16 @@ object Checking { case AppliedTypeTree(tycon, args) => // If `args` is a list of named arguments, return corresponding type parameters, // otherwise return type parameters unchanged - def matchNamed(tparams: List[TypeSymbol], args: List[Tree]): List[Symbol] = - if (hasNamedArg(args)) - for (NamedArg(name, _) <- args) yield tycon.tpe.member(name).symbol - else - tparams - val tparams = matchNamed(tycon.tpe.typeSymbol.typeParams, args) - val bounds = tparams.map(tparam => - tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds) - checkBounds(args, bounds, _.substDealias(tparams, _)) + val tparams = tycon.tpe.typeParams + def argNamed(tparam: TypeParamInfo) = args.find { + case NamedArg(name, _) => name == tparam.paramName + case _ => false + }.getOrElse(TypeTree(tparam.paramRef)) + val orderedArgs = if (hasNamedArg(args)) tparams.map(argNamed) else args + val bounds = tparams.map(_.paramBoundsAsSeenFrom(tycon.tpe)) + def instantiate(bound: Type, args: List[Type]) = + bound.LambdaAbstract(tparams).appliedTo(args) + checkBounds(orderedArgs, bounds, instantiate) def checkValidIfHKApply(implicit ctx: Context): Unit = checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos) |