Skip to content

Commit 9671bc4

Browse files
committed
Fix #7820: Break cycle when computing completerTypeParams
The following no longer crashes: class C { type F[X <: F[_, _], Y] } But it is still flagged as a cyclic reference error, whereas nsc accepts it. I believe it would be tricky/risky to change dotc's algorithms to accept it as well, and I am not sure it's necessary. Generally, we want to get away from F-bounds, so just accepting the most common use case (F-bounds in method type parameters) is hopefully OK.
1 parent d45fea0 commit 9671bc4

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -944,28 +944,27 @@ class Namer { typer: Typer =>
944944
private var nestedCtx: Context = null
945945
assert(!original.isClassDef)
946946

947-
override def completerTypeParams(sym: Symbol)(implicit ctx: Context): List[TypeSymbol] = {
948-
if (myTypeParams == null) {
947+
override def completerTypeParams(sym: Symbol)(implicit ctx: Context): List[TypeSymbol] =
948+
if myTypeParams == null then
949949
//println(i"completing type params of $sym in ${sym.owner}")
950950
nestedCtx = localContext(sym).setNewScope
951-
myTypeParams = {
952-
implicit val ctx = nestedCtx
953-
def typeParamTrees(tdef: Tree): List[TypeDef] = tdef match {
954-
case TypeDef(_, original) =>
955-
original match {
956-
case LambdaTypeTree(tparams, _) => tparams
957-
case original: DerivedFromParamTree => typeParamTrees(original.watched)
958-
case _ => Nil
959-
}
960-
case _ => Nil
961-
}
962-
val tparams = typeParamTrees(original)
963-
completeParams(tparams)
964-
tparams.map(symbolOfTree(_).asType)
965-
}
966-
}
951+
given Context = nestedCtx
952+
953+
def typeParamTrees(tdef: Tree): List[TypeDef] = tdef match
954+
case TypeDef(_, original) =>
955+
original match
956+
case LambdaTypeTree(tparams, _) => tparams
957+
case original: DerivedFromParamTree => typeParamTrees(original.watched)
958+
case _ => Nil
959+
case _ => Nil
960+
961+
val tparams = typeParamTrees(original)
962+
index(tparams)
963+
myTypeParams = tparams.map(symbolOfTree(_).asType)
964+
for param <- tparams do typedAheadExpr(param)
965+
end if
967966
myTypeParams
968-
}
967+
end completerTypeParams
969968

970969
override protected def typeSig(sym: Symbol): Type =
971970
typeDefSig(original, sym, completerTypeParams(sym)(ictx))(nestedCtx)

tests/neg/i7820.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait A1 { type F[X <: F[_, _], Y] } // error: cyclic reference involving type F
2+
trait A2 { type F[X <: F, Y] } // error: cyclic reference involving type F
3+
trait A3 { type F[X >: F, Y] } // error: cyclic reference involving type F

0 commit comments

Comments
 (0)