aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-16 16:08:26 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-16 16:09:25 +0100
commit58059264842fac39a27356d052680a09c2da7571 (patch)
tree5b3ef0642b19cfbbf7bf91ebc7ec016955fa50b7 /src/dotty/tools/dotc/typer
parent36476e46815370ca282cbb3179711125444319e9 (diff)
downloaddotty-58059264842fac39a27356d052680a09c2da7571.tar.gz
dotty-58059264842fac39a27356d052680a09c2da7571.tar.bz2
dotty-58059264842fac39a27356d052680a09c2da7571.zip
Checking for double definitions among class definitions.
Also fixes to typedReturn. Adapted tests accordingly.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala23
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala31
2 files changed, 35 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index cb22e8e88..4d418fe97 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -12,7 +12,7 @@ import util.Positions._
import util.{Stats, SimpleMap}
import Decorators._
import ErrorReporting.{errorType, InfoString}
-import collection.mutable.ListBuffer
+import collection.mutable
object Inferencing {
@@ -249,6 +249,27 @@ object Inferencing {
defn.ObjectClass
}
+ /** Check that class does not define */
+ def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = {
+ val seen = new mutable.HashMap[Name, List[Symbol]] {
+ override def default(key: Name) = Nil
+ }
+ println(i"cndd $cls")
+ for (decl <- cls.info.decls) {
+ for (other <- seen(decl.name)) {
+ println(i"conflict? $decl $other")
+ if (decl.signature matches other.signature) {
+ val ofType = if (decl.isType) "" else i": ${other.info}"
+ val explanation =
+ if (!decl.isSourceMethod) ""
+ else "\n (both definitions have the same erased type signature)"
+ ctx.error(i"$decl is already defined as $other$ofType$explanation", decl.pos)
+ }
+ }
+ seen(decl.name) = decl :: seen(decl.name)
+ }
+ }
+
def checkInstantiatable(cls: ClassSymbol, pos: Position): Unit = {
??? // to be done in later phase: check that class `cls` is legal in a new.
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 4e9d5953a..20f9aeb19 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -611,26 +611,21 @@ class Typer extends Namer with Applications with Implicits {
}
def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") {
- def enclMethInfo(cx: Context): (Tree, Type) =
- if (cx == NoContext || cx.owner.isType) {
- ctx.error("return outside method definition")
+ def enclMethInfo(cx: Context): (Tree, Type) = {
+ val owner = cx.owner
+ if (cx == NoContext || owner.isType) {
+ ctx.error("return outside method definition", tree.pos)
(EmptyTree, WildcardType)
}
- else cx.tree match {
- case ddef: DefDef =>
- val meth = cx.owner
- val from = Ident(TermRef(NoPrefix, meth.asTerm))
- val proto =
- if (meth.isConstructor)
- defn.UnitType
- else if (ddef.tpt.isEmpty)
- errorType(i"method ${meth.name} has return statement; needs result type", tree.pos)
- else
- ddef.tpt.tpe
+ else if (owner.isSourceMethod)
+ if (owner.isCompleted) {
+ val from = Ident(TermRef(NoPrefix, owner.asTerm))
+ val proto = if (owner.isConstructor) defn.UnitType else owner.info.finalResultType
(from, proto)
- case _ =>
- enclMethInfo(cx.outer)
- }
+ }
+ else (EmptyTree, errorType(i"$owner has return statement; needs result type", tree.pos))
+ else enclMethInfo(cx.outer)
+ }
val (from, proto) = enclMethInfo(ctx)
val expr1 = typedExpr(tree.expr orElse untpd.unitLiteral, proto)
cpy.Return(tree, expr1, from) withType defn.NothingType
@@ -786,9 +781,9 @@ class Typer extends Namer with Applications with Implicits {
val self1 = typed(self).asInstanceOf[ValDef]
val localDummy = ctx.newLocalDummy(cls, impl.pos)
val body1 = typedStats(body, localDummy)(inClassContext(self1.symbol))
+ checkNoDoubleDefs(cls)
val impl1 = cpy.Template(impl, constr1, parents1, self1, body1)
.withType(localDummy.termRef)
-
cpy.TypeDef(cdef, mods1, name, impl1).withType(cls.typeRef)
// todo later: check that