diff options
author | Martin Odersky <odersky@gmail.com> | 2015-09-08 10:37:49 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-09-14 13:36:14 +0200 |
commit | 8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c (patch) | |
tree | 4ccee051facbd2a5e6554dca681fdadc2def4a93 /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 1ff1cf5393778b7dc21f765f5c8f372c05877862 (diff) | |
download | dotty-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.scala | 13 |
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 "" |