aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-10-07 12:42:38 +0200
committerMartin Odersky <odersky@gmail.com>2015-10-07 13:41:58 +0200
commit6cca64fa0aa37942812d1c870b99f309dab67352 (patch)
tree5d2e357e72c22ca64a8fad770a8002fc4ff15bcf
parenta8c8bdad57941071b85caa54bc57b84d8ca7d526 (diff)
downloaddotty-6cca64fa0aa37942812d1c870b99f309dab67352.tar.gz
dotty-6cca64fa0aa37942812d1c870b99f309dab67352.tar.bz2
dotty-6cca64fa0aa37942812d1c870b99f309dab67352.zip
Check that some types are not higher-kinded.
Invalidates #813. Review by @darkdimius.
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala13
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala6
-rw-r--r--test/dotc/tests.scala2
-rw-r--r--tests/neg/typers.scala8
-rw-r--r--tests/pos/polyalias.scala2
5 files changed, 25 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 9092523db..8f4a8b72b 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -16,6 +16,7 @@ import Trees._
import ProtoTypes._
import Constants._
import Scopes._
+import ErrorReporting.errorTree
import annotation.unchecked
import util.Positions._
import util.{Stats, SimpleMap}
@@ -347,6 +348,17 @@ trait Checking {
ctx.error(i"""$called is already implemented by super${caller.superClass},
|its constructor cannot be called again""".stripMargin, call.pos)
}
+
+ /** Check that `tpt` does not define a higher-kinded type */
+ def checkSimpleKinded(tpt: Tree)(implicit ctx: Context): Tree =
+ if (tpt.tpe.isHK && !ctx.compilationUnit.isJava) {
+ // be more lenient with missing type params in Java,
+ // needed to make pos/java-interop/t1196 work.
+ val alias = tpt.tpe.dealias
+ if (alias.isHK) errorTree(tpt, d"missing type parameter for ${tpt.tpe}")
+ else tpt.withType(alias)
+ }
+ else tpt
}
trait NoChecking extends Checking {
@@ -360,4 +372,5 @@ trait NoChecking extends Checking {
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = ()
override def checkParentCall(call: Tree, caller: ClassSymbol)(implicit ctx: Context) = ()
+ override def checkSimpleKinded(tpt: Tree)(implicit ctx: Context): Tree = tpt
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index b28ac9bc5..d94505e29 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -369,7 +369,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (untpd.isWildcardStarArg(tree))
TypeTree(defn.SeqClass.typeRef.appliedTo(pt :: Nil))
else
- typedType(tree.tpt)
+ checkSimpleKinded(typedType(tree.tpt))
val expr1 =
if (isWildcard) tree.expr withType tpt1.tpe
else typed(tree.expr, tpt1.tpe)
@@ -917,7 +917,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = track("typedValDef") {
val ValDef(name, tpt, _) = vdef
completeAnnotations(vdef, sym)
- val tpt1 = typedType(tpt)
+ val tpt1 = checkSimpleKinded(typedType(tpt))
val rhs1 = vdef.rhs match {
case rhs @ Ident(nme.WILDCARD) => rhs withType tpt1.tpe
case rhs => typedExpr(rhs, tpt1.tpe)
@@ -931,7 +931,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef])
val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef])
if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1)
- val tpt1 = typedType(tpt)
+ val tpt1 = checkSimpleKinded(typedType(tpt))
val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)
assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
//todo: make sure dependent method types do not depend on implicits or by-name params
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 2b5b86be1..b22da9b5d 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -104,7 +104,7 @@ class tests extends CompilerTest {
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
@Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2)
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)
- @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 10)(allowDoubleBindings)
+ @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 13)(allowDoubleBindings)
@Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2)
@Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2)
@Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3)
diff --git a/tests/neg/typers.scala b/tests/neg/typers.scala
index 9fcc63e38..8bd39a557 100644
--- a/tests/neg/typers.scala
+++ b/tests/neg/typers.scala
@@ -29,8 +29,14 @@ object typers {
def g[T](x: T): T = x // OK!
}
+ type L[X] = scala.collection.immutable.List[X]
+ type M[X, Y] <: scala.collection.immutable.Map[X, Y]
-
+ object hk {
+ def f(x: L) // error: missing type parameter
+ : M = // error: missing type parameter
+ ??? : M // error: missing type parameter
+ }
object returns {
diff --git a/tests/pos/polyalias.scala b/tests/pos/polyalias.scala
index 07bb241f0..6ce0e3230 100644
--- a/tests/pos/polyalias.scala
+++ b/tests/pos/polyalias.scala
@@ -3,7 +3,7 @@ object Test {
type S = scala.Predef.Set
- val z: S = ???
+ val z: S[_] = ???
type Pair[T] = (T, T)