Skip to content

Commit 7fa7859

Browse files
committed
Fix problems related to t0039
This test case exercised several problems: 1.)2.) Two ways to run into a cyclic references. Fixed by - assuming an early info when completing a typedef, similarly to what is done for a classdef - doing wellformed bounds checking in a later phase. Failure to check whether arguments correspond to F-bounds. - a substitution was missing.
1 parent ba8d9ea commit 7fa7859

File tree

6 files changed

+24
-8
lines changed

6 files changed

+24
-8
lines changed

src/dotty/tools/dotc/core/Flags.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ object Flags {
467467
final val ExpandedTypeParam = allOf(ExpandedName, TypeParam)
468468

469469
/** A parameter or parameter accessor */
470-
final val ParamOrAccessor = Param | Accessor
470+
final val ParamOrAccessor = Param | ParamAccessor
471471

472472
/** A covariant type parameter instance */
473473
final val LocalCovariant = allOf(Local, Covariant)

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ object SymDenotations {
145145
if (myFlags is Touched) throw new CyclicReference(this)
146146
myFlags |= Touched
147147

148-
completions.println(s"completing ${this.debugString}")
149-
completer.complete(this)
150-
completions.println(s"completed ${this.debugString}")
148+
// completions.println(s"completing ${this.debugString}")
149+
try completer.complete(this)
150+
catch {
151+
case ex: CyclicReference =>
152+
completions.println(s"error while completing ${this.debugString}")
153+
throw ex
154+
}
155+
// completions.println(s"completed ${this.debugString}")
151156
}
152157

153158
protected[dotc] final def info_=(tp: Type) = {

src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,16 @@ trait Checking extends NoChecking {
4545
}
4646

4747
/** Check that type arguments `args` conform to corresponding bounds in `poly` */
48-
override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit =
48+
override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = {
49+
val argTypes = args.tpes
50+
def substituted(tp: Type) = tp.substParams(poly, argTypes)
4951
for ((arg, bounds) <- args zip poly.paramBounds) {
5052
def notConforms(which: String, bound: Type) =
5153
ctx.error(i"Type argument ${arg.tpe} does not conform to $which bound $bound", arg.pos)
52-
if (!(arg.tpe <:< bounds.hi)) notConforms("upper", bounds.hi)
54+
if (!(arg.tpe <:< substituted(bounds.hi))) notConforms("upper", bounds.hi)
5355
if (!(bounds.lo <:< arg.tpe)) notConforms("lower", bounds.lo)
5456
}
57+
}
5558

5659
/** Check that type `tp` is stable.
5760
* @return The type itself

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ class Namer { typer: Typer =>
614614

615615
def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = {
616616
completeParams(tdef.tparams)
617+
sym.info = TypeBounds.empty // avoid cyclic reference errors for F-bounds
617618
val tparamSyms = tdef.tparams map symbolOfTree
618619
val rhsType = typedAheadType(tdef.rhs).tpe
619620

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
699699
val TypeBoundsTree(lo, hi) = desugar.typeBoundsTree(tree)
700700
val lo1 = typed(lo)
701701
val hi1 = typed(hi)
702-
if (!(lo1.tpe <:< hi1.tpe))
703-
ctx.error(i"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos)
702+
if (false) // need to do in later phase, as this might cause a cyclic reference error. See pos/t0039.scala
703+
if (!(lo1.tpe <:< hi1.tpe))
704+
ctx.error(i"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos)
704705
assignType(cpy.TypeBoundsTree(tree, lo1, hi1), lo1, hi1)
705706
}
706707

tests/new/t0039.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
abstract class Extensible[A, This <: Extensible[A, This]](x: A, xs: This) { self: This =>
2+
def mkObj(x: A, xs: This): This;
3+
}
4+
class Fixed[A](x: A, xs: Fixed[A]) extends Extensible[A, Fixed[A]](x, xs) {
5+
def mkObj(x: A, xs: Fixed[A]) = new Fixed(x, xs);
6+
}

0 commit comments

Comments
 (0)