Skip to content

Commit

Permalink
Drop support of sealed modifier on type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Nov 12, 2023
1 parent e015c0c commit e54c2ac
Show file tree
Hide file tree
Showing 8 changed files with 7 additions and 49 deletions.
6 changes: 0 additions & 6 deletions compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,6 @@ extension (tp: Type)
case _: TypeRef | _: AppliedType => tp.typeSymbol.hasAnnotation(defn.CapabilityAnnot)
case _ => false

def isSealed(using Context): Boolean = tp match
case tp: TypeParamRef => tp.underlying.isSealed
case tp: TypeBounds => tp.hi.hasAnnotation(defn.Caps_SealedAnnot)
case tp: TypeRef => tp.symbol.is(Sealed) || tp.info.isSealed // TODO: drop symbol flag?
case _ => false

/** Drop @retains annotations everywhere */
def dropAllRetains(using Context): Type = // TODO we should drop retains from inferred types before unpickling
val tm = new TypeMap:
Expand Down
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,6 @@ class Definitions {
@tu lazy val Caps_unsafeBox: Symbol = CapsUnsafeModule.requiredMethod("unsafeBox")
@tu lazy val Caps_unsafeUnbox: Symbol = CapsUnsafeModule.requiredMethod("unsafeUnbox")
@tu lazy val Caps_unsafeBoxFunArg: Symbol = CapsUnsafeModule.requiredMethod("unsafeBoxFunArg")
@tu lazy val Caps_SealedAnnot: ClassSymbol = requiredClass("scala.caps.Sealed")
@tu lazy val expandedUniversalSet: CaptureSet = CaptureSet(captureRoot.termRef)

@tu lazy val PureClass: Symbol = requiredClass("scala.Pure")
Expand Down
17 changes: 1 addition & 16 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4072,15 +4072,10 @@ object Types {

protected def toPInfo(tp: Type)(using Context): PInfo

/** If `tparam` is a sealed type parameter symbol of a polymorphic method, add
* a @caps.Sealed annotation to the upperbound in `tp`.
*/
protected def addSealed(tparam: ParamInfo, tp: Type)(using Context): Type = tp

def fromParams[PI <: ParamInfo.Of[N]](params: List[PI], resultType: Type)(using Context): Type =
if (params.isEmpty) resultType
else apply(params.map(_.paramName))(
tl => params.map(param => toPInfo(addSealed(param, tl.integrate(params, param.paramInfo)))),
tl => params.map(param => toPInfo(tl.integrate(params, param.paramInfo))),
tl => tl.integrate(params, resultType))
}

Expand Down Expand Up @@ -4402,16 +4397,6 @@ object Types {
resultTypeExp: PolyType => Type)(using Context): PolyType =
unique(new PolyType(paramNames)(paramInfosExp, resultTypeExp))

override protected def addSealed(tparam: ParamInfo, tp: Type)(using Context): Type =
tparam match
case tparam: Symbol if tparam.is(Sealed) =>
tp match
case tp @ TypeBounds(lo, hi) =>
tp.derivedTypeBounds(lo,
AnnotatedType(hi, Annotation(defn.Caps_SealedAnnot, tparam.span)))
case _ => tp
case _ => tp

def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] =
Some((tl.typeParams, tl.resType))
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3266,9 +3266,6 @@ object Parsers {
val start = in.offset
var mods = annotsAsMods() | Param
if ownerKind == ParamOwner.Class then mods |= PrivateLocal
if Feature.ccEnabled && in.token == SEALED then
mods |= Sealed
in.nextToken()
if isIdent(nme.raw.PLUS) && checkVarianceOK() then
mods |= Covariant
else if isIdent(nme.raw.MINUS) && checkVarianceOK() then
Expand Down
6 changes: 1 addition & 5 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -519,11 +519,7 @@ object Checking {
// but they can never be one of ClassOnlyFlags
if !sym.isClass && sym.isOneOf(ClassOnlyFlags) then
val illegal = sym.flags & ClassOnlyFlags
if sym.is(TypeParam)
&& illegal == Sealed
&& Feature.ccEnabled && cc.ccConfig.allowUniversalInBoxed
then () // OK
else fail(em"only classes can be ${illegal.flagsString}")
fail(em"only classes can be ${illegal.flagsString}")
if (sym.is(AbsOverride) && !sym.owner.is(Trait))
fail(AbstractOverrideOnlyInTraits(sym))
if sym.is(Trait) then
Expand Down
9 changes: 1 addition & 8 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1042,14 +1042,7 @@ class Namer { typer: Typer =>
tp

val rhs1 = typedAheadType(rhs)
val rhsBodyType: TypeBounds =
val bounds = addVariances(rhs1.tpe).toBounds
if sym.is(Sealed) then
sym.resetFlag(Sealed)
bounds.derivedTypeBounds(bounds.lo,
AnnotatedType(bounds.hi, Annotation(defn.Caps_SealedAnnot, rhs1.span)))
else bounds

val rhsBodyType: TypeBounds = addVariances(rhs1.tpe).toBounds
val unsafeInfo = if (isDerived) rhsBodyType else abstracted(rhsBodyType)

def opaqueToBounds(info: Type): Type =
Expand Down
6 changes: 0 additions & 6 deletions library/src/scala/caps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,3 @@ import annotation.experimental
def unsafeBoxFunArg: T => U = f

end unsafe

/** An annotation that expresses the sealed modifier on a type parameter
* Should not be directly referred to in source
*/
@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
8 changes: 4 additions & 4 deletions tests/pos-special/stdlib/collection/ArrayOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ object ArrayOps {
}

@SerialVersionUID(3L)
private[collection] final class ArrayIterator[@specialized(Specializable.Everything) sealed A](xs: Array[A]) extends AbstractIterator[A] with Serializable {
private[collection] final class ArrayIterator[@specialized(Specializable.Everything) A](xs: Array[A]) extends AbstractIterator[A] with Serializable {
private[this] var pos = 0
private[this] val len = xs.length
override def knownSize: Int = len - pos
Expand All @@ -144,7 +144,7 @@ object ArrayOps {
}

@SerialVersionUID(3L)
private final class ReverseIterator[@specialized(Specializable.Everything) sealed A](xs: Array[A]) extends AbstractIterator[A] with Serializable {
private final class ReverseIterator[@specialized(Specializable.Everything) A](xs: Array[A]) extends AbstractIterator[A] with Serializable {
private[this] var pos = xs.length-1
def hasNext: Boolean = pos >= 0
def next(): A = {
Expand Down Expand Up @@ -777,7 +777,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* Returns `z` if this array is empty.
*/
def foldLeft[B](z: B)(op: (B, A) => B): B = {
def f[@specialized(Specializable.Everything) sealed T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
def f[@specialized(Specializable.Everything) T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
val length = xs.length
var v: Any = z
var i = 0
Expand Down Expand Up @@ -883,7 +883,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* Returns `z` if this array is empty.
*/
def foldRight[B](z: B)(op: (A, B) => B): B = {
def f[@specialized(Specializable.Everything) sealed T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
def f[@specialized(Specializable.Everything) T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
var v = z
var i = xs.length - 1
while(i >= 0) {
Expand Down

0 comments on commit e54c2ac

Please sign in to comment.