From 456e7c63af694274331b940adfe0da7077424af9 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 23 Mar 2021 11:35:28 +0100 Subject: [PATCH] Only pickle StableRealizable flag for methods Fixes #9276 That aligns behavior with the TastyFormat doc, where it says: STABLE -- Method that is assumed to be stable, i.e. its applications are legal paths For other occurrences of StableRealizable, we either reconstitute them if they are implied (i.e. for module vals and enum values), or we recompute them in realizability checking as needed. --- compiler/src/dotty/tools/dotc/core/Flags.scala | 6 ++++++ compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala | 2 +- .../src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index d077524342ac..76cb45c1b28c 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -300,6 +300,11 @@ object Flags { * * - the purity analysis used by the inliner to decide whether it is safe to elide, and * - the TASTy reader of Scala 2.13, to determine whether there is a $init$ method. + * + * StableRealizable is + * - asserted for methods + * - automatic in conjunction with Module or Enum vals + * - cached for other vals */ val (_, StableRealizable @ _, _) = newFlags(24, "") @@ -584,6 +589,7 @@ object Flags { val MethodOrModule: FlagSet = Method | Module val ParamForwarder: FlagSet = Method | ParamAccessor | StableRealizable // A parameter forwarder val PrivateMethod: FlagSet = Method | Private + val StableMethod: FlagSet = Method | StableRealizable val NoInitsInterface: FlagSet = NoInits | PureInterface val NoInitsTrait: FlagSet = NoInits | Trait // A trait that does not need to be initialized val ValidForeverFlags: FlagSet = Package | Permanent | Scala2SpecialFlags diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 0ee7fe15f32d..792ddd52de9f 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -739,7 +739,7 @@ class TreePickler(pickler: TastyPickler) { if (flags.is(Accessor)) writeModTag(FIELDaccessor) if (flags.is(CaseAccessor)) writeModTag(CASEaccessor) if (flags.is(HasDefault)) writeModTag(HASDEFAULT) - if (flags.is(StableRealizable)) writeModTag(STABLE) + if flags.isAllOf(StableMethod) then writeModTag(STABLE) // other StableRealizable flag occurrences are either implied or can be recomputed if (flags.is(Extension)) writeModTag(EXTENSION) if (flags.is(ParamAccessor)) writeModTag(PARAMsetter) if (flags.is(SuperParamAlias)) writeModTag(PARAMalias) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index f210f9934df2..043ad61d3ba4 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -487,7 +487,9 @@ class TreeUnpickler(reader: TastyReader, if (lacksDefinition && tag != PARAM) flags |= Deferred if (tag == DEFDEF) flags |= Method if (givenFlags.is(Module)) - flags = flags | (if (tag == VALDEF) ModuleValCreationFlags else ModuleClassCreationFlags) + flags |= (if (tag == VALDEF) ModuleValCreationFlags else ModuleClassCreationFlags) + if flags.is(Enum, butNot = Method) && name.isTermName then + flags |= StableRealizable if (ctx.owner.isClass) { if (tag == TYPEPARAM) flags |= Param else if (tag == PARAM) {