diff options
Diffstat (limited to 'src/dotty/tools')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 17 |
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) } } |