Skip to content

Commit 0b28d58

Browse files
committed
Add capture checking attributes to TASTy
1 parent e7f8a2c commit 0b28d58

File tree

6 files changed

+22
-19
lines changed

6 files changed

+22
-19
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,8 +1038,6 @@ class Definitions {
10381038
@tu lazy val UncheckedVarianceAnnot: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedVariance")
10391039
@tu lazy val UncheckedCapturesAnnot: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedCaptures")
10401040
@tu lazy val VolatileAnnot: ClassSymbol = requiredClass("scala.volatile")
1041-
@tu lazy val WithPureFunsAnnot: ClassSymbol = requiredClass("scala.annotation.internal.WithPureFuns")
1042-
@tu lazy val CaptureCheckedAnnot: ClassSymbol = requiredClass("scala.annotation.internal.CaptureChecked")
10431041
@tu lazy val BeanGetterMetaAnnot: ClassSymbol = requiredClass("scala.annotation.meta.beanGetter")
10441042
@tu lazy val BeanSetterMetaAnnot: ClassSymbol = requiredClass("scala.annotation.meta.beanSetter")
10451043
@tu lazy val FieldMetaAnnot: ClassSymbol = requiredClass("scala.annotation.meta.field")
@@ -2004,7 +2002,7 @@ class Definitions {
20042002
@tu lazy val ccExperimental: Set[Symbol] = Set(
20052003
CapsModule, CapsModule.moduleClass, PureClass,
20062004
CapabilityAnnot, RequiresCapabilityAnnot,
2007-
RetainsAnnot, RetainsByNameAnnot, WithPureFunsAnnot)
2005+
RetainsAnnot, RetainsByNameAnnot)
20082006

20092007
// ----- primitive value class machinery ------------------------------------------
20102008

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,23 @@ class Attributes(
99
booleanTags.contains(TastyFormat.SCALA2STANDARDLIBRARYattr)
1010
def explicitNulls: Boolean =
1111
booleanTags.contains(TastyFormat.EXPLICITNULLSattr)
12+
def captureChecked: Boolean =
13+
booleanTags.contains(TastyFormat.CAPTURECHECKEDattr)
14+
def withPureFuns: Boolean =
15+
booleanTags.contains(TastyFormat.WITHPUREFUNSattr)
1216
}
1317

1418
object Attributes:
1519
def apply(
1620
scala2StandardLibrary: Boolean,
1721
explicitNulls: Boolean,
22+
captureChecked: Boolean,
23+
withPureFuns: Boolean,
1824
): Attributes =
1925
val booleanTags = List.newBuilder[Int]
2026
if scala2StandardLibrary then booleanTags += TastyFormat.SCALA2STANDARDLIBRARYattr
2127
if explicitNulls then booleanTags += TastyFormat.EXPLICITNULLSattr
28+
if captureChecked then booleanTags += TastyFormat.CAPTURECHECKEDattr
29+
if withPureFuns then booleanTags += TastyFormat.WITHPUREFUNSattr
2230
new Attributes(booleanTags.result())
2331
end apply

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,9 @@ class TreeUnpickler(reader: TastyReader,
9292
/** The root owner tree. See `OwnerTree` class definition. Set by `enterTopLevel`. */
9393
private var ownerTree: OwnerTree = uninitialized
9494

95-
/** Was unpickled class compiled with pureFunctions? */
96-
private var withPureFuns: Boolean = false
97-
9895
/** Was unpickled class compiled with capture checks? */
99-
private var withCaptureChecks: Boolean = false
96+
private val withCaptureChecks: Boolean =
97+
attributeUnpicklerOpt.exists(_.attributes.captureChecked)
10098

10199
private val unpicklingScala2Library =
102100
attributeUnpicklerOpt.exists(_.attributes.scala2StandardLibrary)
@@ -655,13 +653,8 @@ class TreeUnpickler(reader: TastyReader,
655653
}
656654
registerSym(start, sym)
657655
if (isClass) {
658-
if sym.owner.is(Package) then
659-
if annots.exists(_.hasSymbol(defn.CaptureCheckedAnnot)) then
660-
sym.setFlag(CaptureChecked)
661-
withCaptureChecks = true
662-
withPureFuns = true
663-
else if annots.exists(_.hasSymbol(defn.WithPureFunsAnnot)) then
664-
withPureFuns = true
656+
if sym.owner.is(Package) && withCaptureChecks then
657+
sym.setFlag(CaptureChecked)
665658
sym.completer.withDecls(newScope)
666659
forkAt(templateStart).indexTemplateParams()(using localContext(sym))
667660
}

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Contexts.*
77
import Decorators.*
88
import tasty.*
99
import config.Printers.{noPrinter, pickling}
10+
import config.Feature
1011
import java.io.PrintStream
1112
import Periods.*
1213
import Phases.*
@@ -111,6 +112,8 @@ class Pickler extends Phase {
111112
val attributes = Attributes(
112113
scala2StandardLibrary = ctx.settings.YcompileScala2Library.value,
113114
explicitNulls = ctx.settings.YexplicitNulls.value,
115+
captureChecked = Feature.ccEnabled,
116+
withPureFuns = Feature.pureFunsEnabled,
114117
)
115118
AttributePickler.pickleAttributes(attributes, pickler, scratch.attributeBuffer)
116119

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,6 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
423423
val reference = ctx.settings.sourceroot.value
424424
val relativePath = util.SourceFile.relativePath(ctx.compilationUnit.source, reference)
425425
sym.addAnnotation(Annotation.makeSourceFile(relativePath, tree.span))
426-
if sym != defn.WithPureFunsAnnot && sym != defn.CaptureCheckedAnnot then
427-
if Feature.ccEnabled then
428-
sym.addAnnotation(Annotation(defn.CaptureCheckedAnnot, tree.span))
429-
else if Feature.pureFunsEnabled then
430-
sym.addAnnotation(Annotation(defn.WithPureFunsAnnot, tree.span))
431426
else
432427
if !sym.is(Param) && !sym.owner.isOneOf(AbstractOrTrait) then
433428
Checking.checkGoodBounds(tree.symbol)

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ Standard Section: "Attributes" Attribute*
272272
```none
273273
Attribute = SCALA2STANDARDLIBRARYattr
274274
EXPLICITNULLSattr
275+
CAPTURECHECKEDattr
276+
WITHPUREFUNSattr
275277
```
276278
277279
**************************************************************************************/
@@ -610,6 +612,8 @@ object TastyFormat {
610612

611613
final val SCALA2STANDARDLIBRARYattr = 1
612614
final val EXPLICITNULLSattr = 2
615+
final val CAPTURECHECKEDattr = 3
616+
final val WITHPUREFUNSattr = 4
613617

614618
/** Useful for debugging */
615619
def isLegalTag(tag: Int): Boolean =
@@ -829,6 +833,8 @@ object TastyFormat {
829833
def attributeTagToString(tag: Int): String = tag match {
830834
case SCALA2STANDARDLIBRARYattr => "SCALA2STANDARDLIBRARYattr"
831835
case EXPLICITNULLSattr => "EXPLICITNULLSattr"
836+
case CAPTURECHECKEDattr => "CAPTURECHECKEDattr"
837+
case WITHPUREFUNSattr => "WITHPUREFUNSattr"
832838
}
833839

834840
/** @return If non-negative, the number of leading references (represented as nats) of a length/trees entry.

0 commit comments

Comments
 (0)