Skip to content

Check that some types are not higher-kinded. #821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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 {
Expand All @@ -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
}
6 changes: 3 additions & 3 deletions src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion tests/neg/typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down
2 changes: 1 addition & 1 deletion tests/pos/polyalias.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ object Test {

type S = scala.Predef.Set

val z: S = ???
val z: S[_] = ???


type Pair[T] = (T, T)
Expand Down