aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-24 17:17:27 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-24 17:17:27 +0100
commit642c5e4500abfc5cef51eee7ed0a98930a24312f (patch)
treeeeda27483b71058860e364ca675bc3a835ebe2cb /src
parent9d6c1040448c48dac2ac3f292fd1e3b65b061b78 (diff)
downloaddotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.tar.gz
dotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.tar.bz2
dotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.zip
Fixed cycle detection.
Now detects the cycles reported by @retronym
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala19
2 files changed, 20 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 8393eb56f..e17b655f9 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -304,6 +304,8 @@ object StdNames {
val ArrayAnnotArg: N = "ArrayAnnotArg"
val Constant: N = "Constant"
val ConstantType: N = "ConstantType"
+ val DummyHi: N = "DummyHi"
+ val DummyLo: N = "DummyLo"
val ExistentialTypeTree: N = "ExistentialTypeTree"
val Flag : N = "Flag"
val Ident: N = "Ident"
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index bc64e10fc..7490e88e9 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -673,7 +673,7 @@ class Namer { typer: Typer =>
def typeDefSig(tdef: TypeDef, sym: Symbol)(implicit ctx: Context): Type = {
completeParams(tdef.tparams)
- sym.info = TypeBounds.empty // avoid cyclic reference errors for F-bounds
+ setDummyInfo(sym)
val tparamSyms = tdef.tparams map symbolOfTree
val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree]
val toParameterize = tparamSyms.nonEmpty && !isDerived
@@ -690,4 +690,21 @@ class Namer { typer: Typer =>
sym.info = NoCompleter
checkNonCyclic(sym, unsafeInfo, reportErrors = true)
}
+
+ /** Temporarily set info of defined type T to
+ *
+ * T >: dummyLo <: dummyHi
+ * type dummyLo, dummyHi
+ *
+ * This is done to avoid cyclic reference errors for F-bounds.
+ * The type is intentionally chosen so that it cannot possibly be
+ * elided when taking a union or intersection.
+ */
+ private def setDummyInfo(sym: Symbol)(implicit ctx: Context): Unit = {
+ def dummyBound(name: TypeName) =
+ ctx.newSymbol(sym.owner, name, Synthetic | Deferred, TypeBounds.empty)
+ val dummyLo = dummyBound(tpnme.DummyLo)
+ val dummyHi = dummyBound(tpnme.DummyHi)
+ sym.info = TypeBounds(TypeRef(NoPrefix, dummyLo), TypeRef(NoPrefix, dummyHi))
+ }
} \ No newline at end of file