From 8fc5835ca13ef5ab47b29d5240d5e8d79a870b7c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 8 Sep 2015 10:37:49 +0200 Subject: 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. --- src/dotty/tools/dotc/typer/Namer.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Namer.scala') 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 "" -- cgit v1.2.3