Skip to content
Prev Previous commit
Next Next commit
Re-constant-fold when rechecking
This is necessary since not all constant folded terms are converted to literals. The conversion does not happen if one of the operands is impure. A test case is run/final-field.scala
  • Loading branch information
odersky committed Aug 13, 2021
commit 749000167345f03dea5f7dd8ee69e7f58cdba6a5
12 changes: 9 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/Recheck.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import NullOpsDecorator.stripNull
import typer.ErrorReporting.err
import typer.ProtoTypes.*
import typer.TypeAssigner.seqLitType
import typer.ConstFold
import config.Printers.recheckr
import util.Property
import StdNames.nme
Expand Down Expand Up @@ -70,6 +71,11 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
sym.updateInfo(reinferResult(sym.info))
case _ =>

def constFold(tree: Tree, tp: Type)(using Context): Type =
val tree1 = tree.withType(tp)
val tree2 = ConstFold(tree1)
if tree2 ne tree1 then tree2.tpe else tp

def recheckIdent(tree: Ident)(using Context): Type =
tree.tpe

Expand All @@ -83,7 +89,7 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
val mbr = qualType.findMember(name, qualType,
excluded = if tree.symbol.is(Private) then EmptyFlags else Private
).suchThat(tree.symbol ==)
qualType.select(name, mbr)
constFold(tree, qualType.select(name, mbr))

def recheckBind(tree: Bind, pt: Type)(using Context): Type = tree match
case Bind(name, body) =>
Expand Down Expand Up @@ -147,14 +153,14 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
assert(formals.isEmpty)
Nil
val argTypes = recheckArgs(tree.args, formals, fntpe.paramRefs)
fntpe.instantiate(argTypes)
constFold(tree, fntpe.instantiate(argTypes))

def recheckTypeApply(tree: TypeApply, pt: Type)(using Context): Type =
recheck(tree.fun).widen match
case fntpe: PolyType =>
assert(sameLength(fntpe.paramInfos, tree.args))
val argTypes = tree.args.map(recheck(_))
fntpe.instantiate(argTypes)
constFold(tree, fntpe.instantiate(argTypes))

def recheckTyped(tree: Typed)(using Context): Type =
val tptType = recheck(tree.tpt)
Expand Down