aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala11
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala8
-rw-r--r--src/dotty/tools/dotc/typer/ProtoTypes.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala17
6 files changed, 36 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index be0eb9230..1700a9c9c 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -378,15 +378,18 @@ class TypeApplications(val self: Type) extends AnyVal {
}
}
+ /** If `self` is a higher-kinded type, its type parameters $hk_i, otherwise Nil */
final def hkTypeParams(implicit ctx: Context): List[MemberBinding] =
if (Config.newHK)
if (isHK) typeParams else Nil
else LambdaTraitOBS.typeParams
- final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = {
- val tparams = typeParams
- assert(tparams.isEmpty || tparams.head.isInstanceOf[Symbol], self)
- tparams.asInstanceOf[List[TypeSymbol]]
+ /** If `self` is a generic class, its type parameter symbols, otherwise Nil */
+ final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = typeParams match {
+ case (_: Symbol) :: _ =>
+ assert(typeParams.forall(_.isInstanceOf[Symbol]))
+ typeParams.asInstanceOf[List[TypeSymbol]]
+ case _ => Nil
}
/** The named type parameters declared or inherited by this type.
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 14071e27c..cdbf692cd 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -17,6 +17,7 @@ import Types._
import Decorators._
import ErrorReporting._
import Trees._
+import config.Config
import Names._
import StdNames._
import ProtoTypes._
@@ -644,7 +645,7 @@ trait Applications extends Compatibility { self: Typer =>
}
def adaptTypeArg(tree: tpd.Tree, bound: Type)(implicit ctx: Context): tpd.Tree =
- tree.withType(tree.tpe.etaExpandIfHK(bound))
+ if (Config.newHK) tree else tree.withType(tree.tpe.etaExpandIfHK(bound))
/** Rewrite `new Array[T](....)` if T is an unbounded generic to calls to newGenericArray.
* It is performed during typer as creation of generic arrays needs a classTag.
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 6944197a1..cfad4e77e 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -36,11 +36,16 @@ object Checking {
/** A general checkBounds method that can be used for TypeApply nodes as
* well as for AppliedTypeTree nodes.
*/
- def checkBounds(args: List[tpd.Tree], boundss: List[TypeBounds], instantiate: (Type, List[Type]) => Type)(implicit ctx: Context) =
+ def checkBounds(args: List[tpd.Tree], boundss: List[TypeBounds], instantiate: (Type, List[Type]) => Type)(implicit ctx: Context) = {
+ (args, boundss).zipped.foreach { (arg, bound) =>
+ if (!bound.isHK && arg.tpe.isHK)
+ ctx.error(d"missing type parameter(s) for $arg", arg.pos)
+ }
for ((arg, which, bound) <- ctx.boundsViolations(args, boundss, instantiate))
ctx.error(
d"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
arg.pos)
+ }
/** Check that type arguments `args` conform to corresponding bounds in `poly`
* Note: This does not check the bounds of AppliedTypeTrees. These
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index a8f3b8918..7982f288d 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -14,6 +14,7 @@ import collection.mutable
import annotation.tailrec
import ErrorReporting._
import tpd.ListOfTreeDecorator
+import config.Config
import config.Printers._
import Annotations._
import Inferencing._
@@ -591,7 +592,7 @@ class Namer { typer: Typer =>
*/
def parentType(parent: untpd.Tree)(implicit ctx: Context): Type =
if (parent.isType) {
- typedAheadType(parent).tpe
+ typedAheadType(parent, AnyTypeConstructorProto).tpe
} else {
val (core, targs) = stripApply(parent) match {
case TypeApply(core, targs) => (core, targs)
@@ -973,7 +974,8 @@ class Namer { typer: Typer =>
ensureUpToDate(sym.typeRef, dummyInfo)
ensureUpToDate(sym.typeRef.appliedTo(tparamSyms.map(_.typeRef)), TypeBounds.empty)
- etaExpandArgs.apply(sym.info)
+ if (Config.newHK) sym.info
+ else etaExpandArgsOBS.apply(sym.info)
}
/** Eta expand all class types C appearing as arguments to a higher-kinded
@@ -982,7 +984,7 @@ class Namer { typer: Typer =>
* of arguments in F-bounds, because the recursive type was initialized with
* TypeBounds.empty.
*/
- def etaExpandArgs(implicit ctx: Context) = new TypeMap {
+ def etaExpandArgsOBS(implicit ctx: Context) = new TypeMap {
def apply(tp: Type): Type = tp match {
case tp: RefinedType =>
val args = tp.argInfos.mapconserve(this)
diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 740258821..68fd99b3f 100644
--- a/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -311,6 +311,9 @@ object ProtoTypes {
*/
@sharable object AnyFunctionProto extends UncachedGroundType with MatchAlways
+ /** A prototype for type constructors that are followed by a type application */
+ @sharable object AnyTypeConstructorProto extends UncachedGroundType with MatchAlways
+
/** Add all parameters in given polytype `pt` to the constraint's domain.
* If the constraint contains already some of these parameters in its domain,
* make a copy of the polytype and add the copy's type parameters instead.
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 225516503..33a94f5c7 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -928,7 +928,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): Tree = track("typedAppliedTypeTree") {
- val tpt1 = typed(tree.tpt)(ctx retractMode Mode.Pattern)
+ val tpt1 = typed(tree.tpt, AnyTypeConstructorProto)(ctx.retractMode(Mode.Pattern))
val tparams = tpt1.tpe.typeParams
if (tparams.isEmpty) {
ctx.error(d"${tpt1.tpe} does not take type parameters", tree.pos)
@@ -1672,6 +1672,17 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
+ def adaptType(tp: Type): Tree = {
+ val tree1 =
+ if (pt != AnyTypeConstructorProto && tp.typeParamSymbols.nonEmpty) {
+ println(i"lam abs $tp with tparams ${tp.typeParamSymbols}%, %")
+ tree.withType(tree.tpe.EtaExpand(tp.typeParamSymbols))
+ }
+ else tree
+ if ((ctx.mode is Mode.Pattern) || tree1.tpe <:< pt) tree1
+ else err.typeMismatch(tree1, pt)
+ }
+
tree match {
case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[_] => tree
case _ => tree.tpe.widen match {
@@ -1705,9 +1716,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
(_, _) => tree // error will be reported in typedTypeApply
}
case _ =>
- if (ctx.mode is Mode.Type)
- if ((ctx.mode is Mode.Pattern) || tree.tpe <:< pt) tree
- else err.typeMismatch(tree, pt)
+ if (ctx.mode is Mode.Type) adaptType(tree.tpe)
else adaptNoArgs(wtp)
}
}