Skip to content

Commit 1c3538a

Browse files
authored
Merge pull request #10496 from dotty-staging/no-mixin-const-expr-final-val
Fix #8602: Do not create mixins for constant-expression final vals.
2 parents ebee228 + dd36255 commit 1c3538a

File tree

6 files changed

+30
-6
lines changed

6 files changed

+30
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =
208208
} else
209209
dropped += sym
210210
case stat @ DefDef(name, _, _, tpt, _)
211-
if stat.symbol.isGetter && stat.symbol.owner.is(Trait) && !stat.symbol.is(Lazy) =>
211+
if stat.symbol.isGetter && stat.symbol.owner.is(Trait) && !stat.symbol.is(Lazy) && !stat.symbol.isConstExprFinalVal =>
212212
val sym = stat.symbol
213213
assert(isRetained(sym), sym)
214214
if !stat.rhs.isEmpty && !isWildcardArg(stat.rhs) then

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
126126

127127
if (sym.is(Accessor, butNot = Deferred) && ownerIsTrait) {
128128
val sym1 =
129-
if (sym.is(Lazy)) sym
129+
if (sym.is(Lazy) || sym.symbol.isConstExprFinalVal) sym
130130
else sym.copySymDenotation(initFlags = sym.flags &~ (ParamAccessor | Inline) | Deferred)
131131
sym1.ensureNotPrivate
132132
}
@@ -166,7 +166,7 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
166166
private def needsTraitSetter(sym: Symbol)(using Context): Boolean =
167167
sym.isGetter && !wasOneOf(sym, DeferredOrLazy | ParamAccessor)
168168
&& atPhase(thisPhase) { !sym.setter.exists }
169-
&& !sym.info.resultType.isInstanceOf[ConstantType]
169+
&& !sym.isConstExprFinalVal
170170

171171
private def makeTraitSetter(getter: TermSymbol)(using Context): Symbol =
172172
getter.copy(
@@ -251,7 +251,10 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
251251
cls.srcPos)
252252
EmptyTree
253253

254-
for (getter <- mixin.info.decls.toList if getter.isGetter && !wasOneOf(getter, Deferred)) yield {
254+
for
255+
getter <- mixin.info.decls.toList
256+
if getter.isGetter && !wasOneOf(getter, Deferred) && !getter.isConstExprFinalVal
257+
yield
255258
if (isCurrent(getter) || getter.name.is(ExpandedName)) {
256259
val rhs =
257260
if (wasOneOf(getter, ParamAccessor))
@@ -266,7 +269,6 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
266269
transformFollowing(DefDef(mkForwarderSym(getter.asTerm), rhs))
267270
}
268271
else EmptyTree
269-
}
270272
}
271273

272274
def setters(mixin: ClassSymbol): List[Tree] =

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import ValueClasses.isDerivedValueClass
1616
import Decorators._
1717
import Constants.Constant
1818
import Annotations.Annotation
19+
import Phases._
1920
import ast.tpd.Literal
2021

2122
import language.implicitConversions
@@ -167,6 +168,11 @@ object SymUtils:
167168
self.owner.info.decl(fieldName).suchThat(!_.is(Method)).symbol
168169
}
169170

171+
def isConstExprFinalVal(using Context): Boolean =
172+
atPhaseNoLater(erasurePhase) {
173+
self.is(Final) && self.info.resultType.isInstanceOf[ConstantType]
174+
}
175+
170176
def isField(using Context): Boolean =
171177
self.isTerm && !self.is(Method)
172178

@@ -268,4 +274,4 @@ object SymUtils:
268274
Annotation(defn.TargetNameAnnot,
269275
Literal(Constant(nameFn(original.targetName).toString)).withSpan(original.span)))
270276
end extension
271-
end SymUtils
277+
end SymUtils

tests/run/i8602/ChildClass_2.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class ChildClass_2 extends Object implements ParentTrait {
2+
public int getFoo() {
3+
return foo();
4+
}
5+
}

tests/run/i8602/ParentTrait_1.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait ParentTrait {
2+
final val foo = 5
3+
}

tests/run/i8602/Test_3.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object Test {
2+
def main(args: Array[String]): Unit =
3+
val child = new ChildClass_2()
4+
assert(child.foo == 5)
5+
assert(child.getFoo() == 5)
6+
val parent: ParentTrait = child
7+
assert(parent.foo == 5)
8+
}

0 commit comments

Comments
 (0)