@@ -156,7 +156,7 @@ object Semantic:
156156 def hasField (f : Symbol ) = fields.contains(f)
157157
158158 object Promoted :
159- class PromotionInfo :
159+ class PromotionInfo ( val entryClass : ClassSymbol ) :
160160 var isCurrentObjectPromoted : Boolean = false
161161 val values = mutable.Set .empty[Value ]
162162 override def toString (): String = values.toString()
@@ -165,14 +165,15 @@ object Semantic:
165165 opaque type Promoted = PromotionInfo
166166
167167 /** Note: don't use `val` to avoid incorrect sharing */
168- def empty : Promoted = new PromotionInfo
168+ def empty ( entryClass : ClassSymbol ) : Promoted = new PromotionInfo (entryClass)
169169
170170 extension (promoted : Promoted )
171171 def isCurrentObjectPromoted : Boolean = promoted.isCurrentObjectPromoted
172172 def promoteCurrent (thisRef : ThisRef ): Unit = promoted.isCurrentObjectPromoted = true
173173 def contains (value : Value ): Boolean = promoted.values.contains(value)
174174 def add (value : Value ): Unit = promoted.values += value
175175 def remove (value : Value ): Unit = promoted.values -= value
176+ def entryClass : ClassSymbol = promoted.entryClass
176177 end extension
177178 end Promoted
178179 type Promoted = Promoted .Promoted
@@ -658,12 +659,12 @@ object Semantic:
658659
659660 def select (field : Symbol , receiver : Type , needResolve : Boolean = true ): Contextual [Value ] = log(" select " + field.show + " , this = " + value, printer, (_ : Value ).show) {
660661 if promoted.isCurrentObjectPromoted then Hot
661- else value match {
662+ else value match
662663 case Hot =>
663664 Hot
664665
665666 case Cold =>
666- val error = AccessCold (field, trace.toVector)
667+ val error = AccessCold (field)( trace.toVector)
667668 reporter.report(error)
668669 Hot
669670
@@ -688,11 +689,11 @@ object Semantic:
688689 val rhs = target.defTree.asInstanceOf [ValOrDefDef ].rhs
689690 eval(rhs, ref, target.owner.asClass, cacheResult = true )
690691 else
691- val error = CallUnknown (field, trace.toVector)
692+ val error = CallUnknown (field)( trace.toVector)
692693 reporter.report(error)
693694 Hot
694695 else
695- val error = AccessNonInit (target, trace.toVector)
696+ val error = AccessNonInit (target)( trace.toVector)
696697 reporter.report(error)
697698 Hot
698699 else
@@ -710,7 +711,6 @@ object Semantic:
710711
711712 case RefSet (refs) =>
712713 refs.map(_.select(field, receiver)).join
713- }
714714 }
715715
716716 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:
779779
780780 case Cold =>
781781 promoteArgs()
782- val error = CallCold (meth, trace.toVector)
782+ val error = CallCold (meth)( trace.toVector)
783783 reporter.report(error)
784784 Hot
785785
@@ -820,7 +820,7 @@ object Semantic:
820820 // try promoting the receiver as last resort
821821 val hasErrors = Reporter .hasErrors { ref.promote(" try promote value to hot" ) }
822822 if hasErrors then
823- val error = CallUnknown (target, trace.toVector)
823+ val error = CallUnknown (target)( trace.toVector)
824824 reporter.report(error)
825825 Hot
826826 else if target.exists then
@@ -899,7 +899,7 @@ object Semantic:
899899 Hot
900900 else
901901 // no source code available
902- val error = CallUnknown (ctor, trace.toVector)
902+ val error = CallUnknown (ctor)( trace.toVector)
903903 reporter.report(error)
904904 Hot
905905 }
@@ -922,7 +922,7 @@ object Semantic:
922922 yield
923923 i + 1
924924
925- val error = UnsafeLeaking (trace.toVector, errors.head, nonHotOuterClass, indices)
925+ val error = UnsafeLeaking (errors.head, nonHotOuterClass, indices)(trace.toVector )
926926 reporter.report(error)
927927 Hot
928928 else
@@ -947,7 +947,7 @@ object Semantic:
947947 tryLeak(warm, NoSymbol , args2)
948948
949949 case Cold =>
950- val error = CallCold (ctor, trace.toVector)
950+ val error = CallCold (ctor)( trace.toVector)
951951 reporter.report(error)
952952 Hot
953953
@@ -1078,15 +1078,15 @@ object Semantic:
10781078 case Hot =>
10791079
10801080 case Cold =>
1081- reporter.report(PromoteError (msg, trace.toVector))
1081+ reporter.report(PromoteError (msg)( trace.toVector))
10821082
10831083 case thisRef : ThisRef =>
10841084 val emptyFields = thisRef.nonInitFields()
10851085 if emptyFields.isEmpty then
10861086 promoted.promoteCurrent(thisRef)
10871087 else
10881088 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))
10901090
10911091 case warm : Warm =>
10921092 if ! promoted.contains(warm) then
@@ -1106,7 +1106,7 @@ object Semantic:
11061106 res.promote(" The function return value is not hot. Found = " + res.show + " ." )
11071107 }
11081108 if errors.nonEmpty then
1109- reporter.report(UnsafePromotion (msg, trace.toVector, errors.head))
1109+ reporter.report(UnsafePromotion (msg, errors.head)(trace.toVector ))
11101110 else
11111111 promoted.add(fun)
11121112
@@ -1156,7 +1156,7 @@ object Semantic:
11561156 if ! isHotSegment then
11571157 for member <- klass.info.decls do
11581158 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)
11601160 reporter.report(error)
11611161 else if ! member.isType && ! member.isConstructor && ! member.is(Flags .Deferred ) then
11621162 given Trace = Trace .empty
@@ -1189,7 +1189,7 @@ object Semantic:
11891189 }
11901190
11911191 if errors.isEmpty then Nil
1192- else UnsafePromotion (msg, trace.toVector, errors.head) :: Nil
1192+ else UnsafePromotion (msg, errors.head)(trace.toVector ) :: Nil
11931193 }
11941194
11951195 end extension
@@ -1230,7 +1230,7 @@ object Semantic:
12301230
12311231 @ tailrec
12321232 def iterate (): Unit = {
1233- given Promoted = Promoted .empty
1233+ given Promoted = Promoted .empty(thisRef.klass)
12341234 given Trace = Trace .empty.add(thisRef.klass.defTree)
12351235 given reporter : Reporter .BufferedReporter = new Reporter .BufferedReporter
12361236
@@ -1513,16 +1513,24 @@ object Semantic:
15131513 thisV.accessLocal(tmref, klass)
15141514
15151515 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)
15171526
15181527 case tp @ ThisType (tref) =>
15191528 val cls = tref.classSymbol.asClass
15201529 if cls.isStaticOwner && ! klass.isContainedIn(cls) then
15211530 // O.this outside the body of the object O
15221531 Hot
15231532 else
1524- val value = resolveThis(cls, thisV, klass)
1525- value
1533+ resolveThis(cls, thisV, klass)
15261534
15271535 case _ : TermParamRef | _ : RecThis =>
15281536 // possible from checking effects of types
@@ -1664,7 +1672,16 @@ object Semantic:
16641672 if thisV.isThisRef || ! thisV.asInstanceOf [Warm ].isPopulatingParams then tpl.body.foreach {
16651673 case vdef : ValDef if ! vdef.symbol.is(Flags .Lazy ) && ! vdef.rhs.isEmpty =>
16661674 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)
16681685 fieldsChanged = true
16691686
16701687 case _ : MemberDef =>
0 commit comments