From bb90b26fbca27f432ade46ae572b82e1b8027b19 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 15:27:50 +0100 Subject: [PATCH 01/22] Tests t01xx and t02xx Test t0288 moved to disabled due to lack of Java interop. Test t0273 fixed by relaxing double def condition: We only regard two definitions that define the same name and have exactly the same signature as double definitions. Previously, signatures that defined the same parameters were also excluded. --- src/dotty/tools/dotc/typer/Checking.scala | 2 +- test/dotc/tests.scala | 4 ++-- tests/{untried => disabled/java-interop}/pos/t0288/Foo.scala | 0 tests/{untried => disabled/java-interop}/pos/t0288/Outer.java | 0 tests/{untried => }/pos/t0123.scala | 0 tests/{untried => }/pos/t0154.scala | 0 tests/{untried => }/pos/t0165.scala | 0 tests/{untried => }/pos/t0204.scala | 0 tests/{untried => }/pos/t0227.scala | 0 tests/{untried => }/pos/t0231.scala | 0 tests/{untried => }/pos/t0273.scala | 1 + 11 files changed, 4 insertions(+), 3 deletions(-) rename tests/{untried => disabled/java-interop}/pos/t0288/Foo.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t0288/Outer.java (100%) rename tests/{untried => }/pos/t0123.scala (100%) rename tests/{untried => }/pos/t0154.scala (100%) rename tests/{untried => }/pos/t0165.scala (100%) rename tests/{untried => }/pos/t0204.scala (100%) rename tests/{untried => }/pos/t0227.scala (100%) rename tests/{untried => }/pos/t0231.scala (100%) rename tests/{untried => }/pos/t0273.scala (65%) diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 36822cb851b5..a81e4079a1c5 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -124,7 +124,7 @@ trait Checking extends NoChecking { for (decl <- cls.info.decls) { for (other <- seen(decl.name)) { typr.println(i"conflict? $decl $other") - if (decl.signature matches other.signature) { + if (decl.signature == other.signature) { def doubleDefError(decl: Symbol, other: Symbol): Unit = { def ofType = if (decl.isType) "" else i": ${other.info}" def explanation = diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 1ddd0a578d75..15d7432ab085 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -47,13 +47,13 @@ class tests extends CompilerTest { @Test def pos_approximateUnion = compileFile(posDir, "approximateUnion", twice) */ @Test def pos_all = compileFiles(posDir, twice) - @Test def pos_new = compileFiles(newDir, "-Xprompt" :: Nil) + @Test def new_all = compileFiles(newDir, twice) @Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1) @Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4) @Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2) @Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3) - @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 10) + @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 6) @Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2) @Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2) @Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3) diff --git a/tests/untried/pos/t0288/Foo.scala b/tests/disabled/java-interop/pos/t0288/Foo.scala similarity index 100% rename from tests/untried/pos/t0288/Foo.scala rename to tests/disabled/java-interop/pos/t0288/Foo.scala diff --git a/tests/untried/pos/t0288/Outer.java b/tests/disabled/java-interop/pos/t0288/Outer.java similarity index 100% rename from tests/untried/pos/t0288/Outer.java rename to tests/disabled/java-interop/pos/t0288/Outer.java diff --git a/tests/untried/pos/t0123.scala b/tests/pos/t0123.scala similarity index 100% rename from tests/untried/pos/t0123.scala rename to tests/pos/t0123.scala diff --git a/tests/untried/pos/t0154.scala b/tests/pos/t0154.scala similarity index 100% rename from tests/untried/pos/t0154.scala rename to tests/pos/t0154.scala diff --git a/tests/untried/pos/t0165.scala b/tests/pos/t0165.scala similarity index 100% rename from tests/untried/pos/t0165.scala rename to tests/pos/t0165.scala diff --git a/tests/untried/pos/t0204.scala b/tests/pos/t0204.scala similarity index 100% rename from tests/untried/pos/t0204.scala rename to tests/pos/t0204.scala diff --git a/tests/untried/pos/t0227.scala b/tests/pos/t0227.scala similarity index 100% rename from tests/untried/pos/t0227.scala rename to tests/pos/t0227.scala diff --git a/tests/untried/pos/t0231.scala b/tests/pos/t0231.scala similarity index 100% rename from tests/untried/pos/t0231.scala rename to tests/pos/t0231.scala diff --git a/tests/untried/pos/t0273.scala b/tests/pos/t0273.scala similarity index 65% rename from tests/untried/pos/t0273.scala rename to tests/pos/t0273.scala index ac02b8c15a6e..10f4268288fb 100644 --- a/tests/untried/pos/t0273.scala +++ b/tests/pos/t0273.scala @@ -3,4 +3,5 @@ class A object Test { def a = () => () def a[T] = (p:A) => () +def main(args: Array[String]) = () } From ee1251f37f844bdb4f4ea69177e8183ad74e7b3d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 17:30:04 +0100 Subject: [PATCH 02/22] Fix of t0438 - lambdas and eta expansion Two fixes were needed 1) When typing a function value (x1: T1, ..., xN: Tn) => e, don't unconditionally issue an error if the expected function type arity is different from N. Instead, issue an error only if one of the types T1, ..., Tn is absent. The idea is that only then we need to consult the expected type for the parameter type. This allows to fix the problem later by an implicit conversion applied to the function value. 2) When eta-expanding, do not automtically take the arity of the expected function value as the arity of the generated lambda. Instead, take the method's arity, and copy method parameters into the lambda in case the arities are different. --- src/dotty/tools/dotc/typer/EtaExpansion.scala | 28 +++++++++++++------ src/dotty/tools/dotc/typer/Typer.scala | 11 ++++---- tests/{untried => }/pos/t0438.scala | 2 +- tests/untried/pos/t0301.scala | 12 -------- tests/untried/pos/t0304.scala | 5 ---- tests/untried/pos/t0305.scala | 7 ----- tests/untried/pos/t0453.scala | 6 ---- 7 files changed, 26 insertions(+), 45 deletions(-) rename tests/{untried => }/pos/t0438.scala (85%) delete mode 100644 tests/untried/pos/t0301.scala delete mode 100644 tests/untried/pos/t0304.scala delete mode 100644 tests/untried/pos/t0305.scala delete mode 100644 tests/untried/pos/t0453.scala diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala index 46a1d35832e0..099dd943a608 100644 --- a/src/dotty/tools/dotc/typer/EtaExpansion.scala +++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala @@ -95,25 +95,35 @@ object EtaExpansion { /** Eta-expanding a tree means converting a method reference to a function value. * @param tree The tree to expand - * @param paramNames The names of the parameters to use in the expansion - * Let `paramNames` be x1, ..., xn + * @param mt The type of the method reference + * @param xarity The arity of the expected function type * and assume the lifted application of `tree` (@see liftApp) is * * { val xs = es; expr } * - * Then the eta-expansion is + * If xarity matches the number of parameters in `mt`, the eta-expansion is * - * { val xs = es; (x1, ..., xn) => expr(xx1, ..., xn) } + * { val xs = es; (x1, ..., xn) => expr(x1, ..., xn) } * - * This is an untyped tree, with `es` and `expr` as typed splices. + * Note that the function value's parameters are untyped, hence the type will + * be supplied by the environment (or if missing be supplied by the target + * method as a fallback). On the other hand, if `xarity` is different from + * the number of parameters in `mt`, then we cannot propagate parameter types + * from the expected type, and we fallback to using the method's original + * parameter types instead. + * + * In either case, the result is an untyped tree, with `es` and `expr` as typed splices. */ - def etaExpand(tree: Tree, paramNames: List[TermName])(implicit ctx: Context): untpd.Tree = { + def etaExpand(tree: Tree, mt: MethodType, xarity: Int)(implicit ctx: Context): untpd.Tree = { import untpd._ val defs = new mutable.ListBuffer[tpd.Tree] val lifted: Tree = TypedSplice(liftApp(defs, tree)) - val params = paramNames map (name => - ValDef(Modifiers(Synthetic | Param), name, TypeTree(), EmptyTree).withPos(tree.pos)) - val ids = paramNames map (name => + val paramTypes: List[Tree] = + if (mt.paramTypes.length == xarity) mt.paramTypes map (_ => TypeTree()) + else mt.paramTypes map TypeTree + val params = (mt.paramNames, paramTypes).zipped.map((name, tpe) => + ValDef(Modifiers(Synthetic | Param), name, TypeTree(tpe), EmptyTree).withPos(tree.pos)) + val ids = mt.paramNames map (name => Ident(name).withPos(tree.pos)) val body = Apply(lifted, ids) val fn = untpd.Function(params, body) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 67e5c59024fe..4fdee86a3a1f 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -496,14 +496,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit errorType(s"missing parameter type for parameter ${param.name}$ofFun, expected = ${pt.show}", param.pos) } - if (protoFormals.length != params.length) - ctx.error(s"wrong number of parameters, expected: ${protoFormals.length}", tree.pos) + def protoFormal(i: Int): Type = + if (protoFormals.length == params.length) protoFormals(i) + else errorType(s"wrong number of parameters, expected: ${protoFormals.length}", tree.pos) val inferredParams: List[untpd.ValDef] = - for ((param, formal) <- params zip protoFormals) yield + for ((param, i) <- params.zipWithIndex) yield if (!param.tpt.isEmpty) param else { - val paramTpt = untpd.TypeTree(inferredParamType(param, formal)) + val paramTpt = untpd.TypeTree(inferredParamType(param, protoFormal(i))) cpy.ValDef(param, param.mods, param.name, paramTpt, param.rhs) } @@ -1135,7 +1136,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit else if (pt eq AnyFunctionProto) wtp.paramTypes.length else -1 if (arity >= 0 && !tree.symbol.isConstructor) - typed(etaExpand(tree, wtp.paramNames take arity), pt) + typed(etaExpand(tree, wtp, arity), pt) else if (wtp.paramTypes.isEmpty) adaptInterpolated(tpd.Apply(tree, Nil), pt) else diff --git a/tests/untried/pos/t0438.scala b/tests/pos/t0438.scala similarity index 85% rename from tests/untried/pos/t0438.scala rename to tests/pos/t0438.scala index dd1e7f9a9f9b..1615e3da7074 100644 --- a/tests/untried/pos/t0438.scala +++ b/tests/pos/t0438.scala @@ -5,7 +5,7 @@ class Foo { def foo(f: ((Int, Int)) => Int) = f def bar(x: Int, y: Int) = x + y - foo({ (x: Int, y: Int) => x + y }) // works + foo(((x: Int, y: Int) => x + y)) // works foo(pair2fun2(bar _)) // works foo(bar _) // error foo(bar) // same error diff --git a/tests/untried/pos/t0301.scala b/tests/untried/pos/t0301.scala deleted file mode 100644 index 24b4776010ab..000000000000 --- a/tests/untried/pos/t0301.scala +++ /dev/null @@ -1,12 +0,0 @@ -package fos - -abstract class Expr -case class Var() extends Expr - -object Analyzer { - def substitution(expr: Expr, cls: (Var,Var)): Expr = - expr match { - case cls._2 => cls._1 // source of the error - case _ => expr - } -} diff --git a/tests/untried/pos/t0304.scala b/tests/untried/pos/t0304.scala deleted file mode 100644 index 607a115db28e..000000000000 --- a/tests/untried/pos/t0304.scala +++ /dev/null @@ -1,5 +0,0 @@ -object O { - def f1 = -1; - def f2 = 0-1; - def f3 = f1 + f2; -} diff --git a/tests/untried/pos/t0305.scala b/tests/untried/pos/t0305.scala deleted file mode 100644 index 4838b1fcf867..000000000000 --- a/tests/untried/pos/t0305.scala +++ /dev/null @@ -1,7 +0,0 @@ -object Test extends App { - - def foo(is:Int*) = 1; - def foo(i:Int) = 2; - - assert(foo( List(3):_* ) == 1) -} diff --git a/tests/untried/pos/t0453.scala b/tests/untried/pos/t0453.scala deleted file mode 100644 index dfacc5eed7c6..000000000000 --- a/tests/untried/pos/t0453.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test { - val foo = new { - trait Bar - def l () : Bar = { new Bar {} } - } -} From 4b57b3d877ca7b66b4cb2e588493d2933ae041bf Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 18:38:03 +0100 Subject: [PATCH 03/22] Fix of t0504: _root_ not found _root_ is now entered into an enclosing context. --- src/dotty/tools/dotc/Compiler.scala | 17 +++++++++++++++-- tests/{untried => }/pos/t0504.scala | 0 2 files changed, 15 insertions(+), 2 deletions(-) rename tests/{untried => }/pos/t0504.scala (100%) diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index c2f21f63908a..286ed34564ac 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -5,6 +5,7 @@ import core._ import Contexts._ import Periods._ import Symbols._ +import Scopes._ import typer.{FrontEnd, Typer, Mode, ImportInfo} import reporting.ConsoleReporter import dotty.tools.dotc.core.Phases.Phase @@ -28,16 +29,28 @@ class Compiler { runId += 1; runId } + /** Produces the following contexts, from outermost to innermost + * + * bootStrap: A context with next available runId and a scope consisting of + * the RootPackage _root_ + * start A context with RootClass as owner and the necessary initializations + * for type checking. + * imports For each element of RootImports, an import context + */ def rootContext(implicit ctx: Context): Context = { ctx.definitions.init(ctx) ctx.usePhases(phases) - val start = ctx.fresh + val rootScope = new MutableScope + val bootstrap = ctx.fresh .withPeriod(Period(nextRunId, FirstPhaseId)) + .withScope(rootScope) + rootScope.enter(ctx.definitions.RootPackage)(bootstrap) + val start = bootstrap.fresh .withOwner(defn.RootClass) .withTyper(new Typer) .withNewMode(Mode.ImplicitsEnabled) .withTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true)) - ctx.definitions.init(start) + ctx.definitions.init(start) // set context of definitions to start def addImport(ctx: Context, sym: Symbol) = ctx.fresh.withImportInfo(ImportInfo.rootImport(sym)(ctx)) (start.withRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport) diff --git a/tests/untried/pos/t0504.scala b/tests/pos/t0504.scala similarity index 100% rename from tests/untried/pos/t0504.scala rename to tests/pos/t0504.scala From 6f1ef32d728320c31cc59daad0f4849c9cd0a87c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 18:39:08 +0100 Subject: [PATCH 04/22] Fix of t0591: implicitly A debug assertion in implicitSearch gave a false alarm and was removed. --- src/dotty/tools/dotc/typer/Implicits.scala | 5 ----- tests/{untried => }/pos/t0591.scala | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) rename tests/{untried => }/pos/t0591.scala (79%) diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index b939c1b0d8f5..d0aa8d546d56 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -419,11 +419,6 @@ trait Implicits { self: Typer => /** An implicit search; parameters as in `inferImplicit` */ class ImplicitSearch(protected val pt: Type, protected val argument: Tree, pos: Position)(implicit ctx: Context) { - pt match { - case pt: TypeVar => assert(pt.isInstantiated) //!!! DEBUG - case _ => - } - private def nestedContext = ctx.fresh.withNewMode(ctx.mode &~ Mode.ImplicitsEnabled) private def implicitProto(resultType: Type, f: Type => Type) = diff --git a/tests/untried/pos/t0591.scala b/tests/pos/t0591.scala similarity index 79% rename from tests/untried/pos/t0591.scala rename to tests/pos/t0591.scala index 6cb5e29b48dc..0a39cab1bfeb 100644 --- a/tests/untried/pos/t0591.scala +++ b/tests/pos/t0591.scala @@ -1,5 +1,5 @@ object Test { - def implicitly[T](implicit t : T) = t + def implicitly[T](implicit t : T): T = t implicit def perhaps[T](implicit t : T) : Option[T] = Some(t) implicit val hello: String = "Hello" implicitly[String] From 6436fa67e561442ef2e2d9b99852a50f323ccacc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 18:39:36 +0100 Subject: [PATCH 05/22] More tests Added more tests which all pass, except for tests in disabled and pending. t0694 went from pos to neg, because the kind of alias type used in t0695 is no longer supported. --- test/dotc/tests.scala | 1 + tests/disabled/java-interop/pos/t0695/JavaClass.java | 5 +++++ tests/disabled/java-interop/pos/t0695/Test.scala | 3 +++ tests/neg/t0654.scala | 5 +++++ tests/{untried => pending}/pos/t0625.scala | 0 tests/pos/ostermann.scala | 3 +++ tests/pos/t0301.scala | 12 ++++++++++++ tests/pos/t0304.scala | 5 +++++ tests/pos/t0305.scala | 7 +++++++ tests/pos/t0453.scala | 6 ++++++ tests/{untried => }/pos/t0586.scala | 0 tests/{untried => }/pos/t0599.scala | 0 tests/{untried => }/pos/t0644.scala | 0 tests/{untried => }/pos/t0674.scala | 0 tests/untried/pos/t0654.scala | 5 ----- 15 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 tests/disabled/java-interop/pos/t0695/JavaClass.java create mode 100644 tests/disabled/java-interop/pos/t0695/Test.scala create mode 100644 tests/neg/t0654.scala rename tests/{untried => pending}/pos/t0625.scala (100%) create mode 100644 tests/pos/ostermann.scala create mode 100644 tests/pos/t0301.scala create mode 100644 tests/pos/t0304.scala create mode 100644 tests/pos/t0305.scala create mode 100644 tests/pos/t0453.scala rename tests/{untried => }/pos/t0586.scala (100%) rename tests/{untried => }/pos/t0599.scala (100%) rename tests/{untried => }/pos/t0644.scala (100%) rename tests/{untried => }/pos/t0674.scala (100%) delete mode 100644 tests/untried/pos/t0654.scala diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 15d7432ab085..ee05dd15cf49 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -62,6 +62,7 @@ class tests extends CompilerTest { @Test def neg_companions = compileFile(negDir, "companions", xerrors = 1) @Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 3) @Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3) + @Test def neg_t0654_polyalias = compileFile(negDir, "t0654", xerrors = 2) @Test def dotc = compileDir(dotcDir + "tools/dotc", twice) @Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice) diff --git a/tests/disabled/java-interop/pos/t0695/JavaClass.java b/tests/disabled/java-interop/pos/t0695/JavaClass.java new file mode 100644 index 000000000000..a765f7e3240f --- /dev/null +++ b/tests/disabled/java-interop/pos/t0695/JavaClass.java @@ -0,0 +1,5 @@ +public class JavaClass { + class InnerClass { + public A method() { return null; } + } +} diff --git a/tests/disabled/java-interop/pos/t0695/Test.scala b/tests/disabled/java-interop/pos/t0695/Test.scala new file mode 100644 index 000000000000..7318867bf7c7 --- /dev/null +++ b/tests/disabled/java-interop/pos/t0695/Test.scala @@ -0,0 +1,3 @@ +object Test extends JavaClass[AnyRef] { + var field: InnerClass = null +} diff --git a/tests/neg/t0654.scala b/tests/neg/t0654.scala new file mode 100644 index 000000000000..52dbbb014c03 --- /dev/null +++ b/tests/neg/t0654.scala @@ -0,0 +1,5 @@ +object Test { + class Foo[T] + type C[T] = Foo[_ <: T] // error: parameter type T of type alias does not appear as type argument of the aliased class Foo + val a: C[AnyRef] = new Foo[AnyRef] // follow-on error: wrong number of type arguments for Test.C, should be 0 +} diff --git a/tests/untried/pos/t0625.scala b/tests/pending/pos/t0625.scala similarity index 100% rename from tests/untried/pos/t0625.scala rename to tests/pending/pos/t0625.scala diff --git a/tests/pos/ostermann.scala b/tests/pos/ostermann.scala new file mode 100644 index 000000000000..f3acafc727a9 --- /dev/null +++ b/tests/pos/ostermann.scala @@ -0,0 +1,3 @@ +trait A { def foo(a: A) : Unit } + +trait C extends A { override def foo(a: A with Any) : Unit } diff --git a/tests/pos/t0301.scala b/tests/pos/t0301.scala new file mode 100644 index 000000000000..24b4776010ab --- /dev/null +++ b/tests/pos/t0301.scala @@ -0,0 +1,12 @@ +package fos + +abstract class Expr +case class Var() extends Expr + +object Analyzer { + def substitution(expr: Expr, cls: (Var,Var)): Expr = + expr match { + case cls._2 => cls._1 // source of the error + case _ => expr + } +} diff --git a/tests/pos/t0304.scala b/tests/pos/t0304.scala new file mode 100644 index 000000000000..607a115db28e --- /dev/null +++ b/tests/pos/t0304.scala @@ -0,0 +1,5 @@ +object O { + def f1 = -1; + def f2 = 0-1; + def f3 = f1 + f2; +} diff --git a/tests/pos/t0305.scala b/tests/pos/t0305.scala new file mode 100644 index 000000000000..4838b1fcf867 --- /dev/null +++ b/tests/pos/t0305.scala @@ -0,0 +1,7 @@ +object Test extends App { + + def foo(is:Int*) = 1; + def foo(i:Int) = 2; + + assert(foo( List(3):_* ) == 1) +} diff --git a/tests/pos/t0453.scala b/tests/pos/t0453.scala new file mode 100644 index 000000000000..dfacc5eed7c6 --- /dev/null +++ b/tests/pos/t0453.scala @@ -0,0 +1,6 @@ +object Test { + val foo = new { + trait Bar + def l () : Bar = { new Bar {} } + } +} diff --git a/tests/untried/pos/t0586.scala b/tests/pos/t0586.scala similarity index 100% rename from tests/untried/pos/t0586.scala rename to tests/pos/t0586.scala diff --git a/tests/untried/pos/t0599.scala b/tests/pos/t0599.scala similarity index 100% rename from tests/untried/pos/t0599.scala rename to tests/pos/t0599.scala diff --git a/tests/untried/pos/t0644.scala b/tests/pos/t0644.scala similarity index 100% rename from tests/untried/pos/t0644.scala rename to tests/pos/t0644.scala diff --git a/tests/untried/pos/t0674.scala b/tests/pos/t0674.scala similarity index 100% rename from tests/untried/pos/t0674.scala rename to tests/pos/t0674.scala diff --git a/tests/untried/pos/t0654.scala b/tests/untried/pos/t0654.scala deleted file mode 100644 index 07b4e727948d..000000000000 --- a/tests/untried/pos/t0654.scala +++ /dev/null @@ -1,5 +0,0 @@ -object Test { - class Foo[T] - type C[T] = Foo[_ <: T] - val a: C[AnyRef] = new Foo[AnyRef] -} From 2c2ab10958e27ced276c9906f18a67c1eddd1928 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 21:37:51 +0100 Subject: [PATCH 06/22] Fix of t0786: view bounds Previously, only implicit method types were eligible as views. This is too strict, as it rules out view bounds. We now also consider types that derive from Function1. The reason for not allowing any type is that this would cause us to check many more types for applicability when an implicit view is searched. --- src/dotty/tools/dotc/typer/Implicits.scala | 2 +- tests/{untried => }/pos/t0786.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename tests/{untried => }/pos/t0786.scala (67%) diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index d0aa8d546d56..fe1c938c9b44 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -65,7 +65,7 @@ object Implicits { case tpw => //if (ctx.typer.isApplicable(tp, argType :: Nil, resultType)) // println(i"??? $tp is applicable to $this / typeSymbol = ${tpw.typeSymbol}") - true + !tpw.derivesFrom(defn.FunctionClass(1)) } def discardForValueType(tpw: Type): Boolean = tpw match { diff --git a/tests/untried/pos/t0786.scala b/tests/pos/t0786.scala similarity index 67% rename from tests/untried/pos/t0786.scala rename to tests/pos/t0786.scala index b347b0bc5403..b320de0ed6c3 100644 --- a/tests/untried/pos/t0786.scala +++ b/tests/pos/t0786.scala @@ -7,15 +7,15 @@ object ImplicitProblem { def eval: Int } - implicit def toRep0(n: Int): ImplicitProblem.Rep[Int] = new Rep[Int] { + implicit def toRep0(n: Int): Rep[Int] = new Rep[Int] { def eval = 0 } - implicit def toRepN[T](n: M[T])(implicit f: T => Rep[T]): ImplicitProblem.Rep[ImplicitProblem.M[T]] = new Rep[M[T]] { + implicit def toRepN[T](n: M[T])(implicit f: T => Rep[T]): Rep[M[T]] = new Rep[M[T]] { def eval = f(nullval[T]).eval + 1 } - def depth[T <% Rep[T]](n: T) = n.eval + def depth[T](n: T)(implicit ev: T => Rep[T]) = n.eval def main(args: Array[String]): Unit = { println(depth(nullval[M[Int]])) // (1) this works From 7bf837c79315e5db7e049f3ffeb6c6842d18880c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 21:39:18 +0100 Subject: [PATCH 07/22] Fix of t0774: empty file Was previously wrapped in a package but the resulting tree had no position, which caused a Typer assertion. If now represented as EmptyTree. --- src/dotty/tools/dotc/parsing/Parsers.scala | 1 + tests/pos/t0612/C.scala | 6 ++++++ tests/pos/t0612/Ob.scala | 5 +++++ tests/{untried => }/pos/t0774/deathname.scala | 0 tests/{untried => }/pos/t0774/unrelated.scala | 0 5 files changed, 12 insertions(+) create mode 100644 tests/pos/t0612/C.scala create mode 100644 tests/pos/t0612/Ob.scala rename tests/{untried => }/pos/t0774/deathname.scala (100%) rename tests/{untried => }/pos/t0774/unrelated.scala (100%) diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index aea019bed612..7bc7d55161c4 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2071,6 +2071,7 @@ object Parsers { topstats() match { case List(stat @ PackageDef(_, _)) => stat + case Nil => EmptyTree // without this case we'd get package defs without positions case stats => PackageDef(Ident(nme.EMPTY_PACKAGE), stats) } } diff --git a/tests/pos/t0612/C.scala b/tests/pos/t0612/C.scala new file mode 100644 index 000000000000..1f260a5b02ea --- /dev/null +++ b/tests/pos/t0612/C.scala @@ -0,0 +1,6 @@ +package test +package app + +class C { + Ob.f +} diff --git a/tests/pos/t0612/Ob.scala b/tests/pos/t0612/Ob.scala new file mode 100644 index 000000000000..d12e64963de8 --- /dev/null +++ b/tests/pos/t0612/Ob.scala @@ -0,0 +1,5 @@ +package test + +object Ob { + protected[test] def f: Unit = {} +} diff --git a/tests/untried/pos/t0774/deathname.scala b/tests/pos/t0774/deathname.scala similarity index 100% rename from tests/untried/pos/t0774/deathname.scala rename to tests/pos/t0774/deathname.scala diff --git a/tests/untried/pos/t0774/unrelated.scala b/tests/pos/t0774/unrelated.scala similarity index 100% rename from tests/untried/pos/t0774/unrelated.scala rename to tests/pos/t0774/unrelated.scala From 90f430bfb9178e49dc112bacf5b250d0780dcd1e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 21:42:10 +0100 Subject: [PATCH 08/22] More tests which all pass. --- .gitignore | 1 + tests/{untried => }/pos/t0710.scala | 0 tests/{untried => }/pos/t0770.scala | 0 tests/{untried => }/pos/t0851.scala | 2 +- tests/{untried => }/pos/t0872.scala | 0 tests/{untried => }/pos/t0904.scala | 0 tests/pos/t0905.scala | 6 ++++++ tests/untried/pos/t0612/C.scala | 6 ------ tests/untried/pos/t0612/Ob.scala | 5 ----- tests/untried/pos/t0695/JavaClass.java | 5 ----- tests/untried/pos/t0695/Test.scala | 3 --- tests/untried/pos/t0905.scala | 6 ------ 12 files changed, 8 insertions(+), 26 deletions(-) rename tests/{untried => }/pos/t0710.scala (100%) rename tests/{untried => }/pos/t0770.scala (100%) rename tests/{untried => }/pos/t0851.scala (78%) rename tests/{untried => }/pos/t0872.scala (100%) rename tests/{untried => }/pos/t0904.scala (100%) create mode 100644 tests/pos/t0905.scala delete mode 100644 tests/untried/pos/t0612/C.scala delete mode 100644 tests/untried/pos/t0612/Ob.scala delete mode 100644 tests/untried/pos/t0695/JavaClass.java delete mode 100644 tests/untried/pos/t0695/Test.scala delete mode 100644 tests/untried/pos/t0905.scala diff --git a/.gitignore b/.gitignore index af401d5680ed..90009066ca8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.class *.log +*~ # sbt specific dist/* diff --git a/tests/untried/pos/t0710.scala b/tests/pos/t0710.scala similarity index 100% rename from tests/untried/pos/t0710.scala rename to tests/pos/t0710.scala diff --git a/tests/untried/pos/t0770.scala b/tests/pos/t0770.scala similarity index 100% rename from tests/untried/pos/t0770.scala rename to tests/pos/t0770.scala diff --git a/tests/untried/pos/t0851.scala b/tests/pos/t0851.scala similarity index 78% rename from tests/untried/pos/t0851.scala rename to tests/pos/t0851.scala index fcfdba51eba5..fdc504af75c5 100644 --- a/tests/untried/pos/t0851.scala +++ b/tests/pos/t0851.scala @@ -5,7 +5,7 @@ object test1 { def apply(t : T) = (s:T2) => f(t,s) def apply(p : (T,T2)) = f(p._1,p._2) } - implicit def g[T](f : (T,String) => String): test.test1.Foo[T,String] = Foo(f) + implicit def g[T](f : (T,String) => String): Foo[T, String] = Foo(f) def main(args : Array[String]) : Unit = { val f = (x:Int,s:String) => s + x println(f(1)) diff --git a/tests/untried/pos/t0872.scala b/tests/pos/t0872.scala similarity index 100% rename from tests/untried/pos/t0872.scala rename to tests/pos/t0872.scala diff --git a/tests/untried/pos/t0904.scala b/tests/pos/t0904.scala similarity index 100% rename from tests/untried/pos/t0904.scala rename to tests/pos/t0904.scala diff --git a/tests/pos/t0905.scala b/tests/pos/t0905.scala new file mode 100644 index 000000000000..3800c6e0ba10 --- /dev/null +++ b/tests/pos/t0905.scala @@ -0,0 +1,6 @@ +object Test { + trait A[T] + def f(implicit p: A[_]) = null + implicit val x: A[_] = null + println(f) +} diff --git a/tests/untried/pos/t0612/C.scala b/tests/untried/pos/t0612/C.scala deleted file mode 100644 index 1f260a5b02ea..000000000000 --- a/tests/untried/pos/t0612/C.scala +++ /dev/null @@ -1,6 +0,0 @@ -package test -package app - -class C { - Ob.f -} diff --git a/tests/untried/pos/t0612/Ob.scala b/tests/untried/pos/t0612/Ob.scala deleted file mode 100644 index d12e64963de8..000000000000 --- a/tests/untried/pos/t0612/Ob.scala +++ /dev/null @@ -1,5 +0,0 @@ -package test - -object Ob { - protected[test] def f: Unit = {} -} diff --git a/tests/untried/pos/t0695/JavaClass.java b/tests/untried/pos/t0695/JavaClass.java deleted file mode 100644 index a765f7e3240f..000000000000 --- a/tests/untried/pos/t0695/JavaClass.java +++ /dev/null @@ -1,5 +0,0 @@ -public class JavaClass { - class InnerClass { - public A method() { return null; } - } -} diff --git a/tests/untried/pos/t0695/Test.scala b/tests/untried/pos/t0695/Test.scala deleted file mode 100644 index 7318867bf7c7..000000000000 --- a/tests/untried/pos/t0695/Test.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends JavaClass[AnyRef] { - var field: InnerClass = null -} diff --git a/tests/untried/pos/t0905.scala b/tests/untried/pos/t0905.scala deleted file mode 100644 index 8cd84759cf79..000000000000 --- a/tests/untried/pos/t0905.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test { - trait A[T] - def f(implicit p: A[T] forSome { type T } ) = null - implicit val x: A[T] forSome { type T } = null - println(f) -} From 77d1c83ff67894bf87d37bfb8982d818fdc88f73 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 17 Mar 2014 15:53:21 +0100 Subject: [PATCH 09/22] Fix of t0625 - compare method types Method type comparison via <:< yielded false if the signatures of the two method types differed. This is too strict, because methods can have the same parametyers but different result types and still be in a subtype relationship. We now onyl demand that the sighatures have the same parameters. --- src/dotty/tools/dotc/core/TypeComparer.scala | 8 ++++++-- tests/{pending => }/pos/t0625.scala | 0 2 files changed, 6 insertions(+), 2 deletions(-) rename tests/{pending => }/pos/t0625.scala (100%) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index cfb9477c3a11..612b78f79ed5 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -201,7 +201,11 @@ class TypeComparer(initctx: Context) extends DotClass { def isNonBottomSubType(tp1: Type, tp2: Type): Boolean = !(tp2 isRef NothingClass) && isSubType(tp1, tp2) - def isSubType(tp1: Type, tp2: Type): Boolean = /*>|>*/ ctx.traceIndented(s"isSubType ${tp1.show} <:< ${tp2.show}", subtyping) /*<|<*/ { + private def traceInfo(tp1: Type, tp2: Type) = + s"${tp1.show} <:< ${tp2.show}" + + (if (ctx.settings.verbose.value) s"${tp1.getClass} ${tp2.getClass}" else "") + + def isSubType(tp1: Type, tp2: Type): Boolean = /*>|>*/ ctx.traceIndented(s"isSubType ${traceInfo(tp1, tp2)}", subtyping) /*<|<*/ { if (tp2 eq NoType) false else if (tp1 eq tp2) true else { @@ -467,7 +471,7 @@ class TypeComparer(initctx: Context) extends DotClass { case tp2 @ MethodType(_, formals2) => def compareMethod = tp1 match { case tp1 @ MethodType(_, formals1) => - tp1.signature == tp2.signature && + (tp1.signature sameParams tp2.signature) && (if (Config.newMatch) subsumeParams(formals1, formals2, tp1.isJava, tp2.isJava) else matchingParams(formals1, formals2, tp1.isJava, tp2.isJava)) && tp1.isImplicit == tp2.isImplicit && // needed? diff --git a/tests/pending/pos/t0625.scala b/tests/pos/t0625.scala similarity index 100% rename from tests/pending/pos/t0625.scala rename to tests/pos/t0625.scala From 7820e62e30a63f2b8fd6b8bab8f96be6924a63a1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 17 Mar 2014 17:08:32 +0100 Subject: [PATCH 10/22] Fix of t1056 - PartialFunction type T was not recorgnized as a SAM type because a case was missing in zeroParamClass. --- src/dotty/tools/dotc/core/Types.scala | 6 ++++-- tests/{untried/pos => new}/t1056.scala | 0 2 files changed, 4 insertions(+), 2 deletions(-) rename tests/{untried/pos => new}/t1056.scala (100%) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 9b5e02186199..b6b17534ec25 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1774,7 +1774,7 @@ object Types { // upper bound is not a singleton type, widen the instance. if (fromBelow && isSingleton(inst) && !isSingleton(upperBound)) inst = inst.widen - + inst = inst.simplified // 2. If instance is from below and is a fully-defined union type, yet upper bound @@ -1782,7 +1782,7 @@ object Types { // of all common base types. if (fromBelow && isOrType(inst) && isFullyDefined(inst) && !isOrType(upperBound)) inst = inst.approximateUnion - + instantiateWith(inst) } @@ -2094,6 +2094,8 @@ object Types { zeroParamClass(tp.underlying) case tp: RefinedType => zeroParamClass(tp.underlying) + case tp: TypeBounds => + zeroParamClass(tp.underlying) case tp: TypeVar => zeroParamClass(tp.underlying) case _ => diff --git a/tests/untried/pos/t1056.scala b/tests/new/t1056.scala similarity index 100% rename from tests/untried/pos/t1056.scala rename to tests/new/t1056.scala From 0a1ec31c2a17c5dd0e6bd363979cbf17a8860616 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 17 Mar 2014 18:05:57 +0100 Subject: [PATCH 11/22] Fix of t112606A - path dependent types Needed an extra case in isSubType. --- src/dotty/tools/dotc/core/TypeComparer.scala | 15 ++++++++++++++- tests/{untried => }/pos/t112606A.scala | 0 2 files changed, 14 insertions(+), 1 deletion(-) rename tests/{untried => }/pos/t112606A.scala (100%) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 612b78f79ed5..b0fc68ba8f8a 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -536,7 +536,20 @@ class TypeComparer(initctx: Context) extends DotClass { (tp1.symbol eq NullClass) && tp2.dealias.typeSymbol.isNullableClass } case tp1: SingletonType => - isNewSubType(tp1.underlying.widenExpr, tp2) + isNewSubType(tp1.underlying.widenExpr, tp2) || { + // if tp2 == p.type and p: q.type then try tp1 <:< q.type as a last effort. + tp2 match { + case tp2: TermRef => + tp2.info match { + case tp2i: TermRef => + isSubType(tp1, tp2i) + case _ => + false + } + case _ => + false + } + } case tp1: RefinedType => isNewSubType(tp1.parent, tp2) case AndType(tp11, tp12) => diff --git a/tests/untried/pos/t112606A.scala b/tests/pos/t112606A.scala similarity index 100% rename from tests/untried/pos/t112606A.scala rename to tests/pos/t112606A.scala From 474b35ff0160c1174674757895e93818dc4f2f19 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 17 Mar 2014 18:06:58 +0100 Subject: [PATCH 12/22] Fix of t1123 - Unit discarding Need to do unit discarding also in selection prototypes. --- src/dotty/tools/dotc/typer/ProtoTypes.scala | 4 +++- tests/{untried => }/pos/t1123.scala | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename tests/{untried => }/pos/t1123.scala (73%) diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 74be3f4cd1c6..16fcc9db7cd1 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -79,7 +79,9 @@ object ProtoTypes { override def isMatchedBy(tp1: Type)(implicit ctx: Context) = { name == nme.WILDCARD || { val mbr = tp1.member(name) - def qualifies(m: SingleDenotation) = compat.normalizedCompatible(m.info, memberProto) + def qualifies(m: SingleDenotation) = + memberProto.isRef(defn.UnitClass) || + compat.normalizedCompatible(m.info, memberProto) mbr match { // hasAltWith inlined for performance case mbr: SingleDenotation => mbr.exists && qualifies(mbr) case _ => mbr hasAltWith qualifies diff --git a/tests/untried/pos/t1123.scala b/tests/pos/t1123.scala similarity index 73% rename from tests/untried/pos/t1123.scala rename to tests/pos/t1123.scala index 3812fa3eb35c..e3a89c14a404 100644 --- a/tests/untried/pos/t1123.scala +++ b/tests/pos/t1123.scala @@ -7,5 +7,5 @@ object Test { } def f = extraListener.h } - def main(args : Array[String]) : Unit = (new Editor).f + def main(args : Array[String]): Unit = (new Editor).f } From c854cc7fcc9d0f889c6235c1534133cff7360e7f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 17 Mar 2014 18:44:39 +0100 Subject: [PATCH 13/22] More tests --- tests/{untried => pending}/pos/t1071.scala | 2 ++ tests/pending/pos/t1208.scala | 7 +++++++ tests/{untried => pending}/pos/t1236.scala | 2 +- tests/{untried => pending}/pos/t1272.scala | 0 tests/{untried => pending}/pos/t1279a.scala | 0 tests/{untried => pending}/pos/t1280.scala | 0 tests/{untried => pending}/pos/t1292.scala | 0 tests/{untried => }/pos/t1000.scala | 0 tests/{untried => }/pos/t1001.scala | 0 tests/{untried => }/pos/t1006.scala | 0 tests/{untried => }/pos/t1014.scala | 0 tests/{untried => }/pos/t1027.scala | 0 tests/{untried => }/pos/t1034.scala | 0 tests/{untried => }/pos/t1035.scala | 2 +- tests/pos/t1048.scala | 14 ++++++++++++++ tests/{untried => }/pos/t1049.scala | 0 tests/{untried => }/pos/t1050.scala | 0 tests/{untried => }/pos/t1053.scala | 0 tests/{new => pos}/t1056.scala | 0 tests/{untried => }/pos/t1070.scala | 0 tests/{untried => }/pos/t1075.scala | 0 tests/{untried => }/pos/t1085.scala | 0 tests/{untried => }/pos/t1090.scala | 0 tests/{untried => }/pos/t1107a.scala | 0 tests/{untried => }/pos/t1119.scala | 0 tests/{untried => }/pos/t1131.scala | 0 tests/{untried => }/pos/t1133.scala | 0 tests/{untried => }/pos/t1136.scala | 0 tests/{untried => }/pos/t1146.scala | 0 tests/{untried => }/pos/t1147.scala | 0 tests/{untried => }/pos/t115.scala | 0 tests/{untried => }/pos/t1159.scala | 0 tests/{untried => }/pos/t116.scala | 0 tests/{untried => }/pos/t1164.scala | 0 tests/{untried => }/pos/t1168.scala | 0 tests/{untried => }/pos/t1185.scala | 0 tests/{untried => }/pos/t119.scala | 0 tests/{untried => }/pos/t1203a.scala | 0 tests/{untried => }/pos/t121.scala | 0 tests/{untried => }/pos/t1210a.scala | 0 tests/{untried => }/pos/t122.scala | 0 tests/{untried => }/pos/t1226.scala | 0 tests/{untried => }/pos/t1237.scala | 0 tests/{untried => }/pos/t124.scala | 0 tests/{untried => }/pos/t1260.scala | 0 tests/untried/pos/t1048.scala | 14 -------------- tests/untried/pos/t1208.scala | 4 ---- 47 files changed, 25 insertions(+), 20 deletions(-) rename tests/{untried => pending}/pos/t1071.scala (50%) create mode 100644 tests/pending/pos/t1208.scala rename tests/{untried => pending}/pos/t1236.scala (78%) rename tests/{untried => pending}/pos/t1272.scala (100%) rename tests/{untried => pending}/pos/t1279a.scala (100%) rename tests/{untried => pending}/pos/t1280.scala (100%) rename tests/{untried => pending}/pos/t1292.scala (100%) rename tests/{untried => }/pos/t1000.scala (100%) rename tests/{untried => }/pos/t1001.scala (100%) rename tests/{untried => }/pos/t1006.scala (100%) rename tests/{untried => }/pos/t1014.scala (100%) rename tests/{untried => }/pos/t1027.scala (100%) rename tests/{untried => }/pos/t1034.scala (100%) rename tests/{untried => }/pos/t1035.scala (88%) create mode 100644 tests/pos/t1048.scala rename tests/{untried => }/pos/t1049.scala (100%) rename tests/{untried => }/pos/t1050.scala (100%) rename tests/{untried => }/pos/t1053.scala (100%) rename tests/{new => pos}/t1056.scala (100%) rename tests/{untried => }/pos/t1070.scala (100%) rename tests/{untried => }/pos/t1075.scala (100%) rename tests/{untried => }/pos/t1085.scala (100%) rename tests/{untried => }/pos/t1090.scala (100%) rename tests/{untried => }/pos/t1107a.scala (100%) rename tests/{untried => }/pos/t1119.scala (100%) rename tests/{untried => }/pos/t1131.scala (100%) rename tests/{untried => }/pos/t1133.scala (100%) rename tests/{untried => }/pos/t1136.scala (100%) rename tests/{untried => }/pos/t1146.scala (100%) rename tests/{untried => }/pos/t1147.scala (100%) rename tests/{untried => }/pos/t115.scala (100%) rename tests/{untried => }/pos/t1159.scala (100%) rename tests/{untried => }/pos/t116.scala (100%) rename tests/{untried => }/pos/t1164.scala (100%) rename tests/{untried => }/pos/t1168.scala (100%) rename tests/{untried => }/pos/t1185.scala (100%) rename tests/{untried => }/pos/t119.scala (100%) rename tests/{untried => }/pos/t1203a.scala (100%) rename tests/{untried => }/pos/t121.scala (100%) rename tests/{untried => }/pos/t1210a.scala (100%) rename tests/{untried => }/pos/t122.scala (100%) rename tests/{untried => }/pos/t1226.scala (100%) rename tests/{untried => }/pos/t1237.scala (100%) rename tests/{untried => }/pos/t124.scala (100%) rename tests/{untried => }/pos/t1260.scala (100%) delete mode 100644 tests/untried/pos/t1048.scala delete mode 100644 tests/untried/pos/t1208.scala diff --git a/tests/untried/pos/t1071.scala b/tests/pending/pos/t1071.scala similarity index 50% rename from tests/untried/pos/t1071.scala rename to tests/pending/pos/t1071.scala index 59149a021b01..b241cd648563 100644 --- a/tests/untried/pos/t1071.scala +++ b/tests/pending/pos/t1071.scala @@ -15,3 +15,5 @@ object Test { c.a // error } +// to fix this we'd need to check accessibility in the isMatchedBy of a SelectionProto, +// so that we can insert an implicit if this does not work. Need to check performance impact of this. diff --git a/tests/pending/pos/t1208.scala b/tests/pending/pos/t1208.scala new file mode 100644 index 000000000000..7b14aadca367 --- /dev/null +++ b/tests/pending/pos/t1208.scala @@ -0,0 +1,7 @@ +object Test { + object Foo + val f: Option[Foo.type] = Some(Foo) +} + +// unsupported with current typing rules. +// on the other hand, we need a way to refer to a module class. diff --git a/tests/untried/pos/t1236.scala b/tests/pending/pos/t1236.scala similarity index 78% rename from tests/untried/pos/t1236.scala rename to tests/pending/pos/t1236.scala index 75a1befd263c..eee1cbf02915 100644 --- a/tests/untried/pos/t1236.scala +++ b/tests/pending/pos/t1236.scala @@ -4,7 +4,7 @@ trait Empty[E[_]] { object T { val ListEmpty = new Empty[List] { - def e[A] = Nil + def e[A]/*: List*/ = Nil // uncomment to get crash } def foo[F[_]](q:(String,String)) = "hello" diff --git a/tests/untried/pos/t1272.scala b/tests/pending/pos/t1272.scala similarity index 100% rename from tests/untried/pos/t1272.scala rename to tests/pending/pos/t1272.scala diff --git a/tests/untried/pos/t1279a.scala b/tests/pending/pos/t1279a.scala similarity index 100% rename from tests/untried/pos/t1279a.scala rename to tests/pending/pos/t1279a.scala diff --git a/tests/untried/pos/t1280.scala b/tests/pending/pos/t1280.scala similarity index 100% rename from tests/untried/pos/t1280.scala rename to tests/pending/pos/t1280.scala diff --git a/tests/untried/pos/t1292.scala b/tests/pending/pos/t1292.scala similarity index 100% rename from tests/untried/pos/t1292.scala rename to tests/pending/pos/t1292.scala diff --git a/tests/untried/pos/t1000.scala b/tests/pos/t1000.scala similarity index 100% rename from tests/untried/pos/t1000.scala rename to tests/pos/t1000.scala diff --git a/tests/untried/pos/t1001.scala b/tests/pos/t1001.scala similarity index 100% rename from tests/untried/pos/t1001.scala rename to tests/pos/t1001.scala diff --git a/tests/untried/pos/t1006.scala b/tests/pos/t1006.scala similarity index 100% rename from tests/untried/pos/t1006.scala rename to tests/pos/t1006.scala diff --git a/tests/untried/pos/t1014.scala b/tests/pos/t1014.scala similarity index 100% rename from tests/untried/pos/t1014.scala rename to tests/pos/t1014.scala diff --git a/tests/untried/pos/t1027.scala b/tests/pos/t1027.scala similarity index 100% rename from tests/untried/pos/t1027.scala rename to tests/pos/t1027.scala diff --git a/tests/untried/pos/t1034.scala b/tests/pos/t1034.scala similarity index 100% rename from tests/untried/pos/t1034.scala rename to tests/pos/t1034.scala diff --git a/tests/untried/pos/t1035.scala b/tests/pos/t1035.scala similarity index 88% rename from tests/untried/pos/t1035.scala rename to tests/pos/t1035.scala index e0a9379c7ed9..ef81cb0d9fa7 100644 --- a/tests/untried/pos/t1035.scala +++ b/tests/pos/t1035.scala @@ -6,7 +6,7 @@ class A { var name:String = _ def getName() = name - def this(name:String, age:Int){this();this.name=name} + def this(name:String, age:Int) = {this(); this.name = name} } diff --git a/tests/pos/t1048.scala b/tests/pos/t1048.scala new file mode 100644 index 000000000000..b8694b38e694 --- /dev/null +++ b/tests/pos/t1048.scala @@ -0,0 +1,14 @@ +trait T[U] { + def x: T[_ <: U] +} + +object T { + def unapply[U](t: T[U]): Option[T[_ <: U]] = Some(t.x) +} + +object Test { + def f[W](t: T[W]) = t match { + case T(T(_)) => () + } +} + diff --git a/tests/untried/pos/t1049.scala b/tests/pos/t1049.scala similarity index 100% rename from tests/untried/pos/t1049.scala rename to tests/pos/t1049.scala diff --git a/tests/untried/pos/t1050.scala b/tests/pos/t1050.scala similarity index 100% rename from tests/untried/pos/t1050.scala rename to tests/pos/t1050.scala diff --git a/tests/untried/pos/t1053.scala b/tests/pos/t1053.scala similarity index 100% rename from tests/untried/pos/t1053.scala rename to tests/pos/t1053.scala diff --git a/tests/new/t1056.scala b/tests/pos/t1056.scala similarity index 100% rename from tests/new/t1056.scala rename to tests/pos/t1056.scala diff --git a/tests/untried/pos/t1070.scala b/tests/pos/t1070.scala similarity index 100% rename from tests/untried/pos/t1070.scala rename to tests/pos/t1070.scala diff --git a/tests/untried/pos/t1075.scala b/tests/pos/t1075.scala similarity index 100% rename from tests/untried/pos/t1075.scala rename to tests/pos/t1075.scala diff --git a/tests/untried/pos/t1085.scala b/tests/pos/t1085.scala similarity index 100% rename from tests/untried/pos/t1085.scala rename to tests/pos/t1085.scala diff --git a/tests/untried/pos/t1090.scala b/tests/pos/t1090.scala similarity index 100% rename from tests/untried/pos/t1090.scala rename to tests/pos/t1090.scala diff --git a/tests/untried/pos/t1107a.scala b/tests/pos/t1107a.scala similarity index 100% rename from tests/untried/pos/t1107a.scala rename to tests/pos/t1107a.scala diff --git a/tests/untried/pos/t1119.scala b/tests/pos/t1119.scala similarity index 100% rename from tests/untried/pos/t1119.scala rename to tests/pos/t1119.scala diff --git a/tests/untried/pos/t1131.scala b/tests/pos/t1131.scala similarity index 100% rename from tests/untried/pos/t1131.scala rename to tests/pos/t1131.scala diff --git a/tests/untried/pos/t1133.scala b/tests/pos/t1133.scala similarity index 100% rename from tests/untried/pos/t1133.scala rename to tests/pos/t1133.scala diff --git a/tests/untried/pos/t1136.scala b/tests/pos/t1136.scala similarity index 100% rename from tests/untried/pos/t1136.scala rename to tests/pos/t1136.scala diff --git a/tests/untried/pos/t1146.scala b/tests/pos/t1146.scala similarity index 100% rename from tests/untried/pos/t1146.scala rename to tests/pos/t1146.scala diff --git a/tests/untried/pos/t1147.scala b/tests/pos/t1147.scala similarity index 100% rename from tests/untried/pos/t1147.scala rename to tests/pos/t1147.scala diff --git a/tests/untried/pos/t115.scala b/tests/pos/t115.scala similarity index 100% rename from tests/untried/pos/t115.scala rename to tests/pos/t115.scala diff --git a/tests/untried/pos/t1159.scala b/tests/pos/t1159.scala similarity index 100% rename from tests/untried/pos/t1159.scala rename to tests/pos/t1159.scala diff --git a/tests/untried/pos/t116.scala b/tests/pos/t116.scala similarity index 100% rename from tests/untried/pos/t116.scala rename to tests/pos/t116.scala diff --git a/tests/untried/pos/t1164.scala b/tests/pos/t1164.scala similarity index 100% rename from tests/untried/pos/t1164.scala rename to tests/pos/t1164.scala diff --git a/tests/untried/pos/t1168.scala b/tests/pos/t1168.scala similarity index 100% rename from tests/untried/pos/t1168.scala rename to tests/pos/t1168.scala diff --git a/tests/untried/pos/t1185.scala b/tests/pos/t1185.scala similarity index 100% rename from tests/untried/pos/t1185.scala rename to tests/pos/t1185.scala diff --git a/tests/untried/pos/t119.scala b/tests/pos/t119.scala similarity index 100% rename from tests/untried/pos/t119.scala rename to tests/pos/t119.scala diff --git a/tests/untried/pos/t1203a.scala b/tests/pos/t1203a.scala similarity index 100% rename from tests/untried/pos/t1203a.scala rename to tests/pos/t1203a.scala diff --git a/tests/untried/pos/t121.scala b/tests/pos/t121.scala similarity index 100% rename from tests/untried/pos/t121.scala rename to tests/pos/t121.scala diff --git a/tests/untried/pos/t1210a.scala b/tests/pos/t1210a.scala similarity index 100% rename from tests/untried/pos/t1210a.scala rename to tests/pos/t1210a.scala diff --git a/tests/untried/pos/t122.scala b/tests/pos/t122.scala similarity index 100% rename from tests/untried/pos/t122.scala rename to tests/pos/t122.scala diff --git a/tests/untried/pos/t1226.scala b/tests/pos/t1226.scala similarity index 100% rename from tests/untried/pos/t1226.scala rename to tests/pos/t1226.scala diff --git a/tests/untried/pos/t1237.scala b/tests/pos/t1237.scala similarity index 100% rename from tests/untried/pos/t1237.scala rename to tests/pos/t1237.scala diff --git a/tests/untried/pos/t124.scala b/tests/pos/t124.scala similarity index 100% rename from tests/untried/pos/t124.scala rename to tests/pos/t124.scala diff --git a/tests/untried/pos/t1260.scala b/tests/pos/t1260.scala similarity index 100% rename from tests/untried/pos/t1260.scala rename to tests/pos/t1260.scala diff --git a/tests/untried/pos/t1048.scala b/tests/untried/pos/t1048.scala deleted file mode 100644 index cd16db5b60cd..000000000000 --- a/tests/untried/pos/t1048.scala +++ /dev/null @@ -1,14 +0,0 @@ -trait T[U] { - def x: T[V] forSome { type V <: U } -} - -object T { - def unapply[U](t: T[U]): Option[T[V] forSome { type V <: U }] = Some(t.x) -} - -object Test { - def f[W](t: T[W]) = t match { - case T(T(_)) => () - } -} - diff --git a/tests/untried/pos/t1208.scala b/tests/untried/pos/t1208.scala deleted file mode 100644 index 9ac783d39a87..000000000000 --- a/tests/untried/pos/t1208.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test { - object Foo - val f: Option[Foo.type] = Some(Foo) -} From 7e51434b89659c49a1cd755c224cc5ca270b82b3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 19 Mar 2014 10:33:55 +0100 Subject: [PATCH 14/22] Fix for t1292 - legal prefixes The original test is now in error because the type Meta in the prefix Meta#Event is not stable and contains an abstract member Slog. Even after removing Slog, the test in pos was still in error because the bound type parameters were incorrectly recognized as abstract members. This has been fixed by the changes to Types. --- src/dotty/tools/dotc/core/Types.scala | 24 ++++++++++++++++-- test/dotc/tests.scala | 1 + tests/neg/t1292.scala | 35 +++++++++++++++++++++++++++ tests/{pending => }/pos/t1292.scala | 5 ++-- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 tests/neg/t1292.scala rename tests/{pending => }/pos/t1292.scala (92%) diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index b6b17534ec25..967421f2b319 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -121,7 +121,11 @@ object Types { * !!! Todo: What about non-final vals that contain abstract types? */ final def isLegalPrefix(implicit ctx: Context): Boolean = - isStable || memberNames(abstractTypeNameFilter).isEmpty + isStable || { + val absTypeNames = memberNames(abstractTypeNameFilter) + if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying}: $absTypeNames") + absTypeNames.isEmpty + } /** Is this type guaranteed not to have `null` as a value? * For the moment this is only true for modules, but it could @@ -811,6 +815,14 @@ object Types { /** Convert to text */ def toText(printer: Printer): Text = printer.toText(this) + /** Utility method to show the underlying type of a TypeProxy together + * with the proxy type itself. + */ + def showWithUnderlying(implicit ctx: Context): String = this match { + case tp: TypeProxy => s"$show with underlying ${tp.underlying.show}" + case _ => show + } + type VarianceMap = SimpleMap[TypeVar, Integer] /** All occurrences of type vars in this type that satisfy predicate @@ -2407,7 +2419,15 @@ object Types { /** A filter for names of abstract types of a given type */ object abstractTypeNameFilter extends NameFilter { def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = - name.isTypeName && ((pre member name).symbol is Deferred) + name.isTypeName && { + val mbr = pre.member(name) + (mbr.symbol is Deferred) && { + mbr.info match { + case TypeBounds(lo, hi) => lo ne hi + case _ => false + } + } + } } /** A filter for names of deferred term definitions of a given type */ diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index ee05dd15cf49..4b52b93c26cb 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -63,6 +63,7 @@ class tests extends CompilerTest { @Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 3) @Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3) @Test def neg_t0654_polyalias = compileFile(negDir, "t0654", xerrors = 2) + @Test def neg_t1192_legalPrefix = compileFile(negDir, "t1192", xerrors = 1) @Test def dotc = compileDir(dotcDir + "tools/dotc", twice) @Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice) diff --git a/tests/neg/t1292.scala b/tests/neg/t1292.scala new file mode 100644 index 000000000000..69e680320909 --- /dev/null +++ b/tests/neg/t1292.scala @@ -0,0 +1,35 @@ +trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] { + type StV = Enum#Value + type Meta = MegaFoo[T, Enum] + + type Slog <: Enumeration + + def getSingleton: Meta +} + +trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] { + def doSomething(what: T, misc: StV, dog: Meta#Event) = None + // error: Meta is not a valid prefix for '#'. + // The error is correct. Meta is not stable, and it has an abstract type member Slog + abstract class Event + object Event + + def stateEnumeration: Slog + def se2: Enum +} + +object E extends Enumeration { + val A = Value + val B = Value +} + +class RFoo extends Foo[RFoo, E.type] { + def getSingleton = MegaRFoo + + type Slog = E.type +} + +object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] { + def stateEnumeration = E + def se2 = E +} diff --git a/tests/pending/pos/t1292.scala b/tests/pos/t1292.scala similarity index 92% rename from tests/pending/pos/t1292.scala rename to tests/pos/t1292.scala index 83a996d530a9..8e69734e97eb 100644 --- a/tests/pending/pos/t1292.scala +++ b/tests/pos/t1292.scala @@ -2,13 +2,14 @@ trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] { type StV = Enum#Value type Meta = MegaFoo[T, Enum] - type Slog <: Enumeration + type Slog = Enumeration def getSingleton: Meta } trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] { def doSomething(what: T, misc: StV, dog: Meta#Event) = None + abstract class Event object Event @@ -23,8 +24,6 @@ object E extends Enumeration { class RFoo extends Foo[RFoo, E.type] { def getSingleton = MegaRFoo - - type Slog = E.type } object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] { From 40202eedb940d0614c08b1ba36c8648ed56ea332 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 19 Mar 2014 11:00:53 +0100 Subject: [PATCH 15/22] Fix of t1280 - type of self The type of self name "x" was taken to be the thisType of the current owner. But the current owner was a local dummy of the class in question, so the ThisType was NoPrefix. Inserting an enclosingClass fixes the problem. --- src/dotty/tools/dotc/typer/Typer.scala | 2 +- tests/{pending => }/pos/t1280.scala | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{pending => }/pos/t1280.scala (100%) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 4fdee86a3a1f..7c301a7f1ab7 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -209,7 +209,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (qualifies(defDenot)) { val curOwner = ctx.owner val found = - if (isSelfDenot(defDenot)) curOwner.thisType + if (isSelfDenot(defDenot)) curOwner.enclosingClass.thisType else curOwner.thisType.select(name, defDenot) if (!(curOwner is Package) || (defDenot.symbol is Package) || isDefinedInCurrentUnit(defDenot)) return checkNewOrShadowed(found, definition) // no need to go further out, we found highest prec entry diff --git a/tests/pending/pos/t1280.scala b/tests/pos/t1280.scala similarity index 100% rename from tests/pending/pos/t1280.scala rename to tests/pos/t1280.scala From d6df293d2120f2247198cb6646a23c338f7dcbbf Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 19 Mar 2014 17:56:03 +0100 Subject: [PATCH 16/22] Fix of t1236: higher-kinded (and also of t0625, which reappeared). Several fixes were made. In summary: 1. Naming and representation of KigherKinded traits changed. It's now $HigherKinded$NIP where the letters after the second $ indicate variance (N)egative, (I)nvariant, (P)ositive. The HKtraits themselves are always non-variant in their parameters. 2. When deriving refined types over higher-kinded types, the variance of a type alias is the variance of the new type constructor. 3. isSubTypeHK was changed, as was the position from where it is called. 4. appliedTo also works for PolyTypes. --- src/dotty/tools/dotc/config/Printers.scala | 1 + src/dotty/tools/dotc/core/Definitions.scala | 13 ++---- src/dotty/tools/dotc/core/NameOps.scala | 13 ++++++ src/dotty/tools/dotc/core/StdNames.scala | 8 +++- .../tools/dotc/core/TypeApplications.scala | 2 + src/dotty/tools/dotc/core/TypeComparer.scala | 44 ++++++++++++------- src/dotty/tools/dotc/core/Types.scala | 22 +++++----- .../tools/dotc/core/transform/Erasure.scala | 4 +- src/dotty/tools/dotc/typer/Namer.scala | 2 + tests/{pending => }/pos/t1236.scala | 2 +- 10 files changed, 72 insertions(+), 39 deletions(-) rename tests/{pending => }/pos/t1236.scala (78%) diff --git a/src/dotty/tools/dotc/config/Printers.scala b/src/dotty/tools/dotc/config/Printers.scala index 853049b047b2..d06eb2ece5fc 100644 --- a/src/dotty/tools/dotc/config/Printers.scala +++ b/src/dotty/tools/dotc/config/Printers.scala @@ -22,6 +22,7 @@ object Printers { val unapp: Printer = noPrinter val completions = noPrinter val gadts = noPrinter + val hk = noPrinter val incremental = noPrinter val config = noPrinter } \ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index a58bfc05816d..0ec770149283 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -359,12 +359,6 @@ class Definitions { */ def hkTrait(vcs: List[Int]) = { - def varianceSuffix(v: Int) = v match { - case -1 => "N" - case 0 => "I" - case 1 => "P" - } - def varianceFlags(v: Int) = v match { case -1 => Contravariant case 0 => Covariant @@ -375,14 +369,13 @@ class Definitions { def complete(denot: SymDenotation)(implicit ctx: Context): Unit = { val cls = denot.asClass.classSymbol val paramDecls = newScope - for ((v, i) <- vcs.zipWithIndex) - newTypeParam(cls, tpnme.higherKindedParamName(i), varianceFlags(v), paramDecls) + for (i <- 0 until vcs.length) + newTypeParam(cls, tpnme.higherKindedParamName(i), EmptyFlags, paramDecls) denot.info = ClassInfo(ScalaPackageClass.thisType, cls, List(ObjectClass.typeRef), paramDecls) } } - val traitName = - tpnme.higherKindedTraitName(vcs.length) ++ (vcs map varianceSuffix).mkString + val traitName = tpnme.higherKindedTraitName(vcs) def createTrait = { val cls = newClassSymbol( diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index 1a9e5eddb6b3..b9df8f6ed162 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -168,6 +168,19 @@ object NameOps { } } + /** The variances of the higherKinded parameters of the trait named + * by this name. + * @pre The name is a higher-kinded trait name, i.e. it starts with HK_TRAIT_PREFIX + */ + def hkVariances: List[Int] = { + def varianceOfSuffix(suffix: Char): Int = { + val idx = tpnme.varianceSuffixes.indexOf(suffix) + assert(idx >= 0) + idx - 1 + } + name.drop(tpnme.HK_TRAIT_PREFIX.length).toList.map(varianceOfSuffix) + } + /** If name length exceeds allowable limit, replace part of it by hash */ def compactified(implicit ctx: Context): TermName = termName(compactify(name.toString)) } diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 6cd9da4b5874..3982c51f00ee 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -248,6 +248,7 @@ object StdNames { val SPECIALIZED_INSTANCE: N = "specInstance$" val THIS: N = "_$this" val HK_PARAM_PREFIX: N = "_$hk$" + val HK_TRAIT_PREFIX: N = "$HigherKinded$" final val Nil: N = "Nil" final val Predef: N = "Predef" @@ -281,7 +282,6 @@ object StdNames { val ConstantType: N = "ConstantType" val ExistentialTypeTree: N = "ExistentialTypeTree" val Flag : N = "Flag" - val HigherKinded: N = "HigherKinded" val Ident: N = "Ident" val Import: N = "Import" val Literal: N = "Literal" @@ -645,10 +645,14 @@ object StdNames { def syntheticTypeParamNames(num: Int): List[TypeName] = (0 until num).map(syntheticTypeParamName)(breakOut) - def higherKindedTraitName(n: Int) = HigherKinded ++ n.toString + def higherKindedTraitName(vcs: List[Int]): TypeName = HK_TRAIT_PREFIX ++ vcs.map(varianceSuffix).mkString def higherKindedParamName(n: Int) = HK_PARAM_PREFIX ++ n.toString final val Conforms = encode("<:<") + + def varianceSuffix(v: Int): Char = varianceSuffixes.charAt(v + 1) + + val varianceSuffixes = "NIP" } abstract class JavaNames[N <: Name] extends DefinedNames[N] { diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 0abd28a716ab..2e936e2f16c1 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -137,6 +137,8 @@ class TypeApplications(val self: Type) extends AnyVal { tp.underlying.appliedTo(args) case AndType(l, r) => l.appliedTo(args) & r + case tp: PolyType => + tp.instantiate(args) case ErrorType => self } diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index b0fc68ba8f8a..753a72dd0583 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -412,8 +412,7 @@ class TypeComparer(initctx: Context) extends DotClass { val base = tp1.baseTypeRef(cls2) if (base.exists && (base ne tp1)) return isSubType(base, tp2) if ( cls2 == defn.SingletonClass && tp1.isStable - || cls2 == defn.NotNullClass && tp1.isNotNull - || (defn.hkTraits contains cls2) && isSubTypeHK(tp1, tp2)) return true + || cls2 == defn.NotNullClass && tp1.isNotNull) return true } fourthTry(tp1, tp2) } @@ -430,7 +429,9 @@ class TypeComparer(initctx: Context) extends DotClass { } case _ => tp2 } - def compareRefined: Boolean = tp1.widen match { + def compareRefined: Boolean = + if (defn.hkTraits contains parent2.typeSymbol) isSubTypeHK(tp1, tp2) + else tp1.widen match { case tp1 @ RefinedType(parent1, name1) if nameMatches(name1, name2, tp1, tp2) => // optimized case; all info on tp1.name2 is in refinement tp1.refinedInfo. isSubType(tp1.refinedInfo, tp2.refinedInfo) && { @@ -443,7 +444,7 @@ class TypeComparer(initctx: Context) extends DotClass { case mbr: SingleDenotation => qualifies(mbr) case _ => mbr hasAltWith qualifies } - def hasMatchingMember(name: Name): Boolean = /*>|>*/ ctx.traceIndented(s"hasMatchingMember($name) ${tp1.member(name)}", subtyping) /*<|<*/ ( + def hasMatchingMember(name: Name): Boolean = /*>|>*/ ctx.traceIndented(s"hasMatchingMember($name) ${tp1.member(name).info.show}", subtyping) /*<|<*/ ( memberMatches(tp1 member name) || { // special case for situations like: @@ -629,20 +630,33 @@ class TypeComparer(initctx: Context) extends DotClass { * This is the case if `tp1` and `tp2` have the same number * of type parameters, the bounds of tp1's paremeters * are contained in the corresponding bounds of tp2's parameters - * and the variances of correesponding parameters agree. + * and the variances of the parameters agree. + * The variances agree if the supertype parameter is invariant, + * or both parameters have the same variance. + * + * Note: When we get to isSubTypeHK, it might be that tp1 is + * instantiated, or not. If it is instantiated, we compare + * actual argument infos against higher-kinded bounds, + * if it is not instantiated we compare type parameter bounds + * and also compare variances. */ - def isSubTypeHK(tp1: Type, tp2: Type): Boolean = { + def isSubTypeHK(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSubTypeHK(${tp1.show}, ${tp2.show}") { val tparams = tp1.typeParams + val argInfos1 = tp1.argInfos + val args1 = + if (argInfos1.nonEmpty) argInfos1 // tp1 is instantiated, use the argument infos + else { // tp1 is uninstantiated, use the parameter bounds + val base = tp1.narrow + tparams.map(base.memberInfo) + } val hkArgs = tp2.argInfos - (hkArgs.length == tparams.length) && { - val base = tp1.narrow - (tparams, hkArgs).zipped.forall { (tparam, hkArg) => - isSubType(base.memberInfo(tparam), hkArg.bounds) // TODO: base.memberInfo needed? - } && - (tparams, tp2.typeSymbol.typeParams).zipped.forall { (tparam, tparam2) => - tparam.variance == tparam2.variance - } - } + hk.println(s"isSubTypeHK: args1 = $args1, hkargs = $hkArgs") + val boundsOK = (args1 corresponds hkArgs)(isSubType) + val variancesOK = + argInfos1.nonEmpty || (tparams corresponds tp2.typeSymbol.name.hkVariances) { (tparam, v) => + v == 0 || tparam.variance == v + } + boundsOK && variancesOK } def trySetType(tr: NamedType, bounds: TypeBounds): Boolean = diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 967421f2b319..38c07d99ac21 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -123,7 +123,7 @@ object Types { final def isLegalPrefix(implicit ctx: Context): Boolean = isStable || { val absTypeNames = memberNames(abstractTypeNameFilter) - if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying}: $absTypeNames") + if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying()}: $absTypeNames") absTypeNames.isEmpty } @@ -815,11 +815,11 @@ object Types { /** Convert to text */ def toText(printer: Printer): Text = printer.toText(this) - /** Utility method to show the underlying type of a TypeProxy together + /** Utility method to show the underlying type of a TypeProxy chain together * with the proxy type itself. */ - def showWithUnderlying(implicit ctx: Context): String = this match { - case tp: TypeProxy => s"$show with underlying ${tp.underlying.show}" + def showWithUnderlying(n: Int = 1)(implicit ctx: Context): String = this match { + case tp: TypeProxy if n > 0 => s"$show with underlying ${tp.underlying.showWithUnderlying(n - 1)}" case _ => show } @@ -1309,12 +1309,13 @@ object Types { lazy val underlyingTypeParams = parent.safeUnderlyingTypeParams lazy val originalTypeParam = underlyingTypeParams(refinedName.hkParamIndex) - /** drop any co/contra variance in refined info if variance disagrees - * with new type param + /** Use variance of newly instantiated type parameter rather than the old hk argument */ - def adjustedHKRefinedInfo(hkBounds: TypeBounds) = { - if (hkBounds.variance == originalTypeParam.info.bounds.variance) hkBounds - else TypeBounds(hkBounds.lo, hkBounds.hi) + def adjustedHKRefinedInfo(hkBounds: TypeBounds, underlyingTypeParam: TypeSymbol) = hkBounds match { + case tp @ TypeBounds(lo, hi) if lo eq hi => + tp.derivedTypeBounds(lo, hi, underlyingTypeParam.variance) + case _ => + hkBounds } if ((parent eq this.parent) && (refinedName eq this.refinedName) && (refinedInfo eq this.refinedInfo)) @@ -1323,7 +1324,8 @@ object Types { // && { println(s"deriving $refinedName $parent $underlyingTypeParams"); true } && refinedName.hkParamIndex < underlyingTypeParams.length && originalTypeParam.name != refinedName) - derivedRefinedType(parent, originalTypeParam.name, adjustedHKRefinedInfo(refinedInfo.bounds)) + derivedRefinedType(parent, originalTypeParam.name, + adjustedHKRefinedInfo(refinedInfo.bounds, underlyingTypeParams(refinedName.hkParamIndex))) else RefinedType(parent, refinedName, rt => refinedInfo.substThis(this, RefinedThis(rt))) } diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala index eaeb3c8e75e0..093b59ae8112 100644 --- a/src/dotty/tools/dotc/core/transform/Erasure.scala +++ b/src/dotty/tools/dotc/core/transform/Erasure.scala @@ -126,7 +126,9 @@ object Erasure { sigName(tp1) case OrType(tp1, tp2) => lubClass(tp1, tp2).name - case ErrorType | WildcardType => + case tp: WildcardType => + tpnme.WILDCARD + case ErrorType => tpnme.WILDCARD } diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 7885e85acdf2..361de802c742 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -549,6 +549,8 @@ class Namer { typer: Typer => else NoType } val iResType = iInstInfo.finalResultType.asSeenFrom(site, cls) + if (iResType.exists) + typr.println(s"using inherited type; raw: $iRawInfo, inst: $iInstInfo, inherited: $iResType") tp & iResType } } diff --git a/tests/pending/pos/t1236.scala b/tests/pos/t1236.scala similarity index 78% rename from tests/pending/pos/t1236.scala rename to tests/pos/t1236.scala index eee1cbf02915..a84cad0fb558 100644 --- a/tests/pending/pos/t1236.scala +++ b/tests/pos/t1236.scala @@ -4,7 +4,7 @@ trait Empty[E[_]] { object T { val ListEmpty = new Empty[List] { - def e[A]/*: List*/ = Nil // uncomment to get crash + def e[B] = Nil } def foo[F[_]](q:(String,String)) = "hello" From 0dda8a1858c162f74f76a1d4dae158e99a250267 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 19 Mar 2014 18:00:14 +0100 Subject: [PATCH 17/22] More tests, currently disabled Mostly Java interop tests which are not yet supported. The test infrastructure for Java ocmpilation and the java parser from Scala are still missing. --- tests/{untried => disabled/java-interop}/pos/t1101/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1101/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1102/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1102/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1150/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1150/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1152/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1152/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1176/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1176/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1186/t1186.java | 0 tests/{untried => disabled/java-interop}/pos/t1196/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1196/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1197/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1197/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1203b/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1203b/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1230/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1230/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1231/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1231/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1232/J.java | 0 tests/{untried => disabled/java-interop}/pos/t1232/J2.java | 0 tests/{untried => disabled/java-interop}/pos/t1232/S.scala | 0 tests/{untried => disabled/java-interop}/pos/t1235/Test.java | 0 tests/{untried => disabled/java-interop}/pos/t1254/t1254.java | 0 tests/{untried => disabled/java-interop}/pos/t1263/Test.java | 0 tests/{untried => disabled/java-interop}/pos/t1263/test.scala | 0 tests/{untried => }/pos/t1029/Test_1.scala | 0 tests/{untried => }/pos/t1029/Test_2.scala | 0 tests/{untried => }/pos/t1107b/O.scala | 0 tests/{untried => }/pos/t1107b/T.scala | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename tests/{untried => disabled/java-interop}/pos/t1101/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1101/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1102/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1102/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1150/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1150/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1152/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1152/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1176/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1176/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1186/t1186.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1196/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1196/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1197/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1197/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1203b/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1203b/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1230/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1230/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1231/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1231/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1232/J.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1232/J2.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1232/S.scala (100%) rename tests/{untried => disabled/java-interop}/pos/t1235/Test.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1254/t1254.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1263/Test.java (100%) rename tests/{untried => disabled/java-interop}/pos/t1263/test.scala (100%) rename tests/{untried => }/pos/t1029/Test_1.scala (100%) rename tests/{untried => }/pos/t1029/Test_2.scala (100%) rename tests/{untried => }/pos/t1107b/O.scala (100%) rename tests/{untried => }/pos/t1107b/T.scala (100%) diff --git a/tests/untried/pos/t1101/J.java b/tests/disabled/java-interop/pos/t1101/J.java similarity index 100% rename from tests/untried/pos/t1101/J.java rename to tests/disabled/java-interop/pos/t1101/J.java diff --git a/tests/untried/pos/t1101/S.scala b/tests/disabled/java-interop/pos/t1101/S.scala similarity index 100% rename from tests/untried/pos/t1101/S.scala rename to tests/disabled/java-interop/pos/t1101/S.scala diff --git a/tests/untried/pos/t1102/J.java b/tests/disabled/java-interop/pos/t1102/J.java similarity index 100% rename from tests/untried/pos/t1102/J.java rename to tests/disabled/java-interop/pos/t1102/J.java diff --git a/tests/untried/pos/t1102/S.scala b/tests/disabled/java-interop/pos/t1102/S.scala similarity index 100% rename from tests/untried/pos/t1102/S.scala rename to tests/disabled/java-interop/pos/t1102/S.scala diff --git a/tests/untried/pos/t1150/J.java b/tests/disabled/java-interop/pos/t1150/J.java similarity index 100% rename from tests/untried/pos/t1150/J.java rename to tests/disabled/java-interop/pos/t1150/J.java diff --git a/tests/untried/pos/t1150/S.scala b/tests/disabled/java-interop/pos/t1150/S.scala similarity index 100% rename from tests/untried/pos/t1150/S.scala rename to tests/disabled/java-interop/pos/t1150/S.scala diff --git a/tests/untried/pos/t1152/J.java b/tests/disabled/java-interop/pos/t1152/J.java similarity index 100% rename from tests/untried/pos/t1152/J.java rename to tests/disabled/java-interop/pos/t1152/J.java diff --git a/tests/untried/pos/t1152/S.scala b/tests/disabled/java-interop/pos/t1152/S.scala similarity index 100% rename from tests/untried/pos/t1152/S.scala rename to tests/disabled/java-interop/pos/t1152/S.scala diff --git a/tests/untried/pos/t1176/J.java b/tests/disabled/java-interop/pos/t1176/J.java similarity index 100% rename from tests/untried/pos/t1176/J.java rename to tests/disabled/java-interop/pos/t1176/J.java diff --git a/tests/untried/pos/t1176/S.scala b/tests/disabled/java-interop/pos/t1176/S.scala similarity index 100% rename from tests/untried/pos/t1176/S.scala rename to tests/disabled/java-interop/pos/t1176/S.scala diff --git a/tests/untried/pos/t1186/t1186.java b/tests/disabled/java-interop/pos/t1186/t1186.java similarity index 100% rename from tests/untried/pos/t1186/t1186.java rename to tests/disabled/java-interop/pos/t1186/t1186.java diff --git a/tests/untried/pos/t1196/J.java b/tests/disabled/java-interop/pos/t1196/J.java similarity index 100% rename from tests/untried/pos/t1196/J.java rename to tests/disabled/java-interop/pos/t1196/J.java diff --git a/tests/untried/pos/t1196/S.scala b/tests/disabled/java-interop/pos/t1196/S.scala similarity index 100% rename from tests/untried/pos/t1196/S.scala rename to tests/disabled/java-interop/pos/t1196/S.scala diff --git a/tests/untried/pos/t1197/J.java b/tests/disabled/java-interop/pos/t1197/J.java similarity index 100% rename from tests/untried/pos/t1197/J.java rename to tests/disabled/java-interop/pos/t1197/J.java diff --git a/tests/untried/pos/t1197/S.scala b/tests/disabled/java-interop/pos/t1197/S.scala similarity index 100% rename from tests/untried/pos/t1197/S.scala rename to tests/disabled/java-interop/pos/t1197/S.scala diff --git a/tests/untried/pos/t1203b/J.java b/tests/disabled/java-interop/pos/t1203b/J.java similarity index 100% rename from tests/untried/pos/t1203b/J.java rename to tests/disabled/java-interop/pos/t1203b/J.java diff --git a/tests/untried/pos/t1203b/S.scala b/tests/disabled/java-interop/pos/t1203b/S.scala similarity index 100% rename from tests/untried/pos/t1203b/S.scala rename to tests/disabled/java-interop/pos/t1203b/S.scala diff --git a/tests/untried/pos/t1230/J.java b/tests/disabled/java-interop/pos/t1230/J.java similarity index 100% rename from tests/untried/pos/t1230/J.java rename to tests/disabled/java-interop/pos/t1230/J.java diff --git a/tests/untried/pos/t1230/S.scala b/tests/disabled/java-interop/pos/t1230/S.scala similarity index 100% rename from tests/untried/pos/t1230/S.scala rename to tests/disabled/java-interop/pos/t1230/S.scala diff --git a/tests/untried/pos/t1231/J.java b/tests/disabled/java-interop/pos/t1231/J.java similarity index 100% rename from tests/untried/pos/t1231/J.java rename to tests/disabled/java-interop/pos/t1231/J.java diff --git a/tests/untried/pos/t1231/S.scala b/tests/disabled/java-interop/pos/t1231/S.scala similarity index 100% rename from tests/untried/pos/t1231/S.scala rename to tests/disabled/java-interop/pos/t1231/S.scala diff --git a/tests/untried/pos/t1232/J.java b/tests/disabled/java-interop/pos/t1232/J.java similarity index 100% rename from tests/untried/pos/t1232/J.java rename to tests/disabled/java-interop/pos/t1232/J.java diff --git a/tests/untried/pos/t1232/J2.java b/tests/disabled/java-interop/pos/t1232/J2.java similarity index 100% rename from tests/untried/pos/t1232/J2.java rename to tests/disabled/java-interop/pos/t1232/J2.java diff --git a/tests/untried/pos/t1232/S.scala b/tests/disabled/java-interop/pos/t1232/S.scala similarity index 100% rename from tests/untried/pos/t1232/S.scala rename to tests/disabled/java-interop/pos/t1232/S.scala diff --git a/tests/untried/pos/t1235/Test.java b/tests/disabled/java-interop/pos/t1235/Test.java similarity index 100% rename from tests/untried/pos/t1235/Test.java rename to tests/disabled/java-interop/pos/t1235/Test.java diff --git a/tests/untried/pos/t1254/t1254.java b/tests/disabled/java-interop/pos/t1254/t1254.java similarity index 100% rename from tests/untried/pos/t1254/t1254.java rename to tests/disabled/java-interop/pos/t1254/t1254.java diff --git a/tests/untried/pos/t1263/Test.java b/tests/disabled/java-interop/pos/t1263/Test.java similarity index 100% rename from tests/untried/pos/t1263/Test.java rename to tests/disabled/java-interop/pos/t1263/Test.java diff --git a/tests/untried/pos/t1263/test.scala b/tests/disabled/java-interop/pos/t1263/test.scala similarity index 100% rename from tests/untried/pos/t1263/test.scala rename to tests/disabled/java-interop/pos/t1263/test.scala diff --git a/tests/untried/pos/t1029/Test_1.scala b/tests/pos/t1029/Test_1.scala similarity index 100% rename from tests/untried/pos/t1029/Test_1.scala rename to tests/pos/t1029/Test_1.scala diff --git a/tests/untried/pos/t1029/Test_2.scala b/tests/pos/t1029/Test_2.scala similarity index 100% rename from tests/untried/pos/t1029/Test_2.scala rename to tests/pos/t1029/Test_2.scala diff --git a/tests/untried/pos/t1107b/O.scala b/tests/pos/t1107b/O.scala similarity index 100% rename from tests/untried/pos/t1107b/O.scala rename to tests/pos/t1107b/O.scala diff --git a/tests/untried/pos/t1107b/T.scala b/tests/pos/t1107b/T.scala similarity index 100% rename from tests/untried/pos/t1107b/T.scala rename to tests/pos/t1107b/T.scala From 7e1343e86a0d2575d596198d0f889b7d64cdb5a4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 20 Mar 2014 10:06:31 +0100 Subject: [PATCH 18/22] Refactored lookupRefined Turned parameter into receiver (reciever was not used before at all). --- src/dotty/tools/dotc/core/TypeComparer.scala | 4 ++-- src/dotty/tools/dotc/core/Types.scala | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 753a72dd0583..d66d4069c0b9 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -640,14 +640,14 @@ class TypeComparer(initctx: Context) extends DotClass { * if it is not instantiated we compare type parameter bounds * and also compare variances. */ - def isSubTypeHK(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSubTypeHK(${tp1.show}, ${tp2.show}") { + def isSubTypeHK(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSubTypeHK(${tp1.show}, ${tp2.show}", subtyping) { val tparams = tp1.typeParams val argInfos1 = tp1.argInfos val args1 = if (argInfos1.nonEmpty) argInfos1 // tp1 is instantiated, use the argument infos else { // tp1 is uninstantiated, use the parameter bounds val base = tp1.narrow - tparams.map(base.memberInfo) + tparams.map(base.memberInfo) } val hkArgs = tp2.argInfos hk.println(s"isSubTypeHK: args1 = $args1, hkargs = $hkArgs") diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 38c07d99ac21..e9c3c56b2284 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -625,11 +625,11 @@ object Types { * * to just U */ - def lookupRefined(pre: Type, name: Name)(implicit ctx: Context): Type = pre.stripTypeVar match { + def lookupRefined(name: Name)(implicit ctx: Context): Type = stripTypeVar match { case pre: RefinedType => - if (pre.refinedName ne name) lookupRefined(pre.parent, name) + if (pre.refinedName ne name) pre.parent.lookupRefined(name) else pre.refinedInfo match { - case TypeBounds(lo, hi) if lo eq hi => hi + case TypeBounds(lo, hi) /*if lo eq hi*/ => hi case _ => NoType } case pre: WildcardType => @@ -643,7 +643,7 @@ object Types { case name: TermName => TermRef(this, name) case name: TypeName => - val res = lookupRefined(this, name) + val res = lookupRefined(name) if (res.exists) res else TypeRef(this, name) } @@ -652,7 +652,7 @@ object Types { case name: TermName => TermRef(this, name, denot) case name: TypeName => - val res = lookupRefined(this, name) + val res = lookupRefined(name) if (res.exists) res else TypeRef(this, name, denot) } @@ -660,7 +660,7 @@ object Types { def select(sym: Symbol)(implicit ctx: Context): Type = if (sym.isTerm) TermRef(this, sym.asTerm) else { - val res = lookupRefined(this, sym.name) + val res = lookupRefined(sym.name) if (res.exists) res else TypeRef(this, sym.asType) } @@ -1114,7 +1114,7 @@ object Types { def derivedSelect(prefix: Type)(implicit ctx: Context): Type = if (prefix eq this.prefix) this else { - val res = lookupRefined(prefix, name) + val res = prefix.lookupRefined(name) if (res.exists) res else newLikeThis(prefix) } @@ -2299,7 +2299,7 @@ object Types { case tp: TypeRef => if (stopAtStatic && tp.symbol.isStatic) x else { - val tp1 = tp.lookupRefined(tp.prefix, tp.name) + val tp1 = tp.prefix.lookupRefined(tp.name) this(x, if (tp1.exists) tp1 else tp.prefix) } case tp: TermRef => From 07939c96715cd5adf7f220d239f61b73dd00edc3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 20 Mar 2014 10:07:24 +0100 Subject: [PATCH 19/22] Fix of t1279a: baseTypeWithArgs baseTypeWithArgs now also keeps track of refinements in the subtypes. Without that, the approximated lub in t1279a is too coarse and the program fails to typecheck. --- .../tools/dotc/core/TypeApplications.scala | 30 +++++++++++++++---- tests/{pending => }/pos/t1279a.scala | 0 2 files changed, 25 insertions(+), 5 deletions(-) rename tests/{pending => }/pos/t1279a.scala (100%) diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 2e936e2f16c1..b61f39ed7f0e 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -10,6 +10,7 @@ import util.common._ import Names._ import Flags._ import util.Positions.Position +import config.Printers._ import collection.mutable object TypeApplications { @@ -195,13 +196,32 @@ class TypeApplications(val self: Type) extends AnyVal { NoType } - /** The base type including all type arguments of this type. + /** The base type including all type arguments and applicable refinements + * of this type. Refinements are applicable if they refine a member of + * the parent type which furthermore is not a name-mangled type parameter. * Existential types in arguments are returned as TypeBounds instances. */ - final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = self.dealias match { - case AndType(tp1, tp2) => tp1.baseTypeWithArgs(base) & tp2.baseTypeWithArgs(base) - case OrType(tp1, tp2) => tp1.baseTypeWithArgs(base) | tp2.baseTypeWithArgs(base) - case _ => self.baseTypeRef(base).appliedTo(baseArgInfos(base)) + final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"btwa ${self.show} wrt $base", core, show = true) { + def default = self.baseTypeRef(base).appliedTo(baseArgInfos(base)) + self match { + case tp: TypeRef => + tp.info match { + case TypeBounds(_, hi) => hi.baseTypeWithArgs(base) + case _ => default + } + case tp @ RefinedType(parent, name) if !tp.member(name).symbol.is(ExpandedTypeParam) => + val pbase = parent.baseTypeWithArgs(base) + if (pbase.member(name).exists) RefinedType(pbase, name, tp.refinedInfo) + else pbase + case tp: TermRef => + tp.underlying.baseTypeWithArgs(base) + case AndType(tp1, tp2) => + tp1.baseTypeWithArgs(base) & tp2.baseTypeWithArgs(base) + case OrType(tp1, tp2) => + tp1.baseTypeWithArgs(base) | tp2.baseTypeWithArgs(base) + case _ => + default + } } /** Translate a type of the form From[T] to To[T], keep other types as they are. diff --git a/tests/pending/pos/t1279a.scala b/tests/pos/t1279a.scala similarity index 100% rename from tests/pending/pos/t1279a.scala rename to tests/pos/t1279a.scala From 72a5f392bf11b6474b351cd81a17d0ceeed13dcc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 20 Mar 2014 10:54:25 +0100 Subject: [PATCH 20/22] Reverting decision what constitutes a double def. test case t0273. Was positive in Scala 2, is now deemed to be negative. Two two definitions def a = () => () def a[T] = (p:A) => () do have matching signatures, so should constitute a double definition. I previously thought that we can get away if the two definitions have different result types, but then you immediately have a problem because the denotations have matching signatures for the pruposes of "&" yet cannot be merged. Which of the two definitions would override a definition in a base class is then an arbitrary decision. --- src/dotty/tools/dotc/typer/Checking.scala | 2 +- test/dotc/tests.scala | 9 +++++---- tests/{pos => neg}/t0273.scala | 0 tests/pos/overloaded.scala | 14 +++++++------- 4 files changed, 13 insertions(+), 12 deletions(-) rename tests/{pos => neg}/t0273.scala (100%) diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index a81e4079a1c5..36822cb851b5 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -124,7 +124,7 @@ trait Checking extends NoChecking { for (decl <- cls.info.decls) { for (other <- seen(decl.name)) { typr.println(i"conflict? $decl $other") - if (decl.signature == other.signature) { + if (decl.signature matches other.signature) { def doubleDefError(decl: Symbol, other: Symbol): Unit = { def ofType = if (decl.isType) "" else i": ${other.info}" def explanation = diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 4b52b93c26cb..ed6f3b5d9166 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -53,15 +53,16 @@ class tests extends CompilerTest { @Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4) @Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2) @Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3) - @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 6) + @Test def neg_typers() = compileFile(negDir, "typers", xerrors = 10) @Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2) @Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2) @Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3) - @Test def neg_i39 = compileFile(negDir, "i39", xerrors = 1) - @Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 4) - @Test def neg_companions = compileFile(negDir, "companions", xerrors = 1) @Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 3) @Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3) + @Test def neg_companions = compileFile(negDir, "companions", xerrors = 1) + @Test def neg_i39 = compileFile(negDir, "i39", xerrors = 1) + @Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 4) + @Test def neg_t0273_doubledefs = compileFile(negDir, "t0273", xerrors = 1) @Test def neg_t0654_polyalias = compileFile(negDir, "t0654", xerrors = 2) @Test def neg_t1192_legalPrefix = compileFile(negDir, "t1192", xerrors = 1) diff --git a/tests/pos/t0273.scala b/tests/neg/t0273.scala similarity index 100% rename from tests/pos/t0273.scala rename to tests/neg/t0273.scala diff --git a/tests/pos/overloaded.scala b/tests/pos/overloaded.scala index ebc1501d8580..a26b9b859a8f 100644 --- a/tests/pos/overloaded.scala +++ b/tests/pos/overloaded.scala @@ -2,23 +2,23 @@ object overloaded { def f(x: String): String = x def f[T >: Null](x: T): Int = 1 - + val x1 = f("abc") val x2 = f(new Integer(1)) val x3 = f(null) - + val x4: String => String = f val x5: String => Any = f val x6: Any = f _ - + def g(): Int = 1 def g(x: Int): Int = 2 - + val y1: Int => Int = g - val y2: Any = g _ - + val y2: Any = g _ + println(g) - + val xs = List("a", "b") xs.mkString } From 5f318bc925c227d2bce5cff31610803185b57f54 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 20 Mar 2014 10:51:01 +0100 Subject: [PATCH 21/22] Fix of t1272: overloading resolution stripImplicits needs to take polytypes into account. --- src/dotty/tools/dotc/typer/Applications.scala | 12 +++++++++--- tests/{pending => }/pos/t1272.scala | 0 2 files changed, 9 insertions(+), 3 deletions(-) rename tests/{pending => }/pos/t1272.scala (100%) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 4d26532d656e..46a6ebf66a16 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -785,9 +785,13 @@ trait Applications extends Compatibility { self: Typer => }} /** Drop any implicit parameter section */ - def stripImplicit(tp: Type) = tp match { - case mt: ImplicitMethodType if !mt.isDependent => mt.resultType // todo: make sure implicit method types are not dependent - case _ => tp + def stripImplicit(tp: Type): Type = tp match { + case mt: ImplicitMethodType if !mt.isDependent => + mt.resultType // todo: make sure implicit method types are not dependent + case pt: PolyType => + pt.derivedPolyType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) + case _ => + tp } val owner1 = alt1.symbol.owner @@ -800,6 +804,8 @@ trait Applications extends Compatibility { self: Typer => def winsOwner2 = isDerived(owner2, owner1) def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1) + implicits.println(i"isAsGood($alt1, $alt2)? $tp1 $tp2 $winsOwner1 $winsType1 $winsOwner2 $winsType2") + // Assume the following probabilities: // // P(winsOwnerX) = 2/3 diff --git a/tests/pending/pos/t1272.scala b/tests/pos/t1272.scala similarity index 100% rename from tests/pending/pos/t1272.scala rename to tests/pos/t1272.scala From 9b17c6c86f3150afa7b5b395c23ec3fdf9c14200 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 21 Mar 2014 18:39:35 +0100 Subject: [PATCH 22/22] Fix of Fix of t1236: higher-kinded Fix of d6df293d2120f2247198cb6646a23c338f7dcbbf. It turned out the original commit was faulty in that iterator.flatten did not typecheck. The problem is fixed in this commit and flatten is added to the collections test. --- src/dotty/tools/dotc/core/TypeComparer.scala | 6 +++--- src/dotty/tools/dotc/core/Types.scala | 5 ++++- tests/pos/collections.scala | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index d66d4069c0b9..ce1c1e869cde 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -649,13 +649,13 @@ class TypeComparer(initctx: Context) extends DotClass { val base = tp1.narrow tparams.map(base.memberInfo) } - val hkArgs = tp2.argInfos - hk.println(s"isSubTypeHK: args1 = $args1, hkargs = $hkArgs") - val boundsOK = (args1 corresponds hkArgs)(isSubType) + val hkBounds = tp2.argInfos.map(_.asInstanceOf[TypeBounds]) + val boundsOK = (hkBounds corresponds args1)(_ contains _) val variancesOK = argInfos1.nonEmpty || (tparams corresponds tp2.typeSymbol.name.hkVariances) { (tparam, v) => v == 0 || tparam.variance == v } + hk.println(s"isSubTypeHK: args1 = $args1, hk-bounds = $hkBounds $boundsOK $variancesOK") boundsOK && variancesOK } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e9c3c56b2284..7cd66f5ddd5f 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1926,7 +1926,10 @@ object Types { if (lo eq tp) this else TypeAlias(tp, variance) - def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi + def contains(tp: Type)(implicit ctx: Context) = tp match { + case tp: TypeBounds => lo <:< tp.lo && tp.hi <:< hi + case _ => lo <:< tp && tp <:< hi + } def & (that: TypeBounds)(implicit ctx: Context): TypeBounds = { val v = this commonVariance that diff --git a/tests/pos/collections.scala b/tests/pos/collections.scala index cd84f03d83c1..535e4b542143 100644 --- a/tests/pos/collections.scala +++ b/tests/pos/collections.scala @@ -1,10 +1,10 @@ import scala.collection.generic.CanBuildFrom object collections { - + val arr = Array("a", "b") val aa = arr ++ arr - + List(1, 2, 3) map (x => 2) val s = Set(1, 2, 3) @@ -18,16 +18,19 @@ object collections { val ints3: List[Int] = ints2 val f = (x: Int) => x + 1 val ints4: List[Int] = List(1, 2, 3, 5) - + val ys = ints3 map (x => x + 1) val zs = ys filter (y => y != 0) - + val chrs = "abc" - + def do2(x: Int, y: Char) = () - + chrs foreach println - + (ints2, chrs).zipped foreach do2 -} \ No newline at end of file + val xs = List(List(1), List(2), List(3)).iterator + println(xs.flatten) + +}