diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-16 16:08:26 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-16 16:09:25 +0100 |
commit | 58059264842fac39a27356d052680a09c2da7571 (patch) | |
tree | 5b3ef0642b19cfbbf7bf91ebc7ec016955fa50b7 /src/dotty/tools/dotc | |
parent | 36476e46815370ca282cbb3179711125444319e9 (diff) | |
download | dotty-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')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 31 |
4 files changed, 43 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index c0b805eeb..f21075f11 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -359,7 +359,13 @@ object Denotations { final def signature(implicit ctx: Context): Signature = { if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation else info match { - case info: SignedType => info.signature + case info: SignedType => + try info.signature + catch { // !!! DEBUG + case ex: MatchError => + println(s"cannot take signature of ${info.show}") + throw ex + } case _ => Signature.NotAMethod } } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 22d84c4e1..a617f86d2 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1434,6 +1434,7 @@ object Types { extends CachedGroundType with BindingType with TermType with SignedType { thisMethodType => override val resultType = resultTypeExp(this) + assert(resultType != NoType, this) def isJava = false def isImplicit = false 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 |