Skip to content

Commit 8d3083b

Browse files
authored
Merge pull request #14853 from dotty-staging/fix-2266
Fix constToLiteral
2 parents 2fa2663 + 6df2c6e commit 8d3083b

File tree

6 files changed

+45
-22
lines changed

6 files changed

+45
-22
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -577,21 +577,28 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
577577
// blocks returning a class literal alone, even if they're idempotent.
578578
tree1
579579
case ConstantType(value) =>
580-
if (isIdempotentExpr(tree1)) Literal(value).withSpan(tree.span)
581-
else {
582-
def keepPrefix(pre: Tree) =
580+
def dropOp(t: Tree): Tree = t match
581+
case Select(pre, _) if t.tpe.isInstanceOf[ConstantType] =>
582+
// it's a primitive unary operator
583+
pre
584+
case Apply(TypeApply(Select(pre, nme.getClass_), _), Nil) =>
585+
pre
586+
case _ =>
587+
tree1
588+
589+
val countsAsPure =
590+
if dropOp(tree1).symbol.isInlineVal
591+
then isIdempotentExpr(tree1)
592+
else isPureExpr(tree1)
593+
594+
if countsAsPure then Literal(value).withSpan(tree.span)
595+
else
596+
val pre = dropOp(tree1)
597+
if pre eq tree1 then tree1
598+
else
599+
// it's a primitive unary operator or getClass call;
600+
// Simplify `pre.op` to `{ pre; v }` where `v` is the value of `pre.op`
583601
Block(pre :: Nil, Literal(value)).withSpan(tree.span)
584-
585-
tree1 match {
586-
case Select(pre, _) if tree1.tpe.isInstanceOf[ConstantType] =>
587-
// it's a primitive unary operator; Simplify `pre.op` to `{ pre; v }` where `v` is the value of `pre.op`
588-
keepPrefix(pre)
589-
case Apply(TypeApply(Select(pre, nme.getClass_), _), Nil) =>
590-
keepPrefix(pre)
591-
case _ =>
592-
tree1
593-
}
594-
}
595602
case _ => tree1
596603
}
597604
}

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ object SymUtils:
110110
self.isCoDefinedGiven(res.typeSymbol)
111111
self.isAllOf(Given | Method) && isCodefined(self.info)
112112

113+
// TODO Scala 3.x: only check for inline vals (no final ones)
114+
def isInlineVal(using Context) =
115+
self.isOneOf(FinalOrInline, butNot = Mutable)
116+
&& (!self.is(Method) || self.is(Accessor))
117+
113118
def useCompanionAsSumMirror(using Context): Boolean =
114119
def companionExtendsSum(using Context): Boolean =
115120
self.linkedClass.isSubClass(defn.Mirror_SumClass)

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,11 +1694,6 @@ class Namer { typer: Typer =>
16941694
case _ =>
16951695
approxTp
16961696

1697-
// println(s"final inherited for $sym: ${inherited.toString}") !!!
1698-
// println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
1699-
// TODO Scala 3.1: only check for inline vals (no final ones)
1700-
def isInlineVal = sym.isOneOf(FinalOrInline, butNot = Method | Mutable)
1701-
17021697
var rhsCtx = ctx.fresh.addMode(Mode.InferringReturnType)
17031698
if sym.isInlineMethod then rhsCtx = rhsCtx.addMode(Mode.InlineableBody)
17041699
if sym.is(ExtensionMethod) then rhsCtx = rhsCtx.addMode(Mode.InExtensionMethod)
@@ -1732,7 +1727,7 @@ class Namer { typer: Typer =>
17321727
// don't strip @uncheckedVariance annot for default getters
17331728
TypeOps.simplify(tp.widenTermRefExpr,
17341729
if defaultTp.exists then TypeOps.SimplifyKeepUnchecked() else null) match
1735-
case ctp: ConstantType if isInlineVal => ctp
1730+
case ctp: ConstantType if sym.isInlineVal => ctp
17361731
case tp => TypeComparer.widenInferred(tp, pt)
17371732

17381733
// Replace aliases to Unit by Unit itself. If we leave the alias in
@@ -1743,7 +1738,7 @@ class Namer { typer: Typer =>
17431738
def lhsType = fullyDefinedType(cookedRhsType, "right-hand side", mdef.span)
17441739
//if (sym.name.toString == "y") println(i"rhs = $rhsType, cooked = $cookedRhsType")
17451740
if (inherited.exists)
1746-
if (isInlineVal) lhsType else inherited
1741+
if sym.isInlineVal then lhsType else inherited
17471742
else {
17481743
if (sym.is(Implicit))
17491744
mdef match {

tests/pos/java-annot/S.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
object C {
2-
val cs: "cs" = "cs"
2+
final val cs: "cs" = "cs"
33
}
44

55
object S {

tests/run/i2266.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
X
2+
true
3+
1

tests/run/i2266.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Test extends App {
2+
lazy val x: true = { println("X"); true }
3+
println(x)
4+
5+
object Inner {
6+
println("Y") // not printed
7+
inline val y = 1
8+
}
9+
println(Inner.y)
10+
11+
inline val MV = Int.MaxValue
12+
}
13+

0 commit comments

Comments
 (0)