Skip to content

Commit d12ebde

Browse files
committed
Fix bug with promotion of this
The previous code does not work, because private fields are not included.
1 parent 37cb75d commit d12ebde

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,10 +515,18 @@ class Semantic {
515515
promoted.isCurrentObjectPromoted || {
516516
val obj = heap(thisRef)
517517
// If we have all fields initialized, then we can promote This to hot.
518-
val allFieldsInitialized = thisRef.klass.appliedRef.fields.forall { denot =>
519-
val sym = denot.symbol
520-
sym.isOneOf(Flags.Lazy | Flags.Deferred) || obj.fields.contains(sym)
518+
val allFieldsInitialized = thisRef.klass.baseClasses.forall { klass =>
519+
if klass.hasSource then
520+
val nonInits = klass.info.decls.filter { member =>
521+
!member.isOneOf(Flags.Method | Flags.Lazy | Flags.Deferred)
522+
&& !member.isType
523+
&& !obj.fields.contains(member)
524+
}
525+
nonInits.isEmpty
526+
else
527+
true
521528
}
529+
522530
if allFieldsInitialized then promoted.promoteCurrent(thisRef)
523531
allFieldsInitialized
524532
}
@@ -535,8 +543,7 @@ class Semantic {
535543
case Cold => PromoteError(msg, source, trace.toVector) :: Nil
536544

537545
case thisRef: ThisRef =>
538-
if promoted.contains(thisRef) then Nil
539-
else if thisRef.tryPromoteCurrentObject then Nil
546+
if thisRef.tryPromoteCurrentObject then Nil
540547
else PromoteError(msg, source, trace.toVector) :: Nil
541548

542549
case warm: Warm =>

tests/init/neg/early-promote2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class M {
2+
println(this) // error
3+
foo()
4+
private val a = 5 // error
5+
def foo() = a
6+
}

0 commit comments

Comments
 (0)