aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-02 18:04:05 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-02 18:04:05 +0100
commit14528228331bdb588278002208c46447e164870c (patch)
tree62e8ccdc7475c597af2f86628415ec29b90b4a2d /src/dotty
parentbddeaecb8f69032c5117e926ef67afc0deedd0dd (diff)
downloaddotty-14528228331bdb588278002208c46447e164870c.tar.gz
dotty-14528228331bdb588278002208c46447e164870c.tar.bz2
dotty-14528228331bdb588278002208c46447e164870c.zip
Fixes to type applications and unapply.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala2
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala73
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala1
5 files changed, 45 insertions, 35 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index ae3b8008a..43c96b587 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -236,7 +236,7 @@ object Trees {
*/
def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
// temporary solution to catch unreported errors early
- if (tpe == ErrorType) assert(ctx.reporter.hasErrors)
+ if (tpe == ErrorType) assert(ctx.errorsReported || !ctx.typerState.isCommittable)
withTypeUnchecked(tpe)
}
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index f8ec3c57b..49e038a1e 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -316,7 +316,7 @@ class Definitions(implicit ctx: Context) {
lazy val RootImports = Set[Symbol](PredefModule, ScalaPackageVal, JavaLangPackageVal)
def isTupleType(tp: Type) = {
- val arity = tp.typeArgs.length
+ val arity = tp.dealias.typeArgs.length
arity <= MaxTupleArity && (tp isRef TupleClass(arity))
}
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index 960fddff7..72b9247c5 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -164,6 +164,8 @@ trait Reporting { this: Context =>
throw ex
}
}
+
+ def errorsReported: Boolean = outersIterator exists (_.reporter.hasErrors)
}
/**
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index d483163e7..cc1e481b2 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -89,7 +89,13 @@ trait Applications extends Compatibility { self: Typer =>
protected def liftFun(): Unit = ()
/** A flag signalling that the typechecking the application was so far succesful */
- protected var ok = true
+ private[this] var _ok = true
+
+ def ok = _ok
+ def ok_=(x: Boolean) = {
+ assert(x || ctx.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG
+ _ok = x
+ }
/** The function's type after widening and instantiating polytypes
* with polyparams in constraint set
@@ -509,7 +515,13 @@ trait Applications extends Compatibility { self: Typer =>
val ownType = typedFn.tpe.widen match {
case pt: PolyType =>
checkBounds(typedArgs, pt, tree.pos)
- pt.resultType.substParams(pt, typedArgs.tpes)
+ val argTypes = typedArgs.tpes
+ if (argTypes.length == pt.paramNames.length)
+ pt.resultType.substParams(pt, typedArgs.tpes)
+ else {
+ ctx.error(i"wrong number of type parameters for ${typedFn.tpe}; expected: ${pt.paramNames.length}", tree.pos)
+ ErrorType
+ }
case _ =>
ctx.error(s"${err.exprStr(typedFn)} does not take type parameters", tree.pos)
ErrorType
@@ -525,7 +537,7 @@ trait Applications extends Compatibility { self: Typer =>
val unapply = {
val dummyArg = untpd.TypedSplice(dummyTreeOfType(WildcardType))
- val unappProto = FunProto(dummyArg :: Nil, pt, this)
+ val unappProto = FunProto(dummyArg :: Nil, WildcardType, this)
tryEither {
implicit ctx => typedExpr(untpd.Select(qual, nme.unapply), unappProto)
} {
@@ -541,38 +553,33 @@ trait Applications extends Compatibility { self: Typer =>
def fromScala2x = unapply.symbol.exists && (unapply.symbol.owner is Scala2x)
def unapplyArgs(unapplyResult: Type)(implicit ctx: Context): List[Type] = {
- def recur(tp: Type): List[Type] = {
- def extractorMemberType(name: Name) = {
- val ref = tp member name
- if (ref.isOverloaded)
- errorType(s"Overloaded reference to ${ref.show} is not allowed in extractor", tree.pos)
- else if (ref.info.isInstanceOf[PolyType])
- errorType(s"Reference to polymorphic ${ref.show}: ${ref.info.show} is not allowed in extractor", tree.pos)
- else
- ref.info
- }
-
- def productSelectors: List[Type] = {
- val sels = for (n <- Iterator.from(0)) yield extractorMemberType(("_" + n).toTermName)
- sels.takeWhile(_.exists).toList
- }
- def seqSelector = defn.RepeatedParamType.appliedTo(tp.elemType :: Nil)
- def optionSelectors(tp: Type): List[Type] =
- if (defn.isTupleType(tp)) tp.typeArgs else tp :: Nil
- if (fromScala2x && (tp isRef defn.OptionClass) && tp.typeArgs.length == 1)
- optionSelectors(tp.typeArgs.head)
- else if (tp derivesFrom defn.ProductClass) productSelectors
- else if (tp derivesFrom defn.SeqClass) seqSelector :: Nil
- else if (tp isRef defn.BooleanClass) Nil
- else if (extractorMemberType(nme.isDefined).exists &&
- extractorMemberType(nme.get).exists) recur(extractorMemberType(nme.get))
- else {
- ctx.error(s"${unapplyResult.show} is not a valid result type of an unapply method of an extractor", tree.pos)
- Nil
- }
+ def extractorMemberType(tp: Type, name: Name) = {
+ val ref = tp member name
+ if (ref.isOverloaded)
+ errorType(s"Overloaded reference to ${ref.show} is not allowed in extractor", tree.pos)
+ else if (ref.info.isInstanceOf[PolyType])
+ errorType(s"Reference to polymorphic ${ref.show}: ${ref.info.show} is not allowed in extractor", tree.pos)
+ else
+ ref.info.widenExpr.dealias
}
- recur(unapplyResult)
+ def productSelectors(tp: Type): List[Type] = {
+ val sels = for (n <- Iterator.from(1)) yield extractorMemberType(tp, ("_" + n).toTermName)
+ sels.takeWhile(_.exists).toList
+ }
+ def seqSelector = defn.RepeatedParamType.appliedTo(unapplyResult.elemType :: Nil)
+ def getSelectors(tp: Type): List[Type] =
+ if (tp derivesFrom defn.ProductClass) productSelectors(tp) else tp :: Nil
+ def getTp = extractorMemberType(unapplyResult, nme.get)
+
+ if ((extractorMemberType(unapplyResult, nme.isDefined) isRef defn.BooleanClass) &&
+ getTp.exists) getSelectors(getTp)
+ else if (unapplyResult derivesFrom defn.SeqClass) seqSelector :: Nil
+ else if (unapplyResult isRef defn.BooleanClass) Nil
+ else {
+ ctx.error(s"${unapplyResult.show} is not a valid result type of an unapply method of an extractor", tree.pos)
+ Nil
+ }
}
unapply.tpe.widen match {
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index c39007a9e..6f5739396 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1113,6 +1113,7 @@ class Typer extends Namer with Applications with Implicits {
case wtp =>
pt match {
case pt: FunProto => adaptToArgs(wtp, pt)
+ case pt: PolyProto => tree // error will be reported in typedTypeApply
case _ =>
if (ctx.mode is Mode.Type)
if (tree.tpe <:< pt) tree