@@ -156,7 +156,7 @@ object Semantic:
156
156
def hasField (f : Symbol ) = fields.contains(f)
157
157
158
158
object Promoted :
159
- class PromotionInfo :
159
+ class PromotionInfo ( val entryClass : ClassSymbol ) :
160
160
var isCurrentObjectPromoted : Boolean = false
161
161
val values = mutable.Set .empty[Value ]
162
162
override def toString (): String = values.toString()
@@ -165,14 +165,15 @@ object Semantic:
165
165
opaque type Promoted = PromotionInfo
166
166
167
167
/** Note: don't use `val` to avoid incorrect sharing */
168
- def empty : Promoted = new PromotionInfo
168
+ def empty ( entryClass : ClassSymbol ) : Promoted = new PromotionInfo (entryClass)
169
169
170
170
extension (promoted : Promoted )
171
171
def isCurrentObjectPromoted : Boolean = promoted.isCurrentObjectPromoted
172
172
def promoteCurrent (thisRef : ThisRef ): Unit = promoted.isCurrentObjectPromoted = true
173
173
def contains (value : Value ): Boolean = promoted.values.contains(value)
174
174
def add (value : Value ): Unit = promoted.values += value
175
175
def remove (value : Value ): Unit = promoted.values -= value
176
+ def entryClass : ClassSymbol = promoted.entryClass
176
177
end extension
177
178
end Promoted
178
179
type Promoted = Promoted .Promoted
@@ -658,12 +659,12 @@ object Semantic:
658
659
659
660
def select (field : Symbol , receiver : Type , needResolve : Boolean = true ): Contextual [Value ] = log(" select " + field.show + " , this = " + value, printer, (_ : Value ).show) {
660
661
if promoted.isCurrentObjectPromoted then Hot
661
- else value match {
662
+ else value match
662
663
case Hot =>
663
664
Hot
664
665
665
666
case Cold =>
666
- val error = AccessCold (field, trace.toVector)
667
+ val error = AccessCold (field)( trace.toVector)
667
668
reporter.report(error)
668
669
Hot
669
670
@@ -688,11 +689,11 @@ object Semantic:
688
689
val rhs = target.defTree.asInstanceOf [ValOrDefDef ].rhs
689
690
eval(rhs, ref, target.owner.asClass, cacheResult = true )
690
691
else
691
- val error = CallUnknown (field, trace.toVector)
692
+ val error = CallUnknown (field)( trace.toVector)
692
693
reporter.report(error)
693
694
Hot
694
695
else
695
- val error = AccessNonInit (target, trace.toVector)
696
+ val error = AccessNonInit (target)( trace.toVector)
696
697
reporter.report(error)
697
698
Hot
698
699
else
@@ -710,7 +711,6 @@ object Semantic:
710
711
711
712
case RefSet (refs) =>
712
713
refs.map(_.select(field, receiver)).join
713
- }
714
714
}
715
715
716
716
def call (meth : Symbol , args : List [ArgInfo ], receiver : Type , superType : Type , needResolve : Boolean = true ): Contextual [Value ] = log(" call " + meth.show + " , args = " + args.map(_.value.show), printer, (_ : Value ).show) {
@@ -779,7 +779,7 @@ object Semantic:
779
779
780
780
case Cold =>
781
781
promoteArgs()
782
- val error = CallCold (meth, trace.toVector)
782
+ val error = CallCold (meth)( trace.toVector)
783
783
reporter.report(error)
784
784
Hot
785
785
@@ -820,7 +820,7 @@ object Semantic:
820
820
// try promoting the receiver as last resort
821
821
val hasErrors = Reporter .hasErrors { ref.promote(" try promote value to hot" ) }
822
822
if hasErrors then
823
- val error = CallUnknown (target, trace.toVector)
823
+ val error = CallUnknown (target)( trace.toVector)
824
824
reporter.report(error)
825
825
Hot
826
826
else if target.exists then
@@ -899,7 +899,7 @@ object Semantic:
899
899
Hot
900
900
else
901
901
// no source code available
902
- val error = CallUnknown (ctor, trace.toVector)
902
+ val error = CallUnknown (ctor)( trace.toVector)
903
903
reporter.report(error)
904
904
Hot
905
905
}
@@ -922,7 +922,7 @@ object Semantic:
922
922
yield
923
923
i + 1
924
924
925
- val error = UnsafeLeaking (trace.toVector, errors.head, nonHotOuterClass, indices)
925
+ val error = UnsafeLeaking (errors.head, nonHotOuterClass, indices)(trace.toVector )
926
926
reporter.report(error)
927
927
Hot
928
928
else
@@ -947,7 +947,7 @@ object Semantic:
947
947
tryLeak(warm, NoSymbol , args2)
948
948
949
949
case Cold =>
950
- val error = CallCold (ctor, trace.toVector)
950
+ val error = CallCold (ctor)( trace.toVector)
951
951
reporter.report(error)
952
952
Hot
953
953
@@ -1078,15 +1078,15 @@ object Semantic:
1078
1078
case Hot =>
1079
1079
1080
1080
case Cold =>
1081
- reporter.report(PromoteError (msg, trace.toVector))
1081
+ reporter.report(PromoteError (msg)( trace.toVector))
1082
1082
1083
1083
case thisRef : ThisRef =>
1084
1084
val emptyFields = thisRef.nonInitFields()
1085
1085
if emptyFields.isEmpty then
1086
1086
promoted.promoteCurrent(thisRef)
1087
1087
else
1088
1088
val fields = " Non initialized field(s): " + emptyFields.map(_.show).mkString(" , " ) + " ."
1089
- reporter.report(PromoteError (msg + " \n " + fields, trace.toVector))
1089
+ reporter.report(PromoteError (msg + " \n " + fields)( trace.toVector))
1090
1090
1091
1091
case warm : Warm =>
1092
1092
if ! promoted.contains(warm) then
@@ -1106,7 +1106,7 @@ object Semantic:
1106
1106
res.promote(" The function return value is not hot. Found = " + res.show + " ." )
1107
1107
}
1108
1108
if errors.nonEmpty then
1109
- reporter.report(UnsafePromotion (msg, trace.toVector, errors.head))
1109
+ reporter.report(UnsafePromotion (msg, errors.head)(trace.toVector ))
1110
1110
else
1111
1111
promoted.add(fun)
1112
1112
@@ -1156,7 +1156,7 @@ object Semantic:
1156
1156
if ! isHotSegment then
1157
1157
for member <- klass.info.decls do
1158
1158
if member.isClass then
1159
- val error = PromoteError (" Promotion cancelled as the value contains inner " + member.show + " ." , Vector .empty)
1159
+ val error = PromoteError (" Promotion cancelled as the value contains inner " + member.show + " ." )( Vector .empty)
1160
1160
reporter.report(error)
1161
1161
else if ! member.isType && ! member.isConstructor && ! member.is(Flags .Deferred ) then
1162
1162
given Trace = Trace .empty
@@ -1189,7 +1189,7 @@ object Semantic:
1189
1189
}
1190
1190
1191
1191
if errors.isEmpty then Nil
1192
- else UnsafePromotion (msg, trace.toVector, errors.head) :: Nil
1192
+ else UnsafePromotion (msg, errors.head)(trace.toVector ) :: Nil
1193
1193
}
1194
1194
1195
1195
end extension
@@ -1230,7 +1230,7 @@ object Semantic:
1230
1230
1231
1231
@ tailrec
1232
1232
def iterate (): Unit = {
1233
- given Promoted = Promoted .empty
1233
+ given Promoted = Promoted .empty(thisRef.klass)
1234
1234
given Trace = Trace .empty.add(thisRef.klass.defTree)
1235
1235
given reporter : Reporter .BufferedReporter = new Reporter .BufferedReporter
1236
1236
@@ -1513,16 +1513,24 @@ object Semantic:
1513
1513
thisV.accessLocal(tmref, klass)
1514
1514
1515
1515
case tmref : TermRef =>
1516
- cases(tmref.prefix, thisV, klass).select(tmref.symbol, receiver = tmref.prefix)
1516
+ val cls = tmref.widenSingleton.classSymbol
1517
+ if cls.exists && cls.isStaticOwner then
1518
+ if klass.isContainedIn(cls) then
1519
+ resolveThis(cls.asClass, thisV, klass)
1520
+ else if cls.isContainedIn(promoted.entryClass) then
1521
+ cases(tmref.prefix, thisV, klass).select(tmref.symbol, receiver = tmref.prefix)
1522
+ else
1523
+ Hot
1524
+ else
1525
+ cases(tmref.prefix, thisV, klass).select(tmref.symbol, receiver = tmref.prefix)
1517
1526
1518
1527
case tp @ ThisType (tref) =>
1519
1528
val cls = tref.classSymbol.asClass
1520
1529
if cls.isStaticOwner && ! klass.isContainedIn(cls) then
1521
1530
// O.this outside the body of the object O
1522
1531
Hot
1523
1532
else
1524
- val value = resolveThis(cls, thisV, klass)
1525
- value
1533
+ resolveThis(cls, thisV, klass)
1526
1534
1527
1535
case _ : TermParamRef | _ : RecThis =>
1528
1536
// possible from checking effects of types
@@ -1664,7 +1672,16 @@ object Semantic:
1664
1672
if thisV.isThisRef || ! thisV.asInstanceOf [Warm ].isPopulatingParams then tpl.body.foreach {
1665
1673
case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.rhs.isEmpty =>
1666
1674
val res = eval(vdef.rhs, thisV, klass)
1667
- thisV.updateField(vdef.symbol, res)
1675
+ // TODO: Improve promotion to avoid handling enum initialization specially
1676
+ //
1677
+ // The failing case is tests/init/pos/i12544.scala due to promotion failure.
1678
+ if vdef.symbol.name == nme.DOLLAR_VALUES
1679
+ && vdef.symbol.is(Flags .Synthetic )
1680
+ && vdef.symbol.owner.companionClass.is(Flags .Enum )
1681
+ then
1682
+ thisV.updateField(vdef.symbol, Hot )
1683
+ else
1684
+ thisV.updateField(vdef.symbol, res)
1668
1685
fieldsChanged = true
1669
1686
1670
1687
case _ : MemberDef =>
0 commit comments