aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Namer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-09-08 10:37:49 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-09-14 13:36:14 +0200
commit8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c (patch)
tree4ccee051facbd2a5e6554dca681fdadc2def4a93 /src/dotty/tools/dotc/typer/Namer.scala
parent1ff1cf5393778b7dc21f765f5c8f372c05877862 (diff)
downloaddotty-8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c.tar.gz
dotty-8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c.tar.bz2
dotty-8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c.zip
Constant final vals need to have right hand type.
Previously, a constant right hand side was not propagated to the type of a final val that implemented another val with a given type. The inherited type was used instead. This means final vals implementing abstract vals get evaluated too late.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 0e8b4d8cf..99119acb3 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -707,18 +707,19 @@ class Namer { typer: Typer =>
// println(s"final inherited for $sym: ${inherited.toString}") !!!
// println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
def isInline = sym.is(Final, butNot = Method)
- def widenRhs(tp: Type): Type = tp match {
- case tp: TermRef => widenRhs(tp.underlying)
- case tp: ExprType => widenRhs(tp.resultType)
+ def widenRhs(tp: Type): Type = tp.widenTermRefExpr match {
case tp: ConstantType if isInline => tp
case _ => tp.widen.approximateUnion
}
val rhsCtx = ctx.addMode(Mode.InferringReturnType)
- def rhsType = typedAheadExpr(mdef.rhs, rhsProto)(rhsCtx).tpe
+ def rhsType = typedAheadExpr(mdef.rhs, inherited orElse rhsProto)(rhsCtx).tpe
def cookedRhsType = ctx.deskolemize(widenRhs(rhsType))
- def lhsType = fullyDefinedType(cookedRhsType, "right-hand side", mdef.pos)
+ lazy val lhsType = fullyDefinedType(cookedRhsType, "right-hand side", mdef.pos)
//if (sym.name.toString == "y") println(i"rhs = $rhsType, cooked = $cookedRhsType")
- if (inherited.exists) inherited
+ if (inherited.exists)
+ if (sym.is(Final, butNot = Method) && lhsType.isInstanceOf[ConstantType])
+ lhsType // keep constant types that fill in for a non-constant (to be revised when inline has landed).
+ else inherited
else {
if (sym is Implicit) {
val resStr = if (mdef.isInstanceOf[DefDef]) "result " else ""