Skip to content

Commit 2fc5889

Browse files
committed
Drop WithBounds annotation
Use new three-element TypeBoundsTree to represent bounded opaque aliases instead.
1 parent 63ed1bf commit 2fc5889

File tree

9 files changed

+31
-52
lines changed

9 files changed

+31
-52
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,8 @@ object desugar {
11561156
val legalOpaque: MemberDefTest = {
11571157
case TypeDef(_, rhs) =>
11581158
def rhsOK(tree: Tree): Boolean = tree match {
1159-
case _: TypeBoundsTree | _: Template => false
1159+
case bounds: TypeBoundsTree => !bounds.alias.isEmpty
1160+
case _: Template => false
11601161
case LambdaTypeTree(_, body) => rhsOK(body)
11611162
case _ => true
11621163
}

compiler/src/dotty/tools/dotc/ast/Trees.scala

-2
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,6 @@ object Trees {
814814
extends ProxyTree[T] {
815815
type ThisTree[-T >: Untyped] = Annotated[T]
816816
def forwardTo: Tree[T] = arg
817-
override def disableOverlapChecks = true
818-
// disable overlaps checks since the WithBounds annotation swaps type and annotation.
819817
}
820818

821819
trait WithoutTypeOrPos[-T >: Untyped] extends Tree[T] {

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

-16
Original file line numberDiff line numberDiff line change
@@ -173,22 +173,6 @@ object Annotations {
173173
else None
174174
}
175175

176-
/** Extractor for WithBounds[T] annotations */
177-
object WithBounds {
178-
def unapply(ann: Annotation)(implicit ctx: Context): Option[TypeBounds] =
179-
if (ann.symbol == defn.WithBoundsAnnot) {
180-
import ast.Trees._
181-
// We need to extract the type of the type tree in the New itself.
182-
// The annotation's type has been simplified as the type of an expression,
183-
// which means that `&` or `|` might have been lost.
184-
// Test in pos/reference/opaque.scala
185-
val Apply(TypeApply(Select(New(tpt), nme.CONSTRUCTOR), _), Nil) = ann.tree
186-
val AppliedType(_, lo :: hi :: Nil) = tpt.tpe
187-
Some(TypeBounds(lo, hi))
188-
}
189-
else None
190-
}
191-
192176
def makeSourceFile(path: String)(implicit ctx: Context): Annotation =
193177
apply(defn.SourceFileAnnot, Literal(Constant(path)))
194178
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,6 @@ class Definitions {
784784
@tu lazy val AnnotationDefaultAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.AnnotationDefault")
785785
@tu lazy val BodyAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.Body")
786786
@tu lazy val ChildAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.Child")
787-
@tu lazy val WithBoundsAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.WithBounds")
788787
@tu lazy val CovariantBetweenAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.CovariantBetween")
789788
@tu lazy val ContravariantBetweenAnnot: ClassSymbol = ctx.requiredClass("scala.annotation.internal.ContravariantBetween")
790789
@tu lazy val DeprecatedAnnot: ClassSymbol = ctx.requiredClass("scala.deprecated")

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Scopes.Scope
1111
import dotty.tools.io.AbstractFile
1212
import Decorators.SymbolIteratorDecorator
1313
import ast._
14+
import ast.Trees.{LambdaTypeTree, TypeBoundsTree}
1415
import Trees.Literal
1516
import Variances.Variance
1617
import annotation.tailrec
@@ -433,8 +434,9 @@ object SymDenotations {
433434
*
434435
* @param info Is assumed to be a (lambda-abstracted) right hand side TypeAlias
435436
* of the opaque type definition.
437+
* @param rhs The right hand side tree of the type definition
436438
*/
437-
def opaqueToBounds(info: Type)(given Context): Type =
439+
def opaqueToBounds(info: Type, rhs: tpd.Tree)(given Context): Type =
438440

439441
def setAlias(tp: Type) =
440442
def recur(self: Type): Unit = self match
@@ -446,21 +448,19 @@ object SymDenotations {
446448
recur(owner.asClass.givenSelfType)
447449
end setAlias
448450

449-
def split(tp: Type): (Type, TypeBounds) = tp match
450-
case AnnotatedType(alias, Annotation.WithBounds(bounds)) =>
451-
(alias, bounds)
452-
case tp: HKTypeLambda =>
453-
val (alias1, bounds1) = split(tp.resType)
454-
(tp.derivedLambdaType(resType = alias1),
455-
HKTypeLambda.boundsFromParams(tp.typeParams, bounds1))
451+
def bounds(t: tpd.Tree): TypeBounds = t match
452+
case LambdaTypeTree(_, body) =>
453+
bounds(body)
454+
case TypeBoundsTree(lo, hi, alias) =>
455+
assert(!alias.isEmpty)
456+
TypeBounds(lo.tpe, hi.tpe)
456457
case _ =>
457-
(tp, HKTypeLambda.boundsFromParams(tp.typeParams, TypeBounds.empty))
458+
TypeBounds.empty
458459

459460
info match
460-
case TypeAlias(tp) if isOpaqueAlias && owner.isClass =>
461-
val (alias, bounds) = split(tp)
461+
case TypeAlias(alias) if isOpaqueAlias && owner.isClass =>
462462
setAlias(alias)
463-
bounds
463+
HKTypeLambda.boundsFromParams(alias.typeParams, bounds(rhs))
464464
case _ =>
465465
info
466466
end opaqueToBounds

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -833,11 +833,12 @@ class TreeUnpickler(reader: TastyReader,
833833
override def completerTypeParams(sym: Symbol)(implicit ctx: Context) =
834834
rhs.tpe.typeParams
835835
}
836-
sym.info = sym.opaqueToBounds {
837-
rhs.tpe match
836+
sym.info = sym.opaqueToBounds(
837+
rhs.tpe match {
838838
case _: TypeBounds | _: ClassInfo => checkNonCyclic(sym, rhs.tpe, reportErrors = false)
839839
case _ => rhs.tpe.toBounds
840-
}
840+
},
841+
rhs)
841842
if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
842843
sym.resetFlag(Provisional)
843844
TypeDef(rhs)

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+4-8
Original file line numberDiff line numberDiff line change
@@ -3348,14 +3348,10 @@ object Parsers {
33483348
syntaxError(i"cannot combine lower bound and match type alias", eqOffset)
33493349
}
33503350
case _ =>
3351-
if (mods.is(Opaque)) {
3352-
val annotType = AppliedTypeTree(
3353-
TypeTree(defn.WithBoundsAnnot.typeRef),
3354-
bounds.lo.orElse(TypeTree(defn.NothingType)) ::
3355-
bounds.hi.orElse(TypeTree(defn.AnyType)) :: Nil)
3356-
rhs = Annotated(rhs, ensureApplied(wrapNew(annotType)))
3357-
}
3358-
else syntaxError(i"cannot combine bound and alias", eqOffset)
3351+
if mods.is(Opaque) then
3352+
rhs = TypeBoundsTree(bounds.lo, bounds.hi, rhs)
3353+
else
3354+
syntaxError(i"cannot combine bound and alias", eqOffset)
33593355
}
33603356
makeTypeDef(rhs)
33613357
}

compiler/src/dotty/tools/dotc/typer/Namer.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -997,12 +997,13 @@ class Namer { typer: Typer =>
997997
}
998998
sym.info = dummyInfo2
999999

1000-
val rhsBodyType: TypeBounds = typedAheadType(rhs).tpe.toBounds
1000+
val rhs1 = typedAheadType(rhs)
1001+
val rhsBodyType: TypeBounds = rhs1.tpe.toBounds
10011002
val unsafeInfo = if (isDerived) rhsBodyType else abstracted(rhsBodyType)
10021003
if (isDerived) sym.info = unsafeInfo
10031004
else {
10041005
sym.info = NoCompleter
1005-
sym.info = sym.opaqueToBounds(checkNonCyclic(sym, unsafeInfo, reportErrors = true))
1006+
sym.info = sym.opaqueToBounds(checkNonCyclic(sym, unsafeInfo, reportErrors = true), rhs1)
10061007
}
10071008
if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
10081009
sym.resetFlag(Provisional)

compiler/src/dotty/tools/dotc/typer/Typer.scala

+6-7
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,11 @@ class Typer extends Namer
15151515
val lo2 = if (lo1.isEmpty) typed(untpd.TypeTree(defn.NothingType)) else lo1
15161516
val hi2 = if (hi1.isEmpty) typed(untpd.TypeTree(defn.AnyType)) else hi1
15171517

1518+
if !alias1.isEmpty then
1519+
val bounds = TypeBounds(lo2.tpe, hi2.tpe)
1520+
if !bounds.contains(alias1.tpe) then
1521+
ctx.error(em"type ${alias1.tpe} outside bounds $bounds", tree.sourcePos)
1522+
15181523
val tree1 = assignType(cpy.TypeBoundsTree(tree)(lo2, hi2, alias1), lo2, hi2, alias1)
15191524
if (ctx.mode.is(Mode.Pattern))
15201525
// Associate a pattern-bound type symbol with the wildcard.
@@ -1952,13 +1957,7 @@ class Typer extends Namer
19521957
val arg1 = typed(tree.arg, pt)
19531958
if (ctx.mode is Mode.Type) {
19541959
if arg1.isType then
1955-
val result = assignType(cpy.Annotated(tree)(arg1, annot1), arg1, annot1)
1956-
result.tpe match {
1957-
case AnnotatedType(rhs, Annotation.WithBounds(bounds)) =>
1958-
if (!bounds.contains(rhs)) ctx.error(em"type $rhs outside bounds $bounds", tree.sourcePos)
1959-
case _ =>
1960-
}
1961-
result
1960+
assignType(cpy.Annotated(tree)(arg1, annot1), arg1, annot1)
19621961
else
19631962
assert(ctx.reporter.errorsReported)
19641963
TypeTree(UnspecifiedErrorType)

0 commit comments

Comments
 (0)