aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-10-21 15:08:35 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-31 14:45:00 +0100
commitd4c26fc6072e69d3f58685e6bfec4609eb9af13c (patch)
treefdfa4d0dc4279b36a881f1af132298d9792c4375
parent7967aa97607964f78c92911038412192cfea3778 (diff)
downloaddotty-d4c26fc6072e69d3f58685e6bfec4609eb9af13c.tar.gz
dotty-d4c26fc6072e69d3f58685e6bfec4609eb9af13c.tar.bz2
dotty-d4c26fc6072e69d3f58685e6bfec4609eb9af13c.zip
Roll normalizedTree into main PostTyper transform
Since we now transform all type trees, no need to have a separate traversal for checking.
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala43
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala87
2 files changed, 50 insertions, 80 deletions
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index b72785dce..6b9fc084e 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -76,13 +76,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
// TODO fill in
}
- /** Check bounds of AppliedTypeTrees.
- */
- private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = {
- if (tree.isType) Checking.typeCheck(tree)
- tree
- }
-
/** If the type of `tree` is a TermRefWithSignature with an underdefined
* signature, narrow the type by re-computing the signature (which should
* be fully-defined by now).
@@ -171,14 +164,19 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
}
override def transform(tree: Tree)(implicit ctx: Context): Tree =
- try normalizeTree(tree) match {
+ try tree match {
case tree: Ident if !tree.isType =>
tree.tpe match {
case tpe: ThisType => This(tpe.cls).withPos(tree.pos)
case _ => paramFwd.adaptRef(fixSignature(tree))
}
- case tree: Select if !tree.isType =>
- transformSelect(paramFwd.adaptRef(fixSignature(tree)), Nil)
+ case tree @ Select(qual, name) =>
+ if (name.isTypeName) {
+ Checking.checkRealizable(qual.tpe, qual.pos.focus)
+ super.transform(tree)
+ }
+ else
+ transformSelect(paramFwd.adaptRef(fixSignature(tree)), Nil)
case tree: Super =>
if (ctx.owner.enclosingMethod.isInlineMethod)
ctx.error(em"super not allowed in inline ${ctx.owner}", tree.pos)
@@ -241,7 +239,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
tree
}
else {
- Checking.typeChecker.traverse(tree.rhs)
+ //Checking.typeChecker.traverse(tree.rhs)
cpy.TypeDef(tree)(rhs = TypeTree(tree.symbol.info))
}
super.transform(tree1)
@@ -253,25 +251,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
super.transform(tree)
case tree @ Annotated(annotated, annot) =>
cpy.Annotated(tree)(transform(annotated), transformAnnot(annot))
- case AppliedTypeTree(tycon, args) =>
- // If `args` is a list of named arguments, return corresponding type parameters,
- // otherwise return type parameters unchanged
- 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)
- Checking.checkBounds(orderedArgs, bounds, instantiate)
-
- def checkValidIfHKApply(implicit ctx: Context): Unit =
- Checking.checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
- checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
+ case tree: AppliedTypeTree =>
+ Checking.checkAppliedType(tree)
+ super.transform(tree)
+ case SingletonTypeTree(ref) =>
+ Checking.checkRealizable(ref.tpe, ref.pos.focus)
super.transform(tree)
-
case tree: TypeTree =>
tree.withType(
tree.tpe match {
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index b6c9e0047..753475d84 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -55,60 +55,45 @@ object Checking {
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
- /** If type is a higher-kinded application with wildcard arguments,
- * check that it or one of its supertypes can be reduced to a normal application.
- * Unreducible applications correspond to general existentials, and we
- * cannot handle those.
+ /** Check applied type trees for well-formedness. This means
+ * - all arguments are within their corresponding bounds
+ * - if type is a higher-kinded application with wildcard arguments,
+ * check that it or one of its supertypes can be reduced to a normal application.
+ * Unreducible applications correspond to general existentials, and we
+ * cannot handle those.
*/
- def checkWildcardHKApply(tp: Type, pos: Position)(implicit ctx: Context): Unit = tp match {
- case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) =>
- tycon match {
- case tycon: PolyType =>
- ctx.errorOrMigrationWarning(
- ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
- pos)
- case _ =>
- checkWildcardHKApply(tp.superType, pos)
- }
- case _ =>
- }
-
- /** Traverse type tree, performing the following checks:
- * 1. All arguments of applied type trees must conform to their bounds.
- * 2. Prefixes of type selections and singleton types must be realizable.
- */
- val typeChecker = new TreeTraverser {
- def traverse(tree: Tree)(implicit ctx: Context) = {
- typeCheck(tree)
- traverseChildren(tree)
- }
+ def checkAppliedType(tree: AppliedTypeTree)(implicit ctx: Context) = {
+ val AppliedTypeTree(tycon, args) = tree
+ // If `args` is a list of named arguments, return corresponding type parameters,
+ // otherwise return type parameters unchanged
+ 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 checkWildcardHKApply(tp: Type, pos: Position): Unit = tp match {
+ case tp @ HKApply(tycon, args) if args.exists(_.isInstanceOf[TypeBounds]) =>
+ tycon match {
+ case tycon: PolyType =>
+ ctx.errorOrMigrationWarning(
+ ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
+ pos)
+ case _ =>
+ checkWildcardHKApply(tp.superType, pos)
+ }
+ case _ =>
+ }
+ def checkValidIfHKApply(implicit ctx: Context): Unit =
+ checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
+ checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
}
- def typeCheck(tree: Tree)(implicit ctx: Context) = tree match {
- case AppliedTypeTree(tycon, args) =>
- // If `args` is a list of named arguments, return corresponding type parameters,
- // otherwise return type parameters unchanged
- 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)
- checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
- case Select(qual, name) if name.isTypeName =>
- checkRealizable(qual.tpe, qual.pos.focus)
- case SingletonTypeTree(ref) =>
- checkRealizable(ref.tpe, ref.pos.focus)
- case _ =>
- }
-
/** Check that `tp` refers to a nonAbstract class
* and that the instance conforms to the self type of the created class.
*/