Skip to content

Commit 44021ea

Browse files
Process Deferred flag last on unpickling
Now that Deferred is conditionally immutable, if we query it along with other properly immutable flags, the query may trigger completion. This will happen if the symbol in question is also opaque and is a type. The completion will be rightfully triggered since the opaque mechanism does indeed mutate the deferred flag on opaque types. However, if e.g. we query `is(Method, butNot = Deferred)` on `opaque type B`, we may be able to return `false` on the query as soon as we see that the symbol in question is not a method, without triggering the completion. Too early completion is undesirable since completion of opaque types modifies the self-type of its owner. If the completion of an opaque type happens during unpickling of the owner itself, the self-type of the owner may be rewritten later in its completion.
1 parent 09d164e commit 44021ea

File tree

2 files changed

+2
-5
lines changed

2 files changed

+2
-5
lines changed

compiler/src/dotty/tools/dotc/core/Flags.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,7 @@ object Flags {
456456
*/
457457
object ConditionallyImmutableFlags {
458458
val flagsAndConditions: List[(Flag, (given Contexts.Context) => SymDenotations.SymDenotation => Boolean)] = List(
459-
Deferred -> { denot =>
460-
denot.is(Opaque) && denot.isType &&
461-
!denot.infoOrCompleter.isInstanceOf[SymbolLoader] // If it is loaded, we assume the opaque mechanism has already set the flags correctly
462-
}
459+
Deferred -> { denot => denot.is(Opaque) && denot.isType }
463460
)
464461

465462
val flags: FlagSet = flagsAndConditions.map(_._1)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ class TreeUnpickler(reader: TastyReader,
677677
if (sym.isTerm && !sym.isOneOf(DeferredOrLazyOrMethod))
678678
initsFlags = EmptyFlags
679679
else if (sym.isClass ||
680-
sym.is(Method, butNot = Deferred) && !sym.isConstructor)
680+
sym.is(Method) && !sym.is(Deferred) && !sym.isConstructor)
681681
initsFlags &= NoInits
682682
case IMPORT =>
683683
skipTree()

0 commit comments

Comments
 (0)