diff options
author | Martin Odersky <odersky@gmail.com> | 2014-11-24 17:17:27 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-11-24 17:17:27 +0100 |
commit | 642c5e4500abfc5cef51eee7ed0a98930a24312f (patch) | |
tree | eeda27483b71058860e364ca675bc3a835ebe2cb | |
parent | 9d6c1040448c48dac2ac3f292fd1e3b65b061b78 (diff) | |
download | dotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.tar.gz dotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.tar.bz2 dotty-642c5e4500abfc5cef51eee7ed0a98930a24312f.zip |
Fixed cycle detection.
Now detects the cycles reported by @retronym
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 19 | ||||
-rw-r--r-- | test/dotc/tests.scala | 2 | ||||
-rw-r--r-- | tests/neg/cycles.scala | 13 |
4 files changed, 34 insertions, 2 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 diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 30de5e15d..1c437e833 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -104,7 +104,7 @@ class tests extends CompilerTest { @Test def neg_badAuxConstr = compileFile(negDir, "badAuxConstr", xerrors = 2) @Test def neg_typetest = compileFile(negDir, "typetest", xerrors = 1) @Test def neg_t1569_failedAvoid = compileFile(negDir, "t1569-failedAvoid", xerrors = 1) - @Test def neg_cycles = compileFile(negDir, "cycles", xerrors = 6) + @Test def neg_cycles = compileFile(negDir, "cycles", xerrors = 8) @Test def neg_boundspropagation = compileFile(negDir, "boundspropagation", xerrors = 4) @Test def dotc = compileDir(dotcDir + "tools/dotc", twice)(allowDeepSubtypes) diff --git a/tests/neg/cycles.scala b/tests/neg/cycles.scala index dbcbe1efb..0dd24c309 100644 --- a/tests/neg/cycles.scala +++ b/tests/neg/cycles.scala @@ -27,3 +27,16 @@ class E { } val x: F#T = ??? } + +class T1 { + type X = (U, U) // cycle + type U = X & Int +} +class T2 { + type X = (U, U) // cycle + type U = X | Int +} +object T12 { + ??? : (T1 {})#U + ??? : (T2 {})#U +} |