diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index e5ab8f65f55b..5bcc139326f9 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -136,16 +136,21 @@ object Feature: if !isExperimentalEnabled then report.error(em"Experimental $which may only be used with a nightly or snapshot version of the compiler$note", srcPos) + private def ccException(sym: Symbol)(using Context): Boolean = + ccEnabled && defn.ccExperimental.contains(sym) + def checkExperimentalDef(sym: Symbol, srcPos: SrcPos)(using Context) = if !isExperimentalEnabled then - val symMsg = - if sym.hasAnnotation(defn.ExperimentalAnnot) then - i"$sym is marked @experimental" - else if sym.owner.hasAnnotation(defn.ExperimentalAnnot) then - i"${sym.owner} is marked @experimental" - else - i"$sym inherits @experimental" - report.error(em"$symMsg and therefore may only be used in an experimental scope.", srcPos) + val experimentalSym = + if sym.hasAnnotation(defn.ExperimentalAnnot) then sym + else if sym.owner.hasAnnotation(defn.ExperimentalAnnot) then sym.owner + else NoSymbol + if !ccException(experimentalSym) then + val symMsg = + if experimentalSym.exists + then i"$experimentalSym is marked @experimental" + else i"$sym inherits @experimental" + report.error(em"$symMsg and therefore may only be used in an experimental scope.", srcPos) /** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */ def checkExperimentalSettings(using Context): Unit = diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 027aec16e9a3..3d11ad80733e 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -976,6 +976,8 @@ class Definitions { @tu lazy val Caps_unsafeBoxFunArg: Symbol = CapsUnsafeModule.requiredMethod("unsafeBoxFunArg") @tu lazy val Caps_SealedAnnot: ClassSymbol = requiredClass("scala.caps.Sealed") + @tu lazy val PureClass: Symbol = requiredClass("scala.Pure") + // Annotation base classes @tu lazy val AnnotationClass: ClassSymbol = requiredClass("scala.annotation.Annotation") @tu lazy val StaticAnnotationClass: ClassSymbol = requiredClass("scala.annotation.StaticAnnotation") @@ -1944,6 +1946,14 @@ class Definitions { case Some(pkgs) => pkgs.contains(sym.owner) case none => false + /** Experimental definitions that can nevertheless be accessed from a stable + * compiler if capture checking is enabled. + */ + @tu lazy val ccExperimental: Set[Symbol] = Set( + CapsModule, CapsModule.moduleClass, PureClass, + CapabilityAnnot, RequiresCapabilityAnnot, + RetainsAnnot, RetainsByNameAnnot, WithPureFunsAnnot) + // ----- primitive value class machinery ------------------------------------------ class PerRun[T](generate: Context ?=> T) { @@ -2041,15 +2051,17 @@ class Definitions { def isValueSubClass(sym1: Symbol, sym2: Symbol): Boolean = valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0 - @tu lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] = - SimpleIdentityMap.empty[Symbol] - .updated(AnyClass, ObjectClass) - .updated(MatchableClass, ObjectClass) - .updated(AnyValClass, ObjectClass) - .updated(SingletonClass, ObjectClass) - .updated(TupleClass, ProductClass) - .updated(NonEmptyTupleClass, ProductClass) - .updated(PairClass, ObjectClass) + @tu lazy val specialErasure: collection.Map[Symbol, ClassSymbol] = + val m = mutable.Map[Symbol, ClassSymbol]() + m(AnyClass) = ObjectClass + m(MatchableClass) = ObjectClass + m(PureClass) = ObjectClass + m(AnyValClass) = ObjectClass + m(SingletonClass) = ObjectClass + m(TupleClass) = ProductClass + m(NonEmptyTupleClass) = ProductClass + m(PairClass) = ObjectClass + m // ----- Initialization --------------------------------------------------- diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 9bcb3eca36bb..50e7e1847adf 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -410,7 +410,7 @@ object TypeErasure { val candidates = takeUntil(tp2superclasses)(!_.is(Trait)) // Candidates st "no other common superclass or trait derives from S" - // Also, drop `PairClass` since it is not valid after erasue + // Also, drop `PairClass` since it is not valid after erasure val minimums = candidates.filter { cand => cand != defn.PairClass && candidates.forall(x => !x.derivesFrom(cand) || x.eq(cand)) diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 981dd5f60aea..f068a48cdba4 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -190,12 +190,14 @@ class Erasure extends Phase with DenotTransformer { def assertErased(tp: Type, tree: tpd.Tree = tpd.EmptyTree)(using Context): Unit = { def isAllowed(cls: Symbol, sourceName: String) = tp.typeSymbol == cls && ctx.compilationUnit.source.file.name == sourceName - assert(isErasedType(tp) || - isAllowed(defn.ArrayClass, "Array.scala") || - isAllowed(defn.TupleClass, "Tuple.scala") || - isAllowed(defn.NonEmptyTupleClass, "Tuple.scala") || - isAllowed(defn.PairClass, "Tuple.scala"), - i"The type $tp - ${tp.toString} of class ${tp.getClass} of tree $tree : ${tree.tpe} / ${tree.getClass} is illegal after erasure, phase = ${ctx.phase.prev}") + assert( + isErasedType(tp) + || isAllowed(defn.ArrayClass, "Array.scala") + || isAllowed(defn.TupleClass, "Tuple.scala") + || isAllowed(defn.NonEmptyTupleClass, "Tuple.scala") + || isAllowed(defn.PairClass, "Tuple.scala") + || isAllowed(defn.PureClass, "Pure.scala"), + i"The type $tp - ${tp.toString} of class ${tp.getClass} of tree $tree : ${tree.tpe} / ${tree.getClass} is illegal after erasure, phase = ${ctx.phase.prev}") } } diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index 3fe05a45699e..d3a17334caf5 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -370,8 +370,6 @@ object SymUtils: self.hasAnnotation(defn.ExperimentalAnnot) || isDefaultArgumentOfExperimentalMethod || (!self.is(Package) && self.owner.isInExperimentalScope) - || self.topLevelClass.ownersIterator.exists(p => - p.is(Package) && p.owner.isRoot && p.name == tpnme.dotty) /** The declared self type of this class, as seen from `site`, stripping * all refinements for opaque types. diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index b2ab5332c3b2..2869f64f33d0 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -784,7 +784,9 @@ object Checking { for case imp @ Import(qual, selectors) <- trees do def isAllowedImport(sel: untpd.ImportSelector) = val name = Feature.experimental(sel.name) - name == Feature.scala2macros || name == Feature.erasedDefinitions + name == Feature.scala2macros + || name == Feature.erasedDefinitions + || name == Feature.captureChecking languageImport(qual) match case Some(nme.experimental) diff --git a/library/src/scala/Pure.scala b/library/src/scala/Pure.scala new file mode 100644 index 000000000000..f3f624cd40d0 --- /dev/null +++ b/library/src/scala/Pure.scala @@ -0,0 +1,9 @@ +package scala +import annotation.experimental + +/** A marker trait that declares that all inheriting classes are "pure" in the + * sense that their values retain no capabilities including capabilities needed + * to perform effects. This has formal meaning only under capture checking. + */ +@experimental trait Pure: + this: Pure => diff --git a/library/src/scala/caps.scala b/library/src/scala/caps.scala index 866e5dbd18cd..e4520d48354c 100644 --- a/library/src/scala/caps.scala +++ b/library/src/scala/caps.scala @@ -40,9 +40,3 @@ import annotation.experimental */ @deprecated("The Sealed annotation should not be directly used in source code.\nUse the `sealed` modifier on type parameters instead.") class Sealed extends annotation.Annotation - - /** Mixing in this trait forces a trait or class to be pure, i.e. - * have no capabilities retained in its self type. - */ - trait Pure: - this: Pure => diff --git a/tests/neg-custom-args/captures/selftype.scala b/tests/neg-custom-args/captures/selftype.scala index 21148f625a7a..f5d24fd2381f 100644 --- a/tests/neg-custom-args/captures/selftype.scala +++ b/tests/neg-custom-args/captures/selftype.scala @@ -1,4 +1,4 @@ -@annotation.experimental class C(x: () => Unit) extends caps.Pure // error +@annotation.experimental class C(x: () => Unit) extends Pure // error -@annotation.experimental class D(@annotation.constructorOnly x: () => Unit) extends caps.Pure // ok +@annotation.experimental class D(@annotation.constructorOnly x: () => Unit) extends Pure // ok diff --git a/tests/pos-custom-args/no-experimental/cc-experimental.scala b/tests/pos-custom-args/no-experimental/cc-experimental.scala new file mode 100644 index 000000000000..c4c1754fa21c --- /dev/null +++ b/tests/pos-custom-args/no-experimental/cc-experimental.scala @@ -0,0 +1,11 @@ +package scala.runtime + +import language.experimental.captureChecking + +object test: + type T = Pure + +class Foo extends Object, Pure: + val x: Pure = ??? + def foo() = () + diff --git a/tests/pos-custom-args/no-experimental/dotty-experimental.scala b/tests/pos-custom-args/no-experimental/dotty-experimental.scala index 72d16ddd9b15..ca2fa5ca9f74 100644 --- a/tests/pos-custom-args/no-experimental/dotty-experimental.scala +++ b/tests/pos-custom-args/no-experimental/dotty-experimental.scala @@ -1,4 +1,4 @@ -package dotty.tools +import language.experimental.captureChecking object test { val x = caps.cap diff --git a/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala b/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala index 6f83af540bea..3ab75bda787e 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/BCodeHelpers.scala @@ -209,7 +209,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { } } // end of trait BCPickles - trait BCInnerClassGen extends caps.Pure { + trait BCInnerClassGen extends Pure { def debugLevel = 3 // 0 -> no debug info; 1-> filename; 2-> lines; 3-> varnames diff --git a/tests/pos-with-compiler-cc/backend/jvm/BCodeIdiomatic.scala b/tests/pos-with-compiler-cc/backend/jvm/BCodeIdiomatic.scala index 5eb8d7a52aa2..2218adf6e18b 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/BCodeIdiomatic.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/BCodeIdiomatic.scala @@ -17,7 +17,7 @@ import dotty.tools.dotc.report * @version 1.0 * */ -trait BCodeIdiomatic extends caps.Pure { +trait BCodeIdiomatic extends Pure { val int: DottyBackendInterface final lazy val bTypes = new BTypesFromSymbols[int.type](int) diff --git a/tests/pos-with-compiler-cc/backend/jvm/BTypes.scala b/tests/pos-with-compiler-cc/backend/jvm/BTypes.scala index dda85e2d5616..f9a3a3aae105 100644 --- a/tests/pos-with-compiler-cc/backend/jvm/BTypes.scala +++ b/tests/pos-with-compiler-cc/backend/jvm/BTypes.scala @@ -14,7 +14,7 @@ import scala.tools.asm * This representation is immutable and independent of the compiler data structures, hence it can * be queried by concurrent threads. */ -abstract class BTypes extends caps.Pure { +abstract class BTypes extends Pure { val int: DottyBackendInterface import int.given @@ -47,7 +47,7 @@ abstract class BTypes extends caps.Pure { * A BType is either a primitve type, a ClassBType, an ArrayBType of one of these, or a MethodType * referring to BTypes. */ - /*sealed*/ trait BType extends caps.Pure { // Not sealed for now due to SI-8546 + /*sealed*/ trait BType extends Pure { // Not sealed for now due to SI-8546 final override def toString: String = this match { case UNIT => "V" case BOOL => "Z" diff --git a/tests/pos-with-compiler-cc/backend/sjs/ScopedVar.scala b/tests/pos-with-compiler-cc/backend/sjs/ScopedVar.scala index 21462929833c..af7570a6edca 100644 --- a/tests/pos-with-compiler-cc/backend/sjs/ScopedVar.scala +++ b/tests/pos-with-compiler-cc/backend/sjs/ScopedVar.scala @@ -1,6 +1,6 @@ package dotty.tools.backend.sjs -class ScopedVar[A](init: A) extends caps.Pure { +class ScopedVar[A](init: A) extends Pure { import ScopedVar.Assignment private[ScopedVar] var value = init diff --git a/tests/pos-with-compiler-cc/dotc/ast/Positioned.scala b/tests/pos-with-compiler-cc/dotc/ast/Positioned.scala index fd30d441a6ee..7b558c65e425 100644 --- a/tests/pos-with-compiler-cc/dotc/ast/Positioned.scala +++ b/tests/pos-with-compiler-cc/dotc/ast/Positioned.scala @@ -15,7 +15,7 @@ import annotation.internal.sharable /** A base class for things that have positions (currently: modifiers and trees) */ -abstract class Positioned(implicit @constructorOnly src: SourceFile) extends SrcPos, Product, Cloneable, caps.Pure { +abstract class Positioned(implicit @constructorOnly src: SourceFile) extends SrcPos, Product, Cloneable, Pure { import Positioned.{ids, nextId, debugId} private var mySpan: Span = _ diff --git a/tests/pos-with-compiler-cc/dotc/cc/CaptureSet.scala b/tests/pos-with-compiler-cc/dotc/cc/CaptureSet.scala index c31bcb76c2c7..2072b43089fb 100644 --- a/tests/pos-with-compiler-cc/dotc/cc/CaptureSet.scala +++ b/tests/pos-with-compiler-cc/dotc/cc/CaptureSet.scala @@ -39,7 +39,7 @@ import annotation.retains * if the mapped function is either a bijection or if it is idempotent * on capture references (c.f. doc comment on `map` below). */ -sealed abstract class CaptureSet extends Showable, caps.Pure: +sealed abstract class CaptureSet extends Showable, Pure: import CaptureSet.* /** The elements of this capture set. For capture variables, diff --git a/tests/pos-with-compiler-cc/dotc/core/Annotations.scala b/tests/pos-with-compiler-cc/dotc/core/Annotations.scala index f307d4a36697..2061bddb9e8a 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Annotations.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Annotations.scala @@ -17,7 +17,7 @@ object Annotations { if (tree.symbol.isConstructor) tree.symbol.owner else tree.tpe.typeSymbol - abstract class Annotation extends Showable, caps.Pure { + abstract class Annotation extends Showable, Pure { def tree(using Context): Tree diff --git a/tests/pos-with-compiler-cc/dotc/core/CheckRealizable.scala b/tests/pos-with-compiler-cc/dotc/core/CheckRealizable.scala index 47fa84b467d8..d166cec11573 100644 --- a/tests/pos-with-compiler-cc/dotc/core/CheckRealizable.scala +++ b/tests/pos-with-compiler-cc/dotc/core/CheckRealizable.scala @@ -13,7 +13,7 @@ import annotation.constructorOnly /** Realizability status */ object CheckRealizable { - sealed abstract class Realizability(val msg: String) extends caps.Pure { + sealed abstract class Realizability(val msg: String) extends Pure { def andAlso(other: => Realizability): Realizability = if (this == Realizable) other else this def mapError(f: Realizability -> Context ?-> Realizability)(using Context): Realizability = diff --git a/tests/pos-with-compiler-cc/dotc/core/Denotations.scala b/tests/pos-with-compiler-cc/dotc/core/Denotations.scala index 246e359f0597..9db285975a0a 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Denotations.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Denotations.scala @@ -76,7 +76,7 @@ object Denotations { /** A PreDenotation represents a group of single denotations or a single multi-denotation * It is used as an optimization to avoid forming MultiDenotations too eagerly. */ - abstract class PreDenotation extends caps.Pure { + abstract class PreDenotation extends Pure { /** A denotation in the group exists */ def exists: Boolean diff --git a/tests/pos-with-compiler-cc/dotc/core/NameKinds.scala b/tests/pos-with-compiler-cc/dotc/core/NameKinds.scala index 2ed9a17b9f7e..07c69afdaf24 100644 --- a/tests/pos-with-compiler-cc/dotc/core/NameKinds.scala +++ b/tests/pos-with-compiler-cc/dotc/core/NameKinds.scala @@ -23,14 +23,14 @@ object NameKinds { @sharable private val uniqueNameKinds = util.HashMap[String, UniqueNameKind]() /** A class for the info stored in a derived name */ - abstract class NameInfo extends caps.Pure { + abstract class NameInfo extends Pure { def kind: NameKind def mkString(underlying: TermName): String def map(f: SimpleName => SimpleName): NameInfo = this } /** An abstract base class of classes that define the kind of a derived name info */ - abstract class NameKind(val tag: Int) extends caps.Pure { self => + abstract class NameKind(val tag: Int) extends Pure { self => /** The info class defined by this kind */ type ThisInfo <: Info diff --git a/tests/pos-with-compiler-cc/dotc/core/Names.scala b/tests/pos-with-compiler-cc/dotc/core/Names.scala index e6ea66f4025b..d1eba69c57a0 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Names.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Names.scala @@ -32,7 +32,7 @@ object Names { * in a name table. A derived term name adds a tag, and possibly a number * or a further simple name to some other name. */ - abstract class Name extends Designator, Showable, caps.Pure derives CanEqual { + abstract class Name extends Designator, Showable, Pure derives CanEqual { /** A type for names of the same kind as this name */ type ThisName <: Name diff --git a/tests/pos-with-compiler-cc/dotc/core/Phases.scala b/tests/pos-with-compiler-cc/dotc/core/Phases.scala index 3744b1f21122..809e24b1e6ef 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Phases.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Phases.scala @@ -285,7 +285,7 @@ object Phases { final def isTyper(phase: Phase): Boolean = phase.id == typerPhase.id } - abstract class Phase extends caps.Pure { + abstract class Phase extends Pure { /** A name given to the `Phase` that can be used to debug the compiler. For * instance, it is possible to print trees after a given phase using: diff --git a/tests/pos-with-compiler-cc/dotc/core/Scopes.scala b/tests/pos-with-compiler-cc/dotc/core/Scopes.scala index 7ab68ddf78a2..f5a108a13c19 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Scopes.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Scopes.scala @@ -60,7 +60,7 @@ object Scopes { * or to delete them. These methods are provided by subclass * MutableScope. */ - abstract class Scope extends printing.Showable, caps.Pure { + abstract class Scope extends printing.Showable, Pure { /** The last scope-entry from which all others are reachable via `prev` */ private[dotc] def lastEntry: ScopeEntry | Null diff --git a/tests/pos-with-compiler-cc/dotc/core/TypeErrors.scala b/tests/pos-with-compiler-cc/dotc/core/TypeErrors.scala index 24f281b36785..43eec81467d4 100644 --- a/tests/pos-with-compiler-cc/dotc/core/TypeErrors.scala +++ b/tests/pos-with-compiler-cc/dotc/core/TypeErrors.scala @@ -15,7 +15,7 @@ import ast.untpd import config.Printers.cyclicErrors import language.experimental.pureFunctions -abstract class TypeError(using creationContext: DetachedContext) extends Exception(""), caps.Pure: +abstract class TypeError(using creationContext: DetachedContext) extends Exception(""), Pure: /** Convert to message. This takes an additional Context, so that we * use the context when the message is first produced, i.e. when the TypeError diff --git a/tests/pos-with-compiler-cc/dotc/core/Types.scala b/tests/pos-with-compiler-cc/dotc/core/Types.scala index e4b30888a5dc..90f2e322ac1c 100644 --- a/tests/pos-with-compiler-cc/dotc/core/Types.scala +++ b/tests/pos-with-compiler-cc/dotc/core/Types.scala @@ -91,7 +91,7 @@ object Types { * * Note: please keep in sync with copy in `docs/docs/internals/type-system.md`. */ - abstract class Type extends Hashable, printing.Showable, caps.Pure { + abstract class Type extends Hashable, printing.Showable, Pure { // ----- Tests ----------------------------------------------------- diff --git a/tests/pos-with-compiler-cc/dotc/core/classfile/ClassfileParser.scala b/tests/pos-with-compiler-cc/dotc/core/classfile/ClassfileParser.scala index 7e369dd6d9cc..21140f437114 100644 --- a/tests/pos-with-compiler-cc/dotc/core/classfile/ClassfileParser.scala +++ b/tests/pos-with-compiler-cc/dotc/core/classfile/ClassfileParser.scala @@ -28,7 +28,7 @@ import annotation.retains object ClassfileParser { /** Marker trait for unpicklers that can be embedded in classfiles. */ - trait Embedded extends caps.Pure + trait Embedded extends Pure /** Indicate that there is nothing to unpickle and the corresponding symbols can * be invalidated. */ diff --git a/tests/pos-with-compiler-cc/dotc/interactive/Completion.scala b/tests/pos-with-compiler-cc/dotc/interactive/Completion.scala index 6a3ac439ef5f..ead3e6c413c9 100644 --- a/tests/pos-with-compiler-cc/dotc/interactive/Completion.scala +++ b/tests/pos-with-compiler-cc/dotc/interactive/Completion.scala @@ -538,7 +538,7 @@ object Completion { /** Temporary data structure representing denotations with the same name introduced in a given scope * as a member of a type, by a local definition or by an import clause */ - private case class ScopedDenotations(denots: Seq[SingleDenotation], ctx: DetachedContext) extends caps.Pure + private case class ScopedDenotations(denots: Seq[SingleDenotation], ctx: DetachedContext) extends Pure /** * The completion mode: defines what kinds of symbols should be included in the completion diff --git a/tests/pos-with-compiler-cc/dotc/parsing/Scanners.scala b/tests/pos-with-compiler-cc/dotc/parsing/Scanners.scala index 90c11e4430ec..737a37b2d4ce 100644 --- a/tests/pos-with-compiler-cc/dotc/parsing/Scanners.scala +++ b/tests/pos-with-compiler-cc/dotc/parsing/Scanners.scala @@ -1554,7 +1554,7 @@ object Scanners { * InBraces a pair of braces { ... } * Indented a pair of ... tokens */ - abstract class Region(val closedBy: Token) extends caps.Pure: + abstract class Region(val closedBy: Token) extends Pure: /** The region enclosing this one, or `null` for the outermost region */ def outer: Region | Null diff --git a/tests/pos-with-compiler-cc/dotc/printing/Highlighting.scala b/tests/pos-with-compiler-cc/dotc/printing/Highlighting.scala index b5fbbfdf1b3a..018bf65b851d 100644 --- a/tests/pos-with-compiler-cc/dotc/printing/Highlighting.scala +++ b/tests/pos-with-compiler-cc/dotc/printing/Highlighting.scala @@ -28,7 +28,7 @@ object Highlighting { else mod + super.show } - case class HighlightBuffer(hl: Highlight)(using DetachedContext) extends caps.Pure { + case class HighlightBuffer(hl: Highlight)(using DetachedContext) extends Pure { private val buffer = new mutable.ListBuffer[String] buffer += hl.show diff --git a/tests/pos-with-compiler-cc/dotc/printing/Printer.scala b/tests/pos-with-compiler-cc/dotc/printing/Printer.scala index 25429c8fc01b..b9da874cf9ae 100644 --- a/tests/pos-with-compiler-cc/dotc/printing/Printer.scala +++ b/tests/pos-with-compiler-cc/dotc/printing/Printer.scala @@ -15,7 +15,7 @@ import scala.annotation.internal.sharable /** The base class of all printers */ -abstract class Printer extends caps.Pure { +abstract class Printer extends Pure { private var prec: Precedence = GlobalPrec diff --git a/tests/pos-with-compiler-cc/dotc/profile/AsyncHelper.scala b/tests/pos-with-compiler-cc/dotc/profile/AsyncHelper.scala index deb8e172a780..1c52e47ade7e 100644 --- a/tests/pos-with-compiler-cc/dotc/profile/AsyncHelper.scala +++ b/tests/pos-with-compiler-cc/dotc/profile/AsyncHelper.scala @@ -9,7 +9,7 @@ import java.util.concurrent.atomic.AtomicInteger import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.core.Contexts._ -sealed trait AsyncHelper extends caps.Pure { +sealed trait AsyncHelper extends Pure { def newUnboundedQueueFixedThreadPool (nThreads: Int, diff --git a/tests/pos-with-compiler-cc/dotc/profile/Profiler.scala b/tests/pos-with-compiler-cc/dotc/profile/Profiler.scala index bb4f9ffe226b..35c98ac2a0d2 100644 --- a/tests/pos-with-compiler-cc/dotc/profile/Profiler.scala +++ b/tests/pos-with-compiler-cc/dotc/profile/Profiler.scala @@ -65,7 +65,7 @@ case class ProfileRange(start: ProfileSnap, end:ProfileSnap, phase:Phase, purpos def retainedHeapMB: Double = toMegaBytes(end.heapBytes - start.heapBytes) } -sealed trait Profiler extends caps.Pure { +sealed trait Profiler extends Pure { def finished(): Unit diff --git a/tests/pos-with-compiler-cc/dotc/transform/CapturedVars.scala b/tests/pos-with-compiler-cc/dotc/transform/CapturedVars.scala index 3aaf4a23ec1c..f3b3421b8356 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/CapturedVars.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/CapturedVars.scala @@ -34,7 +34,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer: override def initContext(ctx: FreshContext): Unit = Captured = ctx.addLocation(util.ReadOnlySet.empty) - private class RefInfo(using DetachedContext) extends caps.Pure { + private class RefInfo(using DetachedContext) extends Pure { /** The classes for which a Ref type exists. */ val refClassKeys: collection.Set[Symbol] = defn.ScalaNumericValueClasses() `union` Set(defn.BooleanClass, defn.ObjectClass) diff --git a/tests/pos-with-compiler-cc/dotc/transform/CrossStageSafety.scala b/tests/pos-with-compiler-cc/dotc/transform/CrossStageSafety.scala index ca00c87161ef..eba5e0071c01 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/CrossStageSafety.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/CrossStageSafety.scala @@ -48,7 +48,7 @@ import scala.annotation.constructorOnly * } * */ -class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWithStages(ictx), Checking, caps.Pure { +class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWithStages(ictx), Checking, Pure { import tpd._ private val InAnnotation = Property.Key[Unit]() @@ -278,7 +278,7 @@ class CrossStageSafety(@constructorOnly ictx: DetachedContext) extends TreeMapWi object CrossStageSafety { import tpd._ - class QuoteTypeTags(span: Span)(using DetachedContext) extends caps.Pure { + class QuoteTypeTags(span: Span)(using DetachedContext) extends Pure { private val tags = collection.mutable.LinkedHashMap.empty[Symbol, TypeDef] diff --git a/tests/pos-with-compiler-cc/dotc/transform/ForwardDepChecks.scala b/tests/pos-with-compiler-cc/dotc/transform/ForwardDepChecks.scala index ada633c04626..8fa0956bed89 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/ForwardDepChecks.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/ForwardDepChecks.scala @@ -26,7 +26,7 @@ object ForwardDepChecks: /** A class to help in forward reference checking */ class LevelInfo(val outer: OptLevelInfo, val owner: Symbol, stats: List[Tree])(using DetachedContext) - extends OptLevelInfo, caps.Pure { + extends OptLevelInfo, Pure { override val levelAndIndex: LevelAndIndex = stats.foldLeft(outer.levelAndIndex, 0) {(mi, stat) => val (m, idx) = mi diff --git a/tests/pos-with-compiler-cc/dotc/transform/MacroTransform.scala b/tests/pos-with-compiler-cc/dotc/transform/MacroTransform.scala index bff0e8340c0b..14ccdc5c6f86 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/MacroTransform.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/MacroTransform.scala @@ -9,7 +9,7 @@ import Contexts._ /** A base class for transforms. * A transform contains a compiler phase which applies a tree transformer. */ -abstract class MacroTransform extends Phase, caps.Pure { +abstract class MacroTransform extends Phase, Pure { import ast.tpd._ diff --git a/tests/pos-with-compiler-cc/dotc/transform/MegaPhase.scala b/tests/pos-with-compiler-cc/dotc/transform/MegaPhase.scala index 2543a89af4d7..14dd7f17d58a 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/MegaPhase.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/MegaPhase.scala @@ -28,7 +28,7 @@ object MegaPhase { * - Other: to prepape/transform a tree that does not have a specific prepare/transform * method pair. */ - abstract class MiniPhase extends Phase, caps.Pure { + abstract class MiniPhase extends Phase, Pure { private[MegaPhase] var superPhase: MegaPhase = _ private[MegaPhase] var idxInGroup: Int = _ diff --git a/tests/pos-with-compiler-cc/dotc/transform/OverridingPairs.scala b/tests/pos-with-compiler-cc/dotc/transform/OverridingPairs.scala index 5db2872e73e5..9e02b291b14e 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/OverridingPairs.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/OverridingPairs.scala @@ -22,7 +22,7 @@ object OverridingPairs: /** The cursor class * @param base the base class that contains the overriding pairs */ - class Cursor(base: Symbol)(using DetachedContext) extends caps.Pure: + class Cursor(base: Symbol)(using DetachedContext) extends Pure: private val self = base.thisType diff --git a/tests/pos-with-compiler-cc/dotc/transform/PatternMatcher.scala b/tests/pos-with-compiler-cc/dotc/transform/PatternMatcher.scala index a93545aec606..b1b268634736 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/PatternMatcher.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/PatternMatcher.scala @@ -145,7 +145,7 @@ object PatternMatcher { private var nxId = 0 /** The different kinds of plans */ - sealed abstract class Plan extends caps.Pure { val id: Int = nxId; nxId += 1 } + sealed abstract class Plan extends Pure { val id: Int = nxId; nxId += 1 } case class TestPlan(test: Test, var scrutinee: Tree, span: Span, var onSuccess: Plan) extends Plan { diff --git a/tests/pos-with-compiler-cc/dotc/transform/SymUtils.scala b/tests/pos-with-compiler-cc/dotc/transform/SymUtils.scala index 6010fe2a2a44..0a6fa9217303 100644 --- a/tests/pos-with-compiler-cc/dotc/transform/SymUtils.scala +++ b/tests/pos-with-compiler-cc/dotc/transform/SymUtils.scala @@ -363,8 +363,6 @@ object SymUtils: self.hasAnnotation(defn.ExperimentalAnnot) || isDefaultArgumentOfExperimentalMethod || (!self.is(Package) && self.owner.isInExperimentalScope) - || self.topLevelClass.ownersIterator.exists(p => - p.is(Package) && p.owner.isRoot && p.name == tpnme.dotty) /** The declared self type of this class, as seen from `site`, stripping * all refinements for opaque types. diff --git a/tests/pos-with-compiler-cc/dotc/typer/Implicits.scala b/tests/pos-with-compiler-cc/dotc/typer/Implicits.scala index 6034b10bf6f3..1f7286b02b5a 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/Implicits.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/Implicits.scala @@ -84,7 +84,7 @@ object Implicits: /** A common base class of contextual implicits and of-type implicits which * represents a set of references to implicit definitions. */ - abstract class ImplicitRefs(initctx: DetachedContext) extends caps.Pure { + abstract class ImplicitRefs(initctx: DetachedContext) extends Pure { val irefCtx: DetachedContext = if (initctx eq NoContext) initctx else initctx.retractMode(Mode.ImplicitsEnabled).detach protected given Context = irefCtx @@ -1651,7 +1651,7 @@ end Implicits * recursive references and emit a complete implicit dictionary when the outermost search * is complete. */ -abstract class SearchHistory extends caps.Pure: +abstract class SearchHistory extends Pure: val root: SearchRoot /** Does this search history contain any by name implicit arguments. */ val byname: Boolean @@ -1869,7 +1869,7 @@ final class SearchRoot extends SearchHistory: end SearchRoot /** A set of term references where equality is =:= */ -sealed class TermRefSet(using DetachedContext) extends caps.Pure: +sealed class TermRefSet(using DetachedContext) extends Pure: private val elemsMap = new util.HashMap[TermSymbol, Type | List[Type]] private val elemsBuf = new mutable.ListBuffer[TermSymbol] diff --git a/tests/pos-with-compiler-cc/dotc/typer/ImportInfo.scala b/tests/pos-with-compiler-cc/dotc/typer/ImportInfo.scala index 3c817f054ac6..8f4ab5de30cb 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/ImportInfo.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/ImportInfo.scala @@ -53,7 +53,7 @@ object ImportInfo { class ImportInfo(symf: Context ?-> Symbol, val selectors: List[untpd.ImportSelector], val qualifier: untpd.Tree, - val isRootImport: Boolean = false) extends Showable, caps.Pure { + val isRootImport: Boolean = false) extends Showable, Pure { private def symNameOpt = qualifier match { case ref: untpd.RefTree => Some(ref.name.asTermName) diff --git a/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala b/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala index 77fd2c1d6d66..285f9b983cb4 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/ProtoTypes.scala @@ -123,7 +123,7 @@ object ProtoTypes { } /** A trait for prototypes that match all types */ - trait MatchAlways extends ProtoType, caps.Pure { + trait MatchAlways extends ProtoType, Pure { def isMatchedBy(tp1: Type, keepConstraint: Boolean)(using Context): Boolean = true def map(tm: TypeMap @retains(caps.cap))(using Context): ProtoType = this def fold[T](x: T, ta: TypeAccumulator[T] @retains(caps.cap))(using Context): T = x @@ -131,7 +131,7 @@ object ProtoTypes { } /** A class marking ignored prototypes that can be revealed by `deepenProto` */ - abstract case class IgnoredProto(ignored: Type) extends CachedGroundType, MatchAlways, caps.Pure: + abstract case class IgnoredProto(ignored: Type) extends CachedGroundType, MatchAlways, Pure: private var myWasDeepened = false override def revealIgnored = ignored override def deepenProto(using Context): Type = @@ -165,7 +165,7 @@ object ProtoTypes { * [ ].name: proto */ abstract case class SelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean) - extends CachedProxyType, ProtoType, ValueTypeOrProto, caps.Pure { + extends CachedProxyType, ProtoType, ValueTypeOrProto, Pure { /** Is the set of members of this type unknown, in the sense that we * cannot compute a non-trivial upper approximation? This is the case if: @@ -575,7 +575,7 @@ object ProtoTypes { * []: argType => resultType */ abstract case class ViewProto(argType: Type, resType: Type) - extends CachedGroundType, ApplyingProto, caps.Pure { + extends CachedGroundType, ApplyingProto, Pure { override def resultType(using Context): Type = resType diff --git a/tests/pos-with-compiler-cc/dotc/typer/Synthesizer.scala b/tests/pos-with-compiler-cc/dotc/typer/Synthesizer.scala index 7bc9619922db..6ead3134235a 100644 --- a/tests/pos-with-compiler-cc/dotc/typer/Synthesizer.scala +++ b/tests/pos-with-compiler-cc/dotc/typer/Synthesizer.scala @@ -596,7 +596,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): case JavaArrayType(elemTp) => defn.ArrayOf(escapeJavaArray(elemTp)) case _ => tp - private enum ManifestKind extends caps.Pure: // !cc! should all enums be Pure? + private enum ManifestKind extends Pure: // !cc! should all enums be Pure? case Full, Opt, Clss /** The kind that should be used for an array element, if we are `OptManifest` then this diff --git a/tests/pos-with-compiler-cc/dotc/util/ReadOnlyMap.scala b/tests/pos-with-compiler-cc/dotc/util/ReadOnlyMap.scala index d24a9ab3ddb2..dbef59d6dee7 100644 --- a/tests/pos-with-compiler-cc/dotc/util/ReadOnlyMap.scala +++ b/tests/pos-with-compiler-cc/dotc/util/ReadOnlyMap.scala @@ -3,7 +3,7 @@ package dotc.util /** A class for the reading part of mutable or immutable maps. */ -abstract class ReadOnlyMap[Key, Value] extends caps.Pure: +abstract class ReadOnlyMap[Key, Value] extends Pure: def lookup(x: Key): Value | Null diff --git a/tests/pos-with-compiler-cc/dotc/util/ReadOnlySet.scala b/tests/pos-with-compiler-cc/dotc/util/ReadOnlySet.scala index 318a04e846fe..2ab59c4c6cb6 100644 --- a/tests/pos-with-compiler-cc/dotc/util/ReadOnlySet.scala +++ b/tests/pos-with-compiler-cc/dotc/util/ReadOnlySet.scala @@ -2,7 +2,7 @@ package dotty.tools.dotc.util /** A class for the readonly part of mutable sets. */ -abstract class ReadOnlySet[T] extends caps.Pure: +abstract class ReadOnlySet[T] extends Pure: /** The entry in the set such that `isEqual(x, entry)`, or else `null`. */ def lookup(x: T): T | Null diff --git a/tests/pos-with-compiler-cc/dotc/util/SourceFile.scala b/tests/pos-with-compiler-cc/dotc/util/SourceFile.scala index 8a5a4828adfd..351cf4c8bf85 100644 --- a/tests/pos-with-compiler-cc/dotc/util/SourceFile.scala +++ b/tests/pos-with-compiler-cc/dotc/util/SourceFile.scala @@ -60,7 +60,7 @@ object ScriptSourceFile { } } -class SourceFile(val file: AbstractFile, computeContent: -> Array[Char]) extends interfaces.SourceFile, caps.Pure { +class SourceFile(val file: AbstractFile, computeContent: -> Array[Char]) extends interfaces.SourceFile, Pure { import SourceFile._ private var myContent: Array[Char] | Null = null diff --git a/tests/pos-with-compiler-cc/dotc/util/SourcePosition.scala b/tests/pos-with-compiler-cc/dotc/util/SourcePosition.scala index ef4350741036..7ab565d58533 100644 --- a/tests/pos-with-compiler-cc/dotc/util/SourcePosition.scala +++ b/tests/pos-with-compiler-cc/dotc/util/SourcePosition.scala @@ -12,7 +12,7 @@ import scala.annotation.internal.sharable /** A source position is comprised of a span and a source file */ case class SourcePosition(source: SourceFile, span: Span, outer: SourcePosition = NoSourcePosition) -extends SrcPos, interfaces.SourcePosition, Showable, caps.Pure { +extends SrcPos, interfaces.SourcePosition, Showable, Pure { def sourcePos(using Context) = this diff --git a/tests/run-custom-args/captures/minicheck.scala b/tests/run-custom-args/captures/minicheck.scala index bdc591580482..a6aca38ae704 100644 --- a/tests/run-custom-args/captures/minicheck.scala +++ b/tests/run-custom-args/captures/minicheck.scala @@ -5,7 +5,7 @@ import annotation.{experimental, tailrec, constructorOnly} import collection.mutable import language.`3.3` -case class Symbol(name: String, initOwner: Symbol | Null) extends caps.Pure: +case class Symbol(name: String, initOwner: Symbol | Null) extends Pure: def owner = initOwner.nn private var myInfo: Type = uninitialized def infoOrCompleter: Type = myInfo @@ -29,7 +29,7 @@ object NoSymbol extends Symbol("", null): override def exists: Boolean = false override def orElse(alt: => Symbol): Symbol = alt -abstract class Type extends caps.Pure: +abstract class Type extends Pure: def exists = true def show: String case class IntType()(using @constructorOnly c: Context) extends Type: diff --git a/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala index 644efb54c32e..1eb2ce3beee0 100644 --- a/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-custom-args/tasty-inspector/stdlibExperimentalDefinitions.scala @@ -53,6 +53,7 @@ val experimentalDefinitionInLibrary = Set( "scala.annotation.internal.requiresCapability", "scala.annotation.retains", "scala.annotation.retainsByName", + "scala.Pure", "scala.caps", "scala.caps$",