Skip to content

Commit 8bf5b49

Browse files
committed
Delay opaque alias checking until PostTyper
When we have a TypeBounds tree that also has an alias, we checked that the alias is within bounds at Typer. This could provoke a CyclicReference when processing opaque type aliases where the type has a bound and also the alias refers back to the type. We avoid the problem by performing the check at PostTyper, analogous to other bounds checks. Fixes scala#16642
1 parent 667d904 commit 8bf5b49

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,13 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
433433
case SingletonTypeTree(ref) =>
434434
Checking.checkRealizable(ref.tpe, ref.srcPos)
435435
super.transform(tree)
436+
case tree: TypeBoundsTree =>
437+
val TypeBoundsTree(lo, hi, alias) = tree
438+
if !alias.isEmpty then
439+
val bounds = TypeBounds(lo.tpe, hi.tpe)
440+
if !bounds.contains(alias.tpe) then
441+
report.error(em"type ${alias.tpe} outside bounds $bounds", tree.srcPos)
442+
super.transform(tree)
436443
case tree: TypeTree =>
437444
tree.withType(
438445
tree.tpe match {

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,10 +2164,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
21642164
val alias1 = typed(alias)
21652165
val lo2 = if (lo1.isEmpty) typed(untpd.TypeTree(defn.NothingType)) else lo1
21662166
val hi2 = if (hi1.isEmpty) typed(untpd.TypeTree(defn.AnyType)) else hi1
2167-
if !alias1.isEmpty then
2168-
val bounds = TypeBounds(lo2.tpe, hi2.tpe)
2169-
if !bounds.contains(alias1.tpe) then
2170-
report.error(em"type ${alias1.tpe} outside bounds $bounds", tree.srcPos)
21712167
assignType(cpy.TypeBoundsTree(tree)(lo2, hi2, alias1), lo2, hi2, alias1)
21722168

21732169
def typedBind(tree: untpd.Bind, pt: Type)(using Context): Tree = {

tests/pos/recursive-opaques.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object Syms:
2+
import SymDs.*
3+
opaque type Symbol <: AnyRef
4+
= SymDenotation
5+
opaque type ClassSymbol <: Symbol
6+
= ClassDenotation
7+
8+
object SymDs:
9+
import Syms.*
10+
class SymDenotation(sym: Symbol)
11+
class ClassDenotation(sym: Symbol) extends SymDenotation(sym)
12+

0 commit comments

Comments
 (0)