Skip to content

Commit 5eb9f49

Browse files
committed
Fix #5486: Constant-fold types in TypeAssigner
Instead of doing it in Typer, sometimes losing it in PostTyper or when unpickling, then recovering it in FirstTransform. We still need a special case in TreeUnpickler because we don't use TypeAssigner when unpickling Select nodes.
1 parent 052c3b1 commit 5eb9f49

File tree

6 files changed

+17
-21
lines changed

6 files changed

+17
-21
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Flags._
1616
import Constants._
1717
import Annotations._
1818
import NameKinds._
19+
import typer.ConstFold
1920
import typer.Checking.checkNonCyclic
2021
import util.Positions._
2122
import ast.{TreeTypeMap, Trees, tpd, untpd}
@@ -996,7 +997,7 @@ class TreeUnpickler(reader: TastyReader,
996997
val localCtx =
997998
if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx
998999
val qual = readTerm()(localCtx)
999-
untpd.Select(qual, name).withType(tpf(qual.tpe.widenIfUnstable))
1000+
ConstFold(untpd.Select(qual, name).withType(tpf(qual.tpe.widenIfUnstable)))
10001001
}
10011002

10021003
def readQualId(): (untpd.Ident, TypeRef) = {

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -588,15 +588,6 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
588588
// add type to term nodes; replace type nodes with their types unless -Yprint-pos is also set.
589589
def tp = tree.typeOpt match {
590590
case tp: TermRef if tree.isInstanceOf[RefTree] && !tp.denot.isOverloaded => tp.underlying
591-
case tp: ConstantType if homogenizedView =>
592-
// constant folded types are forgotten in Tasty, are reconstituted subsequently in FirstTransform.
593-
// Therefore we have to gloss over this when comparing before/after pickling by widening to
594-
// underlying type `T`, or, if expression is a unary primitive operation, to `=> T`.
595-
tree match {
596-
case Select(qual, _) if qual.typeOpt.widen.typeSymbol.isPrimitiveValueClass =>
597-
ExprType(tp.widen)
598-
case _ => tp.widen
599-
}
600591
case tp => tp
601592
}
602593
if (!suppressTypes)

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
769769
new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt)
770770
else
771771
new ApplyToUntyped(tree, fun1, funRef, proto, pt)(argCtx(tree))
772-
convertNewGenericArray(ConstFold(app.result))
772+
convertNewGenericArray(app.result)
773773
case _ =>
774774
handleUnexpectedFunType(tree, fun1)
775775
}

compiler/src/dotty/tools/dotc/typer/ConstFold.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object ConstFold {
1717
import tpd._
1818

1919
/** If tree is a constant operation, replace with result. */
20-
def apply(tree: Tree)(implicit ctx: Context): Tree = finish(tree) {
20+
def apply[T <: Tree](tree: T)(implicit ctx: Context): T = finish(tree) {
2121
tree match {
2222
case Apply(Select(xt, op), yt :: Nil) =>
2323
xt.tpe.widenTermRefExpr match {
@@ -40,18 +40,18 @@ object ConstFold {
4040
/** If tree is a constant value that can be converted to type `pt`, perform
4141
* the conversion.
4242
*/
43-
def apply(tree: Tree, pt: Type)(implicit ctx: Context): Tree =
43+
def apply[T <: Tree](tree: T, pt: Type)(implicit ctx: Context): T =
4444
finish(apply(tree)) {
4545
tree.tpe.widenTermRefExpr match {
4646
case ConstantType(x) => x convertTo pt
4747
case _ => null
4848
}
4949
}
5050

51-
private def finish(tree: Tree)(compX: => Constant)(implicit ctx: Context): Tree =
51+
private def finish[T <: Tree](tree: T)(compX: => Constant)(implicit ctx: Context): T =
5252
try {
5353
val x = compX
54-
if (x ne null) tree withType ConstantType(x)
54+
if (x ne null) tree.withType(ConstantType(x)).asInstanceOf[T]
5555
else tree
5656
} catch {
5757
case _: ArithmeticException => tree // the code will crash at runtime,

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ trait TypeAssigner {
291291

292292
case _ => accessibleSelectionType(tree, qual)
293293
}
294-
tree.withType(tp)
294+
ConstFold(tree.withType(tp))
295295
}
296296

297297
def assignType(tree: untpd.New, tpt: Tree)(implicit ctx: Context): New =
@@ -372,7 +372,7 @@ trait TypeAssigner {
372372
case t =>
373373
errorType(err.takesNoParamsStr(fn, ""), tree.pos)
374374
}
375-
tree.withType(ownType)
375+
ConstFold(tree.withType(ownType))
376376
}
377377

378378
def assignType(tree: untpd.TypeApply, fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = {

tests/pos/constfold.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
object A {
2-
val x = 2;
3-
val y = x.asInstanceOf[Byte];
4-
val z = 1.0 / 2;
5-
val s = "z is " + z;
2+
val x = 2
3+
val y = x.asInstanceOf[Byte]
4+
val z = 1.0 / 2
5+
val s = "z is " + z
6+
7+
val a = 1 + 1
8+
val b = -(1:1)
9+
val c = -(1:1 & Any)
610
}
711

812
object Test extends App {

0 commit comments

Comments
 (0)