Skip to content

Commit 881524b

Browse files
committed
Make Pure a class in scala that gets erased
The Pure marker trait is now a class in the scala package that gets erased to Object.
1 parent d02ecd0 commit 881524b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+73
-67
lines changed

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,8 @@ class Definitions {
974974
@tu lazy val Caps_unsafeUnbox: Symbol = CapsUnsafeModule.requiredMethod("unsafeUnbox")
975975
@tu lazy val Caps_unsafeBoxFunArg: Symbol = CapsUnsafeModule.requiredMethod("unsafeBoxFunArg")
976976

977+
@tu lazy val PureClass: Symbol = requiredClass("scala.Pure")
978+
977979
// Annotation base classes
978980
@tu lazy val AnnotationClass: ClassSymbol = requiredClass("scala.annotation.Annotation")
979981
@tu lazy val StaticAnnotationClass: ClassSymbol = requiredClass("scala.annotation.StaticAnnotation")
@@ -2038,15 +2040,17 @@ class Definitions {
20382040
def isValueSubClass(sym1: Symbol, sym2: Symbol): Boolean =
20392041
valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0
20402042

2041-
@tu lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] =
2042-
SimpleIdentityMap.empty[Symbol]
2043-
.updated(AnyClass, ObjectClass)
2044-
.updated(MatchableClass, ObjectClass)
2045-
.updated(AnyValClass, ObjectClass)
2046-
.updated(SingletonClass, ObjectClass)
2047-
.updated(TupleClass, ProductClass)
2048-
.updated(NonEmptyTupleClass, ProductClass)
2049-
.updated(PairClass, ObjectClass)
2043+
@tu lazy val specialErasure: collection.Map[Symbol, ClassSymbol] =
2044+
val m = mutable.Map[Symbol, ClassSymbol]()
2045+
m(AnyClass) = ObjectClass
2046+
m(MatchableClass) = ObjectClass
2047+
m(PureClass) = ObjectClass
2048+
m(AnyValClass) = ObjectClass
2049+
m(SingletonClass) = ObjectClass
2050+
m(TupleClass) = ProductClass
2051+
m(NonEmptyTupleClass) = ProductClass
2052+
m(PairClass) = ObjectClass
2053+
m
20502054

20512055
// ----- Initialization ---------------------------------------------------
20522056

library/src/scala/Pure.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package scala
2+
import annotation.experimental
3+
4+
/** A marker trait that declares that all inheriting classes are "pure" in the
5+
* sense that their values retain no capabilities including capabilities needed
6+
* to perform effects. This has formal meaning only under capture checking.
7+
*/
8+
@experimental trait Pure:
9+
this: Pure =>

library/src/scala/caps.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,3 @@ import annotation.experimental
2525
extension [T, U](f: T => U) def unsafeBoxFunArg: T => U = f
2626
end unsafe
2727

28-
/** Mixing in this trait forces a trait or class to be pure, i.e.
29-
* have no capabilities retained in its self type.
30-
*/
31-
trait Pure:
32-
this: Pure =>

project/MiMaFilters.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object MiMaFilters {
66
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.unsafeBox"),
77
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.unsafeUnbox"),
88
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.CanEqual.canEqualMap"),
9-
ProblemFilters.exclude[MissingClassProblem]("scala.caps$Pure"),
9+
ProblemFilters.exclude[MissingClassProblem]("scala.Pure"),
1010
ProblemFilters.exclude[MissingClassProblem]("scala.caps$unsafe$"),
1111
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.3-migration"),
1212
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.stdLibPatches.language.3.3"),
@@ -33,7 +33,6 @@ object MiMaFilters {
3333
// Added java.io.Serializable as LazyValControlState supertype
3434
ProblemFilters.exclude[MissingTypesProblem]("scala.runtime.LazyVals$LazyValControlState"),
3535
ProblemFilters.exclude[MissingTypesProblem]("scala.runtime.LazyVals$Waiting"),
36-
3736
)
3837
val TastyCore: Seq[ProblemFilter] = Seq(
3938
ProblemFilters.exclude[DirectMissingMethodProblem]("dotty.tools.tasty.TastyBuffer.reset"),
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@annotation.experimental class C(x: () => Unit) extends caps.Pure // error
1+
@annotation.experimental class C(x: () => Unit) extends Pure // error
22

3-
@annotation.experimental class D(@annotation.constructorOnly x: () => Unit) extends caps.Pure // ok
3+
@annotation.experimental class D(@annotation.constructorOnly x: () => Unit) extends Pure // ok
44

tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
209209
}
210210
} // end of trait BCPickles
211211

212-
trait BCInnerClassGen extends caps.Pure {
212+
trait BCInnerClassGen extends Pure {
213213

214214
def debugLevel = 3 // 0 -> no debug info; 1-> filename; 2-> lines; 3-> varnames
215215

tests/pos-with-compiler-cc/backend/jvm/BCodeIdiomatic.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import dotty.tools.dotc.report
1717
* @version 1.0
1818
*
1919
*/
20-
trait BCodeIdiomatic extends caps.Pure {
20+
trait BCodeIdiomatic extends Pure {
2121
val int: DottyBackendInterface
2222
final lazy val bTypes = new BTypesFromSymbols[int.type](int)
2323

tests/pos-with-compiler-cc/backend/jvm/BTypes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import scala.tools.asm
1414
* This representation is immutable and independent of the compiler data structures, hence it can
1515
* be queried by concurrent threads.
1616
*/
17-
abstract class BTypes extends caps.Pure {
17+
abstract class BTypes extends Pure {
1818

1919
val int: DottyBackendInterface
2020
import int.given
@@ -47,7 +47,7 @@ abstract class BTypes extends caps.Pure {
4747
* A BType is either a primitve type, a ClassBType, an ArrayBType of one of these, or a MethodType
4848
* referring to BTypes.
4949
*/
50-
/*sealed*/ trait BType extends caps.Pure { // Not sealed for now due to SI-8546
50+
/*sealed*/ trait BType extends Pure { // Not sealed for now due to SI-8546
5151
final override def toString: String = this match {
5252
case UNIT => "V"
5353
case BOOL => "Z"

tests/pos-with-compiler-cc/backend/sjs/ScopedVar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.backend.sjs
22

3-
class ScopedVar[A](init: A) extends caps.Pure {
3+
class ScopedVar[A](init: A) extends Pure {
44
import ScopedVar.Assignment
55

66
private[ScopedVar] var value = init

tests/pos-with-compiler-cc/dotc/ast/Positioned.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import annotation.internal.sharable
1515

1616
/** A base class for things that have positions (currently: modifiers and trees)
1717
*/
18-
abstract class Positioned(implicit @constructorOnly src: SourceFile) extends SrcPos, Product, Cloneable, caps.Pure {
18+
abstract class Positioned(implicit @constructorOnly src: SourceFile) extends SrcPos, Product, Cloneable, Pure {
1919
import Positioned.{ids, nextId, debugId}
2020

2121
private var mySpan: Span = _

tests/pos-with-compiler-cc/dotc/cc/CaptureSet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import annotation.retains
3939
* if the mapped function is either a bijection or if it is idempotent
4040
* on capture references (c.f. doc comment on `map` below).
4141
*/
42-
sealed abstract class CaptureSet extends Showable, caps.Pure:
42+
sealed abstract class CaptureSet extends Showable, Pure:
4343
import CaptureSet.*
4444

4545
/** The elements of this capture set. For capture variables,

tests/pos-with-compiler-cc/dotc/core/Annotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Annotations {
1717
if (tree.symbol.isConstructor) tree.symbol.owner
1818
else tree.tpe.typeSymbol
1919

20-
abstract class Annotation extends Showable, caps.Pure {
20+
abstract class Annotation extends Showable, Pure {
2121

2222
def tree(using Context): Tree
2323

tests/pos-with-compiler-cc/dotc/core/CheckRealizable.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import annotation.constructorOnly
1313
/** Realizability status */
1414
object CheckRealizable {
1515

16-
sealed abstract class Realizability(val msg: String) extends caps.Pure {
16+
sealed abstract class Realizability(val msg: String) extends Pure {
1717
def andAlso(other: => Realizability): Realizability =
1818
if (this == Realizable) other else this
1919
def mapError(f: Realizability -> Context ?-> Realizability)(using Context): Realizability =

tests/pos-with-compiler-cc/dotc/core/Denotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ object Denotations {
7676
/** A PreDenotation represents a group of single denotations or a single multi-denotation
7777
* It is used as an optimization to avoid forming MultiDenotations too eagerly.
7878
*/
79-
abstract class PreDenotation extends caps.Pure {
79+
abstract class PreDenotation extends Pure {
8080

8181
/** A denotation in the group exists */
8282
def exists: Boolean

tests/pos-with-compiler-cc/dotc/core/NameKinds.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ object NameKinds {
2323
@sharable private val uniqueNameKinds = util.HashMap[String, UniqueNameKind]()
2424

2525
/** A class for the info stored in a derived name */
26-
abstract class NameInfo extends caps.Pure {
26+
abstract class NameInfo extends Pure {
2727
def kind: NameKind
2828
def mkString(underlying: TermName): String
2929
def map(f: SimpleName => SimpleName): NameInfo = this
3030
}
3131

3232
/** An abstract base class of classes that define the kind of a derived name info */
33-
abstract class NameKind(val tag: Int) extends caps.Pure { self =>
33+
abstract class NameKind(val tag: Int) extends Pure { self =>
3434

3535
/** The info class defined by this kind */
3636
type ThisInfo <: Info

tests/pos-with-compiler-cc/dotc/core/Names.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object Names {
3232
* in a name table. A derived term name adds a tag, and possibly a number
3333
* or a further simple name to some other name.
3434
*/
35-
abstract class Name extends Designator, Showable, caps.Pure derives CanEqual {
35+
abstract class Name extends Designator, Showable, Pure derives CanEqual {
3636

3737
/** A type for names of the same kind as this name */
3838
type ThisName <: Name

tests/pos-with-compiler-cc/dotc/core/Phases.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ object Phases {
285285
final def isTyper(phase: Phase): Boolean = phase.id == typerPhase.id
286286
}
287287

288-
abstract class Phase extends caps.Pure {
288+
abstract class Phase extends Pure {
289289

290290
/** A name given to the `Phase` that can be used to debug the compiler. For
291291
* instance, it is possible to print trees after a given phase using:

tests/pos-with-compiler-cc/dotc/core/Scopes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ object Scopes {
6464
* or to delete them. These methods are provided by subclass
6565
* MutableScope.
6666
*/
67-
abstract class Scope extends printing.Showable, caps.Pure {
67+
abstract class Scope extends printing.Showable, Pure {
6868

6969
/** The last scope-entry from which all others are reachable via `prev` */
7070
private[dotc] def lastEntry: ScopeEntry | Null

tests/pos-with-compiler-cc/dotc/core/TypeErrors.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import ast.untpd
1515
import config.Printers.cyclicErrors
1616
import language.experimental.pureFunctions
1717

18-
abstract class TypeError(using creationContext: DetachedContext) extends Exception(""), caps.Pure:
18+
abstract class TypeError(using creationContext: DetachedContext) extends Exception(""), Pure:
1919

2020
/** Convert to message. This takes an additional Context, so that we
2121
* use the context when the message is first produced, i.e. when the TypeError

tests/pos-with-compiler-cc/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ object Types {
9191
*
9292
* Note: please keep in sync with copy in `docs/docs/internals/type-system.md`.
9393
*/
94-
abstract class Type extends Hashable, printing.Showable, caps.Pure {
94+
abstract class Type extends Hashable, printing.Showable, Pure {
9595

9696
// ----- Tests -----------------------------------------------------
9797

tests/pos-with-compiler-cc/dotc/core/classfile/ClassfileParser.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import annotation.retains
2828

2929
object ClassfileParser {
3030
/** Marker trait for unpicklers that can be embedded in classfiles. */
31-
trait Embedded extends caps.Pure
31+
trait Embedded extends Pure
3232

3333
/** Indicate that there is nothing to unpickle and the corresponding symbols can
3434
* be invalidated. */

tests/pos-with-compiler-cc/dotc/interactive/Completion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ object Completion {
538538
/** Temporary data structure representing denotations with the same name introduced in a given scope
539539
* as a member of a type, by a local definition or by an import clause
540540
*/
541-
private case class ScopedDenotations(denots: Seq[SingleDenotation], ctx: DetachedContext) extends caps.Pure
541+
private case class ScopedDenotations(denots: Seq[SingleDenotation], ctx: DetachedContext) extends Pure
542542

543543
/**
544544
* The completion mode: defines what kinds of symbols should be included in the completion

tests/pos-with-compiler-cc/dotc/parsing/Scanners.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ object Scanners {
15541554
* InBraces a pair of braces { ... }
15551555
* Indented a pair of <indent> ... <outdent> tokens
15561556
*/
1557-
abstract class Region(val closedBy: Token) extends caps.Pure:
1557+
abstract class Region(val closedBy: Token) extends Pure:
15581558

15591559
/** The region enclosing this one, or `null` for the outermost region */
15601560
def outer: Region | Null

tests/pos-with-compiler-cc/dotc/printing/Highlighting.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object Highlighting {
2828
else mod + super.show
2929
}
3030

31-
case class HighlightBuffer(hl: Highlight)(using DetachedContext) extends caps.Pure {
31+
case class HighlightBuffer(hl: Highlight)(using DetachedContext) extends Pure {
3232
private val buffer = new mutable.ListBuffer[String]
3333

3434
buffer += hl.show

tests/pos-with-compiler-cc/dotc/printing/Printer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import scala.annotation.internal.sharable
1515

1616
/** The base class of all printers
1717
*/
18-
abstract class Printer extends caps.Pure {
18+
abstract class Printer extends Pure {
1919

2020
private var prec: Precedence = GlobalPrec
2121

tests/pos-with-compiler-cc/dotc/profile/AsyncHelper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import java.util.concurrent.atomic.AtomicInteger
99
import dotty.tools.dotc.core.Phases.Phase
1010
import dotty.tools.dotc.core.Contexts._
1111

12-
sealed trait AsyncHelper extends caps.Pure {
12+
sealed trait AsyncHelper extends Pure {
1313

1414
def newUnboundedQueueFixedThreadPool
1515
(nThreads: Int,

tests/pos-with-compiler-cc/dotc/profile/Profiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ case class ProfileRange(start: ProfileSnap, end:ProfileSnap, phase:Phase, purpos
6565
def retainedHeapMB: Double = toMegaBytes(end.heapBytes - start.heapBytes)
6666
}
6767

68-
sealed trait Profiler extends caps.Pure {
68+
sealed trait Profiler extends Pure {
6969

7070
def finished(): Unit
7171

tests/pos-with-compiler-cc/dotc/transform/CapturedVars.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
3434
override def initContext(ctx: FreshContext): Unit =
3535
Captured = ctx.addLocation(util.ReadOnlySet.empty)
3636

37-
private class RefInfo(using DetachedContext) extends caps.Pure {
37+
private class RefInfo(using DetachedContext) extends Pure {
3838
/** The classes for which a Ref type exists. */
3939
val refClassKeys: collection.Set[Symbol] =
4040
defn.ScalaNumericValueClasses() `union` Set(defn.BooleanClass, defn.ObjectClass)

tests/pos-with-compiler-cc/dotc/transform/CrossStageSafety.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import scala.annotation.constructorOnly
4848
* }
4949
*
5050
*/
51-
class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWithStages(ictx), Checking, caps.Pure {
51+
class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWithStages(ictx), Checking, Pure {
5252
import tpd._
5353

5454
private val InAnnotation = Property.Key[Unit]()
@@ -278,7 +278,7 @@ class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWi
278278
object CrossStageSafety {
279279
import tpd._
280280

281-
class QuoteTypeTags(span: Span)(using DetachedContext) extends caps.Pure {
281+
class QuoteTypeTags(span: Span)(using DetachedContext) extends Pure {
282282

283283
private val tags = collection.mutable.LinkedHashMap.empty[Symbol, TypeDef]
284284

tests/pos-with-compiler-cc/dotc/transform/ForwardDepChecks.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ object ForwardDepChecks:
2626

2727
/** A class to help in forward reference checking */
2828
class LevelInfo(val outer: OptLevelInfo, val owner: Symbol, stats: List[Tree])(using DetachedContext)
29-
extends OptLevelInfo, caps.Pure {
29+
extends OptLevelInfo, Pure {
3030
override val levelAndIndex: LevelAndIndex =
3131
stats.foldLeft(outer.levelAndIndex, 0) {(mi, stat) =>
3232
val (m, idx) = mi

tests/pos-with-compiler-cc/dotc/transform/MacroTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Contexts._
99
/** A base class for transforms.
1010
* A transform contains a compiler phase which applies a tree transformer.
1111
*/
12-
abstract class MacroTransform extends Phase, caps.Pure {
12+
abstract class MacroTransform extends Phase, Pure {
1313

1414
import ast.tpd._
1515

tests/pos-with-compiler-cc/dotc/transform/MegaPhase.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object MegaPhase {
2828
* - Other: to prepape/transform a tree that does not have a specific prepare/transform
2929
* method pair.
3030
*/
31-
abstract class MiniPhase extends Phase, caps.Pure {
31+
abstract class MiniPhase extends Phase, Pure {
3232

3333
private[MegaPhase] var superPhase: MegaPhase = _
3434
private[MegaPhase] var idxInGroup: Int = _

tests/pos-with-compiler-cc/dotc/transform/OverridingPairs.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object OverridingPairs:
2222
/** The cursor class
2323
* @param base the base class that contains the overriding pairs
2424
*/
25-
class Cursor(base: Symbol)(using DetachedContext) extends caps.Pure:
25+
class Cursor(base: Symbol)(using DetachedContext) extends Pure:
2626

2727
private val self = base.thisType
2828

tests/pos-with-compiler-cc/dotc/transform/PatternMatcher.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ object PatternMatcher {
145145
private var nxId = 0
146146

147147
/** The different kinds of plans */
148-
sealed abstract class Plan extends caps.Pure { val id: Int = nxId; nxId += 1 }
148+
sealed abstract class Plan extends Pure { val id: Int = nxId; nxId += 1 }
149149

150150
case class TestPlan(test: Test, var scrutinee: Tree, span: Span,
151151
var onSuccess: Plan) extends Plan {

tests/pos-with-compiler-cc/dotc/transform/SymUtils.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,6 @@ object SymUtils:
363363
self.hasAnnotation(defn.ExperimentalAnnot)
364364
|| isDefaultArgumentOfExperimentalMethod
365365
|| (!self.is(Package) && self.owner.isInExperimentalScope)
366-
|| self.topLevelClass.ownersIterator.exists(p =>
367-
p.is(Package) && p.owner.isRoot && p.name == tpnme.dotty)
368366

369367
/** The declared self type of this class, as seen from `site`, stripping
370368
* all refinements for opaque types.

0 commit comments

Comments
 (0)