diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 2acfc4cf86e3..57c74d90b45d 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -518,6 +518,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def scalaUnit(implicit src: SourceFile): Select = scalaDot(tpnme.Unit) def scalaAny(implicit src: SourceFile): Select = scalaDot(tpnme.Any) + def capsInternalDot(name: Name)(using SourceFile): Select = + Select(Select(scalaDot(nme.caps), nme.internal), name) + def captureRoot(using Context): Select = Select(scalaDot(nme.caps), nme.CAPTURE_ROOT) @@ -525,7 +528,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { Annotated(parent, New(scalaAnnotationDot(annotName), List(refs))) def makeCapsOf(tp: RefTree)(using Context): Tree = - TypeApply(Select(scalaDot(nme.caps), nme.capsOf), tp :: Nil) + TypeApply(capsInternalDot(nme.capsOf), tp :: Nil) // Capture set variable `[C^]` becomes: `[C >: CapSet <: CapSet^{cap}]` def makeCapsBound()(using Context): TypeBoundsTree = diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index a74cade40cda..e44bfcee2cf7 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -993,17 +993,19 @@ class Definitions { @tu lazy val LabelClass: Symbol = requiredClass("scala.util.boundary.Label") @tu lazy val BreakClass: Symbol = requiredClass("scala.util.boundary.Break") - @tu lazy val CapsModule: Symbol = requiredModule("scala.caps") + @tu lazy val CapsModule: Symbol = requiredPackage("scala.caps") @tu lazy val captureRoot: TermSymbol = CapsModule.requiredValue("cap") @tu lazy val Caps_Capability: TypeSymbol = CapsModule.requiredType("Capability") @tu lazy val Caps_CapSet: ClassSymbol = requiredClass("scala.caps.CapSet") - @tu lazy val Caps_reachCapability: TermSymbol = CapsModule.requiredMethod("reachCapability") - @tu lazy val Caps_capsOf: TermSymbol = CapsModule.requiredMethod("capsOf") + @tu lazy val CapsInternalModule: Symbol = requiredModule("scala.caps.internal") + @tu lazy val Caps_reachCapability: TermSymbol = CapsInternalModule.requiredMethod("reachCapability") + @tu lazy val Caps_capsOf: TermSymbol = CapsInternalModule.requiredMethod("capsOf") @tu lazy val Caps_Exists: ClassSymbol = requiredClass("scala.caps.Exists") @tu lazy val CapsUnsafeModule: Symbol = requiredModule("scala.caps.unsafe") @tu lazy val Caps_unsafeAssumePure: Symbol = CapsUnsafeModule.requiredMethod("unsafeAssumePure") @tu lazy val Caps_ContainsTrait: TypeSymbol = CapsModule.requiredType("Contains") - @tu lazy val Caps_containsImpl: TermSymbol = CapsModule.requiredMethod("containsImpl") + @tu lazy val Caps_ContainsModule: Symbol = requiredModule("scala.caps.Contains") + @tu lazy val Caps_containsImpl: TermSymbol = Caps_ContainsModule.requiredMethod("containsImpl") /** The same as CaptureSet.universal but generated implicitly for references of Capability subtypes */ @tu lazy val universalCSImpliedByCapability = CaptureSet(captureRoot.termRef) @@ -1063,7 +1065,7 @@ class Definitions { @tu lazy val UncheckedStableAnnot: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedStable") @tu lazy val UncheckedVarianceAnnot: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedVariance") @tu lazy val UncheckedCapturesAnnot: ClassSymbol = requiredClass("scala.annotation.unchecked.uncheckedCaptures") - @tu lazy val UntrackedCapturesAnnot: ClassSymbol = requiredClass("scala.caps.untrackedCaptures") + @tu lazy val UntrackedCapturesAnnot: ClassSymbol = requiredClass("scala.caps.unsafe.untrackedCaptures") @tu lazy val UseAnnot: ClassSymbol = requiredClass("scala.caps.use") @tu lazy val VolatileAnnot: ClassSymbol = requiredClass("scala.volatile") @tu lazy val LanguageFeatureMetaAnnot: ClassSymbol = requiredClass("scala.annotation.meta.languageFeature") @@ -2087,7 +2089,12 @@ class Definitions { */ @tu lazy val ccExperimental: Set[Symbol] = Set( CapsModule, CapsModule.moduleClass, PureClass, + Caps_Capability, // TODO: Remove when Capability is stabilized RequiresCapabilityAnnot, + captureRoot, Caps_CapSet, Caps_ContainsTrait, Caps_ContainsModule, Caps_ContainsModule.moduleClass, UseAnnot, + Caps_Exists, + CapsUnsafeModule, CapsUnsafeModule.moduleClass, + CapsInternalModule, CapsInternalModule.moduleClass, RetainsAnnot, RetainsCapAnnot, RetainsByNameAnnot) /** Experimental language features defined in `scala.runtime.stdLibPatches.language.experimental`. diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 39297697f29a..6a9d70a19f49 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -78,7 +78,7 @@ object SymbolLoaders { * and give them `completer` as type. */ def enterPackage(owner: Symbol, pname: TermName, completer: (TermSymbol, ClassSymbol) => PackageLoader)(using Context): Symbol = { - val preExisting = owner.info.decls lookup pname + val preExisting = owner.info.decls.lookup(pname) if (preExisting != NoSymbol) // Some jars (often, obfuscated ones) include a package and // object with the same name. Rather than render them unusable, @@ -95,6 +95,18 @@ object SymbolLoaders { s"Resolving package/object name conflict in favor of object ${preExisting.fullName}. The package will be inaccessible.") return NoSymbol } + else if pname == nme.caps && owner == defn.ScalaPackageClass then + // `scala.caps`` was an object until 3.6, it is a package from 3.7. Without special handling + // this would cause a TypeError to be thrown below if a build has several versions of the + // Scala standard library on the classpath. This was the case for 29 projects in OpenCB. + // These projects should be updated. But until that's the case we issue a warning instead + // of a hard failure. + report.warning( + em"""$owner contains object and package with same name: $pname. + |This indicates that there are several versions of the Scala standard library on the classpath. + |The build should be reconfigured so that only one version of the standard library is on the classpath.""") + owner.info.decls.openForMutations.unlink(preExisting) + owner.info.decls.openForMutations.unlink(preExisting.moduleClass) else throw TypeError( em"""$owner contains object and package with same name: $pname diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index e90aeb217362..53e9a2c2098b 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -187,10 +187,11 @@ class PlainPrinter(_ctx: Context) extends Printer { homogenize(tp) match { case tp: TypeType => toTextRHS(tp) + case tp: TermRef if tp.isRootCapability => + toTextCaptureRef(tp) case tp: TermRef if !tp.denotationIsCurrent && !homogenizedView // always print underlying when testing picklers - && !tp.isRootCapability || tp.symbol.is(Module) || tp.symbol.name == nme.IMPORT => toTextRef(tp) ~ ".type" diff --git a/library/src/scala/caps.scala b/library/src/scala/caps.scala deleted file mode 100644 index c35b3b55e813..000000000000 --- a/library/src/scala/caps.scala +++ /dev/null @@ -1,69 +0,0 @@ -package scala - -import annotation.{experimental, compileTimeOnly, retainsCap} - -@experimental object caps: - - trait Capability extends Any - - /** The universal capture reference */ - val cap: Capability = new Capability() {} - - /** The universal capture reference (deprecated) */ - @deprecated("Use `cap` instead") - val `*`: Capability = cap - - @deprecated("Use `Capability` instead") - type Cap = Capability - - /** Carrier trait for capture set type parameters */ - trait CapSet extends Any - - /** A type constraint expressing that the capture set `C` needs to contain - * the capability `R` - */ - sealed trait Contains[+C >: CapSet <: CapSet @retainsCap, R <: Singleton] - - /** The only implementation of `Contains`. The constraint that `{R} <: C` is - * added separately by the capture checker. - */ - given containsImpl[C >: CapSet <: CapSet @retainsCap, R <: Singleton]: Contains[C, R]() - - /** A wrapper indicating a type variable in a capture argument list of a - * @retains annotation. E.g. `^{x, Y^}` is represented as `@retains(x, capsOf[Y])`. - */ - @compileTimeOnly("Should be be used only internally by the Scala compiler") - def capsOf[CS >: CapSet <: CapSet @retainsCap]: Any = ??? - - /** Reach capabilities x* which appear as terms in @retains annotations are encoded - * as `caps.reachCapability(x)`. When converted to CaptureRef types in capture sets - * they are represented as `x.type @annotation.internal.reachCapability`. - */ - extension (x: Any) def reachCapability: Any = x - - /** A trait to allow expressing existential types such as - * - * (x: Exists) => A ->{x} B - */ - sealed trait Exists extends Capability - - /** This should go into annotations. For now it is here, so that we - * can experiment with it quickly between minor releases - */ - final class untrackedCaptures extends annotation.StaticAnnotation - - /** This should go into annotations. For now it is here, so that we - * can experiment with it quickly between minor releases - */ - final class use extends annotation.StaticAnnotation - - object unsafe: - - extension [T](x: T) - /** A specific cast operation to remove a capture set. - * If argument is of type `T^C`, assume it is of type `T` instead. - * Calls to this method are treated specially by the capture checker. - */ - def unsafeAssumePure: T = x - - end unsafe diff --git a/library/src/scala/caps/package.scala b/library/src/scala/caps/package.scala new file mode 100644 index 000000000000..3705a6137be8 --- /dev/null +++ b/library/src/scala/caps/package.scala @@ -0,0 +1,106 @@ +package scala +package caps + +import annotation.{experimental, compileTimeOnly, retainsCap} + +/** + * Base trait for classes that represent capabilities in the + * [object-capability model](https://en.wikipedia.org/wiki/Object-capability_model). + * + * A capability is a value representing a permission, access right, resource or effect. + * Capabilities are typically passed to code as parameters; they should not be global objects. + * Often, they come with access restrictions such as scoped lifetimes or limited sharing. + * + * An example is the [[scala.util.boundary.Label Label]] class in [[scala.util.boundary]]. + * It represents a capability in the sense that it gives permission to [[scala.util.boundary.break break]] + * to the enclosing boundary represented by the `Label`. It has a scoped lifetime, since breaking to + * a `Label` after the associated `boundary` was exited gives a runtime exception. + * + * [[Capability]] has a formal meaning when + * [[scala.language.experimental.captureChecking Capture Checking]] + * is turned on. + * But even without capture checking, extending this trait can be useful for documenting the intended purpose + * of a class. + */ +@experimental +trait Capability extends Any + +/** The universal capture reference. */ +@experimental +object cap extends Capability + +/** Carrier trait for capture set type parameters */ +@experimental +trait CapSet extends Any + +/** A type constraint expressing that the capture set `C` needs to contain + * the capability `R` + */ +@experimental +sealed trait Contains[+C >: CapSet <: CapSet @retainsCap, R <: Singleton] + +@experimental +object Contains: + /** The only implementation of `Contains`. The constraint that `{R} <: C` is + * added separately by the capture checker. + */ + @experimental + given containsImpl[C >: CapSet <: CapSet @retainsCap, R <: Singleton]: Contains[C, R]() + +/** An annotation on parameters `x` stating that the method's body makes + * use of the reach capability `x*`. Consequently, when calling the method + * we need to charge the deep capture set of the actual argiment to the + * environment. + * + * Note: This should go into annotations. For now it is here, so that we + * can experiment with it quickly between minor releases + */ +@experimental +final class use extends annotation.StaticAnnotation + +/** A trait to allow expressing existential types such as + * + * (x: Exists) => A ->{x} B + */ +@experimental +sealed trait Exists extends Capability + +@experimental +object internal: + + /** A wrapper indicating a type variable in a capture argument list of a + * @retains annotation. E.g. `^{x, Y^}` is represented as `@retains(x, capsOf[Y])`. + */ + @compileTimeOnly("Should be be used only internally by the Scala compiler") + def capsOf[CS >: CapSet <: CapSet @retainsCap]: Any = ??? + + /** Reach capabilities x* which appear as terms in @retains annotations are encoded + * as `caps.reachCapability(x)`. When converted to CaptureRef types in capture sets + * they are represented as `x.type @annotation.internal.reachCapability`. + */ + extension (x: Any) def reachCapability: Any = x + +@experimental +object unsafe: + /** + * Marks the constructor parameter as untracked. + * The capture set of this parameter will not be included in + * the capture set of the constructed object. + * + * @note This should go into annotations. For now it is here, so that we + * can experiment with it quickly between minor releases + */ + final class untrackedCaptures extends annotation.StaticAnnotation + + extension [T](x: T) + /** A specific cast operation to remove a capture set. + * If argument is of type `T^C`, assume it is of type `T` instead. + * Calls to this method are treated specially by the capture checker. + */ + def unsafeAssumePure: T = x + + /** A wrapper around code for which separation checks are suppressed. + */ + def unsafeAssumeSeparate(op: Any): op.type = op + +end unsafe diff --git a/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala b/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala index 28ce8da104aa..7a63fbb4f248 100644 --- a/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala +++ b/scala2-library-cc/src/scala/collection/immutable/LazyListIterable.scala @@ -24,7 +24,7 @@ import scala.language.implicitConversions import scala.runtime.Statics import language.experimental.captureChecking import annotation.unchecked.uncheckedCaptures -import caps.untrackedCaptures +import caps.unsafe.untrackedCaptures /** This class implements an immutable linked list. We call it "lazy" * because it computes its elements only when they are needed. diff --git a/tests/disabled/neg-custom-args/captures/capt-wf.scala b/tests/disabled/neg-custom-args/captures/capt-wf.scala index bfe349747776..302202064ac0 100644 --- a/tests/disabled/neg-custom-args/captures/capt-wf.scala +++ b/tests/disabled/neg-custom-args/captures/capt-wf.scala @@ -1,7 +1,7 @@ // No longer valid class C -type Cap = C @retains(caps.*) -type Top = Any @retains(caps.*) +type Cap = C @retains(caps.cap) +type Top = Any @retains(caps.cap) type T = (x: Cap) => List[String @retains(x)] => Unit // error val x: (x: Cap) => Array[String @retains(x)] = ??? // error diff --git a/tests/disabled/neg-custom-args/captures/try2.scala b/tests/disabled/neg-custom-args/captures/try2.scala index 876dc1ec12f1..43e17d8c9eef 100644 --- a/tests/disabled/neg-custom-args/captures/try2.scala +++ b/tests/disabled/neg-custom-args/captures/try2.scala @@ -5,7 +5,7 @@ import annotation.ability @ability erased val canThrow: * = ??? class CanThrow[E <: Exception] extends Retains[canThrow.type] -type Top = Any @retains(caps.*) +type Top = Any @retains(caps.cap) infix type throws[R, E <: Exception] = (erased CanThrow[E]) ?=> R diff --git a/tests/neg-custom-args/captures/capt1.check b/tests/neg-custom-args/captures/capt1.check index acf8faa7a969..15fe32fc7653 100644 --- a/tests/neg-custom-args/captures/capt1.check +++ b/tests/neg-custom-args/captures/capt1.check @@ -36,15 +36,15 @@ -- Error: tests/neg-custom-args/captures/capt1.scala:34:16 ------------------------------------------------------------- 34 | val z2 = h[() -> Cap](() => x) // error // error | ^^^^^^^^^ - | Type variable X of method h cannot be instantiated to () -> (ex$15: caps.Exists) -> C^{ex$15} since - | the part C^{ex$15} of that type captures the root capability `cap`. + | Type variable X of method h cannot be instantiated to () -> (ex$15: scala.caps.Exists) -> C^{ex$15} since + | the part C^{ex$15} of that type captures the root capability `cap`. -- Error: tests/neg-custom-args/captures/capt1.scala:34:30 ------------------------------------------------------------- 34 | val z2 = h[() -> Cap](() => x) // error // error | ^ - | reference (x : C^) is not included in the allowed capture set {} - | of an enclosing function literal with expected type () -> (ex$15: caps.Exists) -> C^{ex$15} + | reference (x : C^) is not included in the allowed capture set {} + | of an enclosing function literal with expected type () -> (ex$15: scala.caps.Exists) -> C^{ex$15} -- Error: tests/neg-custom-args/captures/capt1.scala:36:13 ------------------------------------------------------------- 36 | val z3 = h[(() -> Cap) @retains(x)](() => x)(() => C()) // error | ^^^^^^^^^^^^^^^^^^^^^^^ - | Type variable X of method h cannot be instantiated to box () ->{x} (ex$20: caps.Exists) -> C^{ex$20} since - | the part C^{ex$20} of that type captures the root capability `cap`. + |Type variable X of method h cannot be instantiated to box () ->{x} (ex$20: scala.caps.Exists) -> C^{ex$20} since + |the part C^{ex$20} of that type captures the root capability `cap`. diff --git a/tests/neg-custom-args/captures/cc-poly-1.check b/tests/neg-custom-args/captures/cc-poly-1.check index ea486f55a61f..0ac35b532916 100644 --- a/tests/neg-custom-args/captures/cc-poly-1.check +++ b/tests/neg-custom-args/captures/cc-poly-1.check @@ -1,12 +1,12 @@ -- [E057] Type Mismatch Error: tests/neg-custom-args/captures/cc-poly-1.scala:12:6 ------------------------------------- 12 | f[Any](D()) // error | ^ - | Type argument Any does not conform to upper bound caps.CapSet^ + | Type argument Any does not conform to upper bound scala.caps.CapSet^ | | longer explanation available when compiling with `-explain` -- [E057] Type Mismatch Error: tests/neg-custom-args/captures/cc-poly-1.scala:13:6 ------------------------------------- 13 | f[String](D()) // error | ^ - | Type argument String does not conform to upper bound caps.CapSet^ + | Type argument String does not conform to upper bound scala.caps.CapSet^ | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-this2.check b/tests/neg-custom-args/captures/cc-this2.check index 6cb3010d6174..dc61fe2e0396 100644 --- a/tests/neg-custom-args/captures/cc-this2.check +++ b/tests/neg-custom-args/captures/cc-this2.check @@ -2,7 +2,7 @@ -- Error: tests/neg-custom-args/captures/cc-this2/D_2.scala:3:8 -------------------------------------------------------- 3 | this: D^ => // error | ^^ - |reference (caps.cap : caps.Capability) captured by this self type is not included in the allowed capture set {} of pure base class class C + | reference cap captured by this self type is not included in the allowed capture set {} of pure base class class C -- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this2/D_2.scala:2:6 ----------------------------------- 2 |class D extends C: // error | ^ diff --git a/tests/neg-custom-args/captures/exception-definitions.check b/tests/neg-custom-args/captures/exception-definitions.check index 3f2b15f312b9..67f0f3b72cbb 100644 --- a/tests/neg-custom-args/captures/exception-definitions.check +++ b/tests/neg-custom-args/captures/exception-definitions.check @@ -1,7 +1,7 @@ -- Error: tests/neg-custom-args/captures/exception-definitions.scala:3:8 ----------------------------------------------- 3 | self: Err^ => // error | ^^^^ - |reference (caps.cap : caps.Capability) captured by this self type is not included in the allowed capture set {} of pure base class class Throwable + |reference cap captured by this self type is not included in the allowed capture set {} of pure base class class Throwable -- Error: tests/neg-custom-args/captures/exception-definitions.scala:7:12 ---------------------------------------------- 7 | val x = c // error | ^ diff --git a/tests/neg-custom-args/captures/existential-mapping.check b/tests/neg-custom-args/captures/existential-mapping.check index 30836bc427cf..43f4e97e6a2a 100644 --- a/tests/neg-custom-args/captures/existential-mapping.check +++ b/tests/neg-custom-args/captures/existential-mapping.check @@ -5,84 +5,84 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:9:25 --------------------------- 9 | val _: (x: C^) -> C = x1 // error | ^^ - | Found: (x1 : (x: C^) -> (ex$3: caps.Exists) -> C^{ex$3}) + | Found: (x1 : (x: C^) -> (ex$3: scala.caps.Exists) -> C^{ex$3}) | Required: (x: C^) -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:12:20 -------------------------- 12 | val _: C^ -> C = x2 // error | ^^ - | Found: (x2 : C^ -> (ex$7: caps.Exists) -> C^{ex$7}) + | Found: (x2 : C^ -> (ex$7: scala.caps.Exists) -> C^{ex$7}) | Required: C^ -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:15:30 -------------------------- 15 | val _: A^ -> (x: C^) -> C = x3 // error | ^^ - | Found: (x3 : A^ -> (x: C^) -> (ex$11: caps.Exists) -> C^{ex$11}) + | Found: (x3 : A^ -> (x: C^) -> (ex$11: scala.caps.Exists) -> C^{ex$11}) | Required: A^ -> (x: C^) -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:18:25 -------------------------- 18 | val _: A^ -> C^ -> C = x4 // error | ^^ - | Found: (x4 : A^ -> C^ -> (ex$19: caps.Exists) -> C^{ex$19}) + | Found: (x4 : A^ -> C^ -> (ex$19: scala.caps.Exists) -> C^{ex$19}) | Required: A^ -> C^ -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:21:30 -------------------------- 21 | val _: A^ -> (x: C^) -> C = x5 // error | ^^ - | Found: (x5 : A^ -> (x: C^) -> (ex$27: caps.Exists) -> C^{ex$27}) + | Found: (x5 : A^ -> (x: C^) -> (ex$27: scala.caps.Exists) -> C^{ex$27}) | Required: A^ -> (x: C^) -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:24:30 -------------------------- 24 | val _: A^ -> (x: C^) => C = x6 // error | ^^ - | Found: (x6 : A^ -> (ex$36: caps.Exists) -> (x: C^) ->{ex$36} (ex$35: caps.Exists) -> C^{ex$35}) - | Required: A^ -> (ex$39: caps.Exists) -> (x: C^) ->{ex$39} C + | Found: (x6 : A^ -> (ex$36: scala.caps.Exists) -> (x: C^) ->{ex$36} (ex$35: scala.caps.Exists) -> C^{ex$35}) + | Required: A^ -> (ex$39: scala.caps.Exists) -> (x: C^) ->{ex$39} C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:27:25 -------------------------- 27 | val _: (x: C^) => C = y1 // error | ^^ - | Found: (y1 : (x: C^) => (ex$41: caps.Exists) -> C^{ex$41}) + | Found: (y1 : (x: C^) => (ex$41: scala.caps.Exists) -> C^{ex$41}) | Required: (x: C^) => C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:30:20 -------------------------- 30 | val _: C^ => C = y2 // error | ^^ - | Found: (y2 : C^ => (ex$45: caps.Exists) -> C^{ex$45}) + | Found: (y2 : C^ => (ex$45: scala.caps.Exists) -> C^{ex$45}) | Required: C^ => C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:33:30 -------------------------- 33 | val _: A^ => (x: C^) => C = y3 // error | ^^ - | Found: (y3 : A^ => (ex$50: caps.Exists) -> (x: C^) ->{ex$50} (ex$49: caps.Exists) -> C^{ex$49}) - | Required: A^ => (ex$53: caps.Exists) -> (x: C^) ->{ex$53} C + | Found: (y3 : A^ => (ex$50: scala.caps.Exists) -> (x: C^) ->{ex$50} (ex$49: scala.caps.Exists) -> C^{ex$49}) + | Required: A^ => (ex$53: scala.caps.Exists) -> (x: C^) ->{ex$53} C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:36:25 -------------------------- 36 | val _: A^ => C^ => C = y4 // error | ^^ - | Found: (y4 : A^ => (ex$56: caps.Exists) -> C^ ->{ex$56} (ex$55: caps.Exists) -> C^{ex$55}) - | Required: A^ => (ex$59: caps.Exists) -> C^ ->{ex$59} C + | Found: (y4 : A^ => (ex$56: scala.caps.Exists) -> C^ ->{ex$56} (ex$55: scala.caps.Exists) -> C^{ex$55}) + | Required: A^ => (ex$59: scala.caps.Exists) -> C^ ->{ex$59} C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:39:30 -------------------------- 39 | val _: A^ => (x: C^) -> C = y5 // error | ^^ - | Found: (y5 : A^ => (x: C^) -> (ex$61: caps.Exists) -> C^{ex$61}) + | Found: (y5 : A^ => (x: C^) -> (ex$61: scala.caps.Exists) -> C^{ex$61}) | Required: A^ => (x: C^) -> C | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/existential-mapping.scala:42:30 -------------------------- 42 | val _: A^ => (x: C^) => C = y6 // error | ^^ - | Found: (y6 : A^ => (ex$70: caps.Exists) -> (x: C^) ->{ex$70} (ex$69: caps.Exists) -> C^{ex$69}) - | Required: A^ => (ex$73: caps.Exists) -> (x: C^) ->{ex$73} C + | Found: (y6 : A^ => (ex$70: scala.caps.Exists) -> (x: C^) ->{ex$70} (ex$69: scala.caps.Exists) -> C^{ex$69}) + | Required: A^ => (ex$73: scala.caps.Exists) -> (x: C^) ->{ex$73} C | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21313.check b/tests/neg-custom-args/captures/i21313.check index 37b944a97d68..f76f4bc6871e 100644 --- a/tests/neg-custom-args/captures/i21313.check +++ b/tests/neg-custom-args/captures/i21313.check @@ -5,7 +5,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21313.scala:15:12 --------------------------------------- 15 | ac1.await(src2) // error | ^^^^ - | Found: (src2 : Source[Int, caps.CapSet^{ac2}]^?) - | Required: Source[Int, caps.CapSet^{ac1}]^ + | Found: (src2 : Source[Int, scala.caps.CapSet^{ac2}]^?) + | Required: Source[Int, scala.caps.CapSet^{ac1}]^ | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21401.check b/tests/neg-custom-args/captures/i21401.check index e7483e10bfa6..05378bf57f23 100644 --- a/tests/neg-custom-args/captures/i21401.check +++ b/tests/neg-custom-args/captures/i21401.check @@ -21,7 +21,7 @@ -- Error: tests/neg-custom-args/captures/i21401.scala:17:52 ------------------------------------------------------------ 17 | val x: Boxed[IO^] = leaked[Boxed[IO^], Boxed[IO^] -> Boxed[IO^]](x => x) // error // error | ^^^^^^^^^^^^^^^^^^^^^^^^ - |Type variable X of value leaked cannot be instantiated to Boxed[box IO^] -> (ex$20: caps.Exists) -> Boxed[box IO^{ex$20}] since + |Type variable X of value leaked cannot be instantiated to Boxed[box IO^] -> (ex$20: scala.caps.Exists) -> Boxed[box IO^{ex$20}] since |the part box IO^{ex$20} of that type captures the root capability `cap`. -- Error: tests/neg-custom-args/captures/i21401.scala:18:21 ------------------------------------------------------------ 18 | val y: IO^{x*} = x.unbox // error diff --git a/tests/neg-custom-args/captures/i21614.check b/tests/neg-custom-args/captures/i21614.check index f4967253455f..2d1de6c57a0b 100644 --- a/tests/neg-custom-args/captures/i21614.check +++ b/tests/neg-custom-args/captures/i21614.check @@ -8,10 +8,10 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21614.scala:15:12 --------------------------------------- 15 | files.map(new Logger(_)) // error, Q: can we improve the error message? | ^^^^^^^^^^^^^ - | Found: (_$1: box File^{files*}) ->{files*} (ex$16: caps.Exists) -> box Logger{val f: File^{_$1}}^{ex$16} - | Required: (_$1: box File^{files*}) => box Logger{val f: File^?}^? + |Found: (_$1: box File^{files*}) ->{files*} (ex$16: scala.caps.Exists) -> box Logger{val f: File^{_$1}}^{ex$16} + |Required: (_$1: box File^{files*}) => box Logger{val f: File^?}^? | - | Note that the universal capability `cap` - | cannot be included in capture set ? + |Note that the universal capability `cap` + |cannot be included in capture set ? | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/leaked-curried.check b/tests/neg-custom-args/captures/leaked-curried.check index be11aedd74ae..d6b9c46f71e0 100644 --- a/tests/neg-custom-args/captures/leaked-curried.check +++ b/tests/neg-custom-args/captures/leaked-curried.check @@ -1,10 +1,10 @@ -- Error: tests/neg-custom-args/captures/leaked-curried.scala:14:20 ---------------------------------------------------- 14 | () => () => io // error | ^^ - | reference (io : Cap^) is not included in the allowed capture set {} - | of an enclosing function literal with expected type () -> () ->{io} (ex$7: caps.Exists) -> Cap^{ex$7} + | reference (io : Cap^) is not included in the allowed capture set {} + | of an enclosing function literal with expected type () -> () ->{io} (ex$7: scala.caps.Exists) -> Cap^{ex$7} -- Error: tests/neg-custom-args/captures/leaked-curried.scala:17:20 ---------------------------------------------------- 17 | () => () => io // error | ^^ - | reference (io : Cap^) is not included in the allowed capture set {} - | of an enclosing function literal with expected type () -> () ->{io} (ex$15: caps.Exists) -> Cap^{ex$15} + | reference (io : Cap^) is not included in the allowed capture set {} + | of an enclosing function literal with expected type () -> () ->{io} (ex$15: scala.caps.Exists) -> Cap^{ex$15} diff --git a/tests/neg/i22890.check b/tests/neg/i22890.check new file mode 100644 index 000000000000..f5e37b10dac2 --- /dev/null +++ b/tests/neg/i22890.check @@ -0,0 +1,7 @@ +-- [E161] Naming Error: tests/neg/i22890/caps_1.java:3:0 --------------------------------------------------------------- +3 |class caps { // error: caps is already defined as package caps + |^ + |caps is already defined as package scala.caps +package scala contains object and package with same name: caps. +This indicates that there are several versions of the Scala standard library on the classpath. +The build should be reconfigured so that only one version of the standard library is on the classpath. diff --git a/tests/neg/i22890/Test_2.scala b/tests/neg/i22890/Test_2.scala new file mode 100644 index 000000000000..4545d5ab94ae --- /dev/null +++ b/tests/neg/i22890/Test_2.scala @@ -0,0 +1,3 @@ +@main def Test = + println("hello") +// nopos-warn diff --git a/tests/neg/i22890/caps_1.java b/tests/neg/i22890/caps_1.java new file mode 100644 index 000000000000..9bc804829932 --- /dev/null +++ b/tests/neg/i22890/caps_1.java @@ -0,0 +1,5 @@ +package scala; + +class caps { // error: caps is already defined as package caps + static public void foo() {} +} \ No newline at end of file diff --git a/tests/pos-custom-args/captures/untracked-captures.scala b/tests/pos-custom-args/captures/untracked-captures.scala index 7a090a5dd24f..f02dee607c01 100644 --- a/tests/pos-custom-args/captures/untracked-captures.scala +++ b/tests/pos-custom-args/captures/untracked-captures.scala @@ -1,4 +1,5 @@ -import caps.untrackedCaptures +import caps.unsafe.untrackedCaptures + class LL[+A] private (@untrackedCaptures lazyState: () => LL.State[A]^): private val res = lazyState() diff --git a/tests/pos/caps-universal.scala b/tests/pos/caps-universal.scala index 014955caaa87..3451866ed8f3 100644 --- a/tests/pos/caps-universal.scala +++ b/tests/pos/caps-universal.scala @@ -3,7 +3,7 @@ import annotation.retains val id: Int -> Int = (x: Int) => x val foo: Int => Int = id -val bar: (Int -> Int) @retains(caps.*) = foo +val bar: (Int -> Int) @retains(caps.cap) = foo diff --git a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala index 0715bedea201..3e7a4868b0cb 100644 --- a/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala +++ b/tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala @@ -32,8 +32,19 @@ val experimentalDefinitionInLibrary = Set( "scala.annotation.retainsCap", "scala.annotation.retainsArg", "scala.Pure", - "scala.caps", - "scala.caps$", + "scala.caps.CapSet", + "scala.caps.Capability", + "scala.caps.Contains", + "scala.caps.Contains$", + "scala.caps.Contains$.containsImpl", + "scala.caps.Exists", + "scala.caps.internal", + "scala.caps.internal$", + "scala.caps.cap", + "scala.caps.cap$", + "scala.caps.unsafe", + "scala.caps.unsafe$", + "scala.caps.use", //// New feature: into "scala.annotation.into",