aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-05-29 14:14:28 +0200
committerMartin Odersky <odersky@gmail.com>2015-05-29 15:45:19 +0200
commit7bc7c9ba5e04b9a17ed7d548f3ea8caf7bd8c4a7 (patch)
tree05f92cdf5c9b3d42d93623150ddecc67d40ea10d /src/dotty/tools/dotc/typer/Typer.scala
parentef274600378cc55b78ad62ac9afc8ce9a21efb89 (diff)
downloaddotty-7bc7c9ba5e04b9a17ed7d548f3ea8caf7bd8c4a7.tar.gz
dotty-7bc7c9ba5e04b9a17ed7d548f3ea8caf7bd8c4a7.tar.bz2
dotty-7bc7c9ba5e04b9a17ed7d548f3ea8caf7bd8c4a7.zip
Fix compilation failure by refining adaptation of constants
Constants that are adapted to a different supertype need to do this explicitly (not just by changing the type). Otherwise tree checkers will compute the original type and fail. This caused a test failure in pos/harmonize. The mystery is why this was not caught in the checkin tests.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index ea19dd1c9..acf4f3845 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1337,10 +1337,22 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
+ /** Adapt an expression of constant type to a different constant type `tpe`. */
+ def adaptConstant(tree: Tree, tpe: ConstantType): Tree = {
+ def lit = Literal(tpe.value).withPos(tree.pos)
+ tree match {
+ case Literal(c) => lit
+ case tree @ Block(stats, expr) => tpd.cpy.Block(tree)(stats, adaptConstant(expr, tpe))
+ case tree =>
+ if (isIdempotentExpr(tree)) lit // See discussion in phase Literalize why we demand isIdempotentExpr
+ else Block(tree :: Nil, lit)
+ }
+ }
+
def adaptToSubType(wtp: Type): Tree = {
// try converting a constant to the target type
val folded = ConstFold(tree, pt)
- if (folded ne tree) return folded
+ if (folded ne tree) return adaptConstant(folded, folded.tpe.asInstanceOf[ConstantType])
// drop type if prototype is Unit
if (pt isRef defn.UnitClass)
return tpd.Block(tree :: Nil, Literal(Constant(())))