From 3c29bbe7953f31f35dd404577cd04b4de95f74bb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 30 Dec 2015 16:12:38 +0100 Subject: Adapt and add tests New test that exhibited the problem is ski.scala. Previously this did not fail with a bounds violation. --- test/dotc/tests.scala | 7 ++- tests/neg/bounds.scala | 4 ++ tests/neg/ski.scala | 136 +++++++++++++++++++++++++++++++++++++++++++++ tests/neg/typedapply.scala | 10 +--- 4 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 tests/neg/ski.scala diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 354bc62d2..bc212bdca 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -108,8 +108,8 @@ class tests extends CompilerTest { @Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2) @Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1) - @Test def neg_bounds() = compileFile(negDir, "bounds", xerrors = 2) - @Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4) + @Test def neg_bounds() = compileFile(negDir, "bounds", xerrors = 3) + @Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 3) @Test def neg_typedIdents() = compileDir(negDir, "typedIdents", xerrors = 2) @Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3) @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 14)(allowDoubleBindings) @@ -167,6 +167,7 @@ class tests extends CompilerTest { @Test def neg_selfreq = compileFile(negDir, "selfreq", xerrors = 2) @Test def neg_singletons = compileFile(negDir, "singletons", xerrors = 8) @Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2) + @Test def neg_ski = compileFile(negDir, "ski", xerrors = 2) @Test def neg_traitParamsTyper = compileFile(negDir, "traitParamsTyper", xerrors = 5) @Test def neg_traitParamsMixin = compileFile(negDir, "traitParamsMixin", xerrors = 2) @Test def neg_firstError = compileFile(negDir, "firstError", xerrors = 3) @@ -185,7 +186,7 @@ class tests extends CompilerTest { .filter(_.nonEmpty) .toList - @Test def compileStdLib = compileList("compileStdLib", stdlibFiles, "-migration" :: scala2mode) + @Test def compileStdLib = compileList("compileStdLib", stdlibFiles, "-migration" :: scala2mode)(allowDeepSubtypes) @Test def compileMixed = compileLine( """tests/pos/B.scala |./scala-scala/src/library/scala/collection/immutable/Seq.scala diff --git a/tests/neg/bounds.scala b/tests/neg/bounds.scala index 8d2cd8259..55eec6941 100644 --- a/tests/neg/bounds.scala +++ b/tests/neg/bounds.scala @@ -5,4 +5,8 @@ object Test { g("foo") new C("bar") } + def baz[X >: Y, Y <: String](x: X, y: Y) = (x, y) + + baz[Int, String](1, "abc") + } diff --git a/tests/neg/ski.scala b/tests/neg/ski.scala new file mode 100644 index 000000000..6510e66ae --- /dev/null +++ b/tests/neg/ski.scala @@ -0,0 +1,136 @@ +trait Term { + type ap[x <: Term] <: Term + type eval <: Term +} + +// The S combinator +trait S extends Term { + type ap[x <: Term] = S1[x] + type eval = S +} +trait S1[x <: Term] extends Term { + type ap[y <: Term] = S2[x, y] + type eval = S1[x] +} +trait S2[x <: Term, y <: Term] extends Term { + type ap[z <: Term] = S3[x, y, z] + type eval = S2[x, y] +} +trait S3[x <: Term, y <: Term, z <: Term] extends Term { + type ap[v <: Term] = eval#ap[v] + type eval = x#ap[z]#ap[y#ap[z]]#eval +} + +// The K combinator +trait K extends Term { + type ap[x <: Term] = K1[x] + type eval = K +} +trait K1[x <: Term] extends Term { + type ap[y <: Term] = K2[x, y] + type eval = K1[x] +} +trait K2[x <: Term, y <: Term] extends Term { + type ap[z <: Term] = eval#ap[z] + type eval = x#eval +} + +// The I combinator +trait I extends Term { + type ap[x <: Term] = I1[x] + type eval = I +} +trait I1[x <: Term] extends Term { + type ap[y <: Term] = eval#ap[y] + type eval = x#eval +} + +// Constants + +trait c extends Term { + type ap[x <: Term] = c + type eval = c +} +trait d extends Term { + type ap[x <: Term] = d + type eval = d +} +trait e extends Term { + type ap[x <: Term] = e + type eval = e +} + +case class Equals[A >: B <:B , B]() + +object Test { + type T1 = Equals[Int, Int] // compiles fine + type T2 = Equals[String, Int] // error + type T3 = Equals[I#ap[c]#eval, c] + type T3a = Equals[I#ap[c]#eval, d]// error + + // Ic -> c + type T4 = Equals[I#ap[c]#eval, c] + + // Kcd -> c + type T5 = Equals[K#ap[c]#ap[d]#eval, c] + + // KKcde -> d + type T6 = Equals[K#ap[K]#ap[c]#ap[d]#ap[e]#eval, d] + + // SIIIc -> Ic + type T7 = Equals[S#ap[I]#ap[I]#ap[I]#ap[c]#eval, c] + + // SKKc -> Ic + type T8 = Equals[S#ap[K]#ap[K]#ap[c]#eval, c] + + // SIIKc -> KKc + type T9 = Equals[S#ap[I]#ap[I]#ap[K]#ap[c]#eval, K#ap[K]#ap[c]#eval] + + // SIKKc -> K(KK)c + type T10 = Equals[S#ap[I]#ap[K]#ap[K]#ap[c]#eval, K#ap[K#ap[K]]#ap[c]#eval] + + // SIKIc -> KIc + type T11 = Equals[S#ap[I]#ap[K]#ap[I]#ap[c]#eval, K#ap[I]#ap[c]#eval] + + // SKIc -> Ic + type T12 = Equals[S#ap[K]#ap[I]#ap[c]#eval, c] + + // R = S(K(SI))K (reverse) + type R = S#ap[K#ap[S#ap[I]]]#ap[K] + type T13 = Equals[R#ap[c]#ap[d]#eval, d#ap[c]#eval] + + type b[a <: Term] = S#ap[K#ap[a]]#ap[S#ap[I]#ap[I]] + + trait A0 extends Term { + type ap[x <: Term] = c + type eval = A0 + } + trait A1 extends Term { + type ap[x <: Term] = x#ap[A0]#eval + type eval = A1 + } + trait A2 extends Term { + type ap[x <: Term] = x#ap[A1]#eval + type eval = A2 + } + + type NN1 = b[R]#ap[b[R]]#ap[A0] + type T13a = Equals[NN1#eval, c] + + // Double iteration + type NN2 = b[R]#ap[b[R]]#ap[A1] + type T14 = Equals[NN2#eval, c] + + // Triple iteration + type NN3 = b[R]#ap[b[R]]#ap[A2] + type T15 = Equals[NN3#eval, c] + + trait An extends Term { + type ap[x <: Term] = x#ap[An]#eval + type eval = An + } + +// Infinite iteration: Smashes scalac's stack + type NNn = b[R]#ap[b[R]]#ap[An] + // type X = Equals[NNn#eval, c] +} diff --git a/tests/neg/typedapply.scala b/tests/neg/typedapply.scala index b80281c9f..706b05da3 100644 --- a/tests/neg/typedapply.scala +++ b/tests/neg/typedapply.scala @@ -2,16 +2,12 @@ object typedapply { def foo[X, Y](x: X, y: Y) = (x, y) - foo[Int](1, "abc") + foo[Int](1, "abc") // error: wrong number of type parameters - foo[Int, String, String](1, "abc") + foo[Int, String, String](1, "abc") // error: wrong number of type parameters def bar(x: Int) = x - bar[Int](1) - - def baz[X >: Y, Y <: String](x: X, y: Y) = (x, y) - - baz[Int, String](1, "abc") + bar[Int](1) // error: does not take parameters } -- cgit v1.2.3