From d47a15b01557ca6c6416892a98d35324bf0a13d7 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 20 Sep 2012 17:05:43 -0700 Subject: Pending tests for SI-5954, SI-6225, SI-5877, SI-4695. Which are all package object bugs. Plus one more test regarding package object overloading. --- test/pending/pos/overloading-boundaries.scala | 37 +++++++++++++++++++++++++++ test/pending/pos/t4695/T_1.scala | 4 +++ test/pending/pos/t4695/T_2.scala | 4 +++ test/pending/pos/t5877.scala | 5 ++++ test/pending/pos/t5954/T_1.scala | 8 ++++++ test/pending/pos/t5954/T_2.scala | 8 ++++++ test/pending/pos/t5954/T_3.scala | 8 ++++++ test/pending/pos/t6225.scala | 11 ++++++++ 8 files changed, 85 insertions(+) create mode 100644 test/pending/pos/overloading-boundaries.scala create mode 100644 test/pending/pos/t4695/T_1.scala create mode 100644 test/pending/pos/t4695/T_2.scala create mode 100644 test/pending/pos/t5877.scala create mode 100644 test/pending/pos/t5954/T_1.scala create mode 100644 test/pending/pos/t5954/T_2.scala create mode 100644 test/pending/pos/t5954/T_3.scala create mode 100644 test/pending/pos/t6225.scala (limited to 'test') diff --git a/test/pending/pos/overloading-boundaries.scala b/test/pending/pos/overloading-boundaries.scala new file mode 100644 index 0000000000..d2e9fdbb12 --- /dev/null +++ b/test/pending/pos/overloading-boundaries.scala @@ -0,0 +1,37 @@ +package bar { + object bippy extends (Double => String) { + def apply(x: Double): String = "Double" + } +} + +package object bar { + def bippy(x: Int, y: Int, z: Int) = "(Int, Int, Int)" +} + +object Test { + def main(args: Array[String]): Unit = { + println(bar.bippy(5.5d)) + println(bar.bippy(1, 2, 3)) + } +} + +/**** + +% scalac3 a.scala +a.scala:13: error: not enough arguments for method bippy: (x: Int, y: Int, z: Int)String. +Unspecified value parameters y, z. + println(bar.bippy(5.5d)) + ^ +one error found + +# Comment out the call to bar.bippy(5.5d) - compiles +% scalac3 a.scala + +# Compiles only from pure source though - if classes are present, fails. +% scalac3 a.scala +a.scala:2: error: bippy is already defined as method bippy in package object bar + object bippy extends (Double => String) { + ^ +one error found + +****/ diff --git a/test/pending/pos/t4695/T_1.scala b/test/pending/pos/t4695/T_1.scala new file mode 100644 index 0000000000..70fb1a7f21 --- /dev/null +++ b/test/pending/pos/t4695/T_1.scala @@ -0,0 +1,4 @@ +package foo + +class Bar { } +package object Bar { } diff --git a/test/pending/pos/t4695/T_2.scala b/test/pending/pos/t4695/T_2.scala new file mode 100644 index 0000000000..70fb1a7f21 --- /dev/null +++ b/test/pending/pos/t4695/T_2.scala @@ -0,0 +1,4 @@ +package foo + +class Bar { } +package object Bar { } diff --git a/test/pending/pos/t5877.scala b/test/pending/pos/t5877.scala new file mode 100644 index 0000000000..b77605f7f2 --- /dev/null +++ b/test/pending/pos/t5877.scala @@ -0,0 +1,5 @@ +package foo { } + +package object foo { + implicit class Foo(val s: String) { } +} diff --git a/test/pending/pos/t5954/T_1.scala b/test/pending/pos/t5954/T_1.scala new file mode 100644 index 0000000000..0064c596b6 --- /dev/null +++ b/test/pending/pos/t5954/T_1.scala @@ -0,0 +1,8 @@ +package p { + package base { + class X + } + package object base { + case class B() + } +} diff --git a/test/pending/pos/t5954/T_2.scala b/test/pending/pos/t5954/T_2.scala new file mode 100644 index 0000000000..0064c596b6 --- /dev/null +++ b/test/pending/pos/t5954/T_2.scala @@ -0,0 +1,8 @@ +package p { + package base { + class X + } + package object base { + case class B() + } +} diff --git a/test/pending/pos/t5954/T_3.scala b/test/pending/pos/t5954/T_3.scala new file mode 100644 index 0000000000..0064c596b6 --- /dev/null +++ b/test/pending/pos/t5954/T_3.scala @@ -0,0 +1,8 @@ +package p { + package base { + class X + } + package object base { + case class B() + } +} diff --git a/test/pending/pos/t6225.scala b/test/pending/pos/t6225.scala new file mode 100644 index 0000000000..d7dff3c419 --- /dev/null +++ b/test/pending/pos/t6225.scala @@ -0,0 +1,11 @@ +package library.x { + class X { + class Foo + implicit val foo = new Foo + } +} +package library { package object x extends X } +package app { + import library.x._ + object App { implicitly[Foo] } +} -- cgit v1.2.3 From e6f10b07d44f0ddde26246b4a41527a84eede81c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 26 Sep 2012 12:14:13 -0700 Subject: Fixed SI-5604, selections on package objects. mkAttributedSelect, which creates a Select tree based on a symbol, has been a major source of package object bugs, because it has not been accurately identifying selections on package objects. When selecting foo.bar, if foo turns out to be a package object, the created Select tree must be foo.`package`.bar However mkAttributedSelect was only examining the owner of the symbol, which means it would work if the package object defined bar directly, but not if it inherited it. --- src/reflect/scala/reflect/internal/TreeGen.scala | 25 ++++++++++-- test/files/pos/t5604b/T_1.scala | 6 +++ test/files/pos/t5604b/T_2.scala | 6 +++ test/files/pos/t5604b/Test_1.scala | 7 ++++ test/files/pos/t5604b/Test_2.scala | 7 ++++ test/files/pos/t5604b/pack_1.scala | 5 +++ test/files/run/t5604.check | 8 ++++ test/files/run/t5604.scala | 50 ++++++++++++++++++++++++ 8 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 test/files/pos/t5604b/T_1.scala create mode 100644 test/files/pos/t5604b/T_2.scala create mode 100644 test/files/pos/t5604b/Test_1.scala create mode 100644 test/files/pos/t5604b/Test_2.scala create mode 100644 test/files/pos/t5604b/pack_1.scala create mode 100644 test/files/run/t5604.check create mode 100644 test/files/run/t5604.scala (limited to 'test') diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index ebf0998573..c1753fc5a1 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -172,10 +172,29 @@ abstract class TreeGen extends macros.TreeBuilder { if (qual.symbol != null && (qual.symbol.isEffectiveRoot || qual.symbol.isEmptyPackage)) mkAttributedIdent(sym) else { + // Have to recognize anytime a selection is made on a package + // so it can be rewritten to foo.bar.`package`.name rather than + // foo.bar.name if name is in the package object. + // TODO - factor out the common logic between this and + // the Typers method "isInPackageObject", used in typedIdent. + val qualsym = ( + if (qual.tpe ne null) qual.tpe.typeSymbol + else if (qual.symbol ne null) qual.symbol + else NoSymbol + ) + val needsPackageQualifier = ( + (sym ne null) + && qualsym.isPackage + && !sym.isDefinedInPackage + ) val pkgQualifier = - if (sym != null && sym.owner.isPackageObjectClass && sym.effectiveOwner == qual.tpe.typeSymbol) { - val obj = sym.owner.sourceModule - Select(qual, nme.PACKAGE) setSymbol obj setType singleType(qual.tpe, obj) + if (needsPackageQualifier) { + // The owner of a symbol which requires package qualification may be the + // package object iself, but it also could be any superclass of the package + // object. In the latter case, we must go through the qualifier's info + // to obtain the right symbol. + val packageObject = if (sym.owner.isModuleClass) sym.owner.sourceModule else qual.tpe member nme.PACKAGE + Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject) } else qual diff --git a/test/files/pos/t5604b/T_1.scala b/test/files/pos/t5604b/T_1.scala new file mode 100644 index 0000000000..179dcb10c6 --- /dev/null +++ b/test/files/pos/t5604b/T_1.scala @@ -0,0 +1,6 @@ +// sandbox/t5604/T.scala +package t6504 + +trait T { + def foo: Boolean = false +} diff --git a/test/files/pos/t5604b/T_2.scala b/test/files/pos/t5604b/T_2.scala new file mode 100644 index 0000000000..179dcb10c6 --- /dev/null +++ b/test/files/pos/t5604b/T_2.scala @@ -0,0 +1,6 @@ +// sandbox/t5604/T.scala +package t6504 + +trait T { + def foo: Boolean = false +} diff --git a/test/files/pos/t5604b/Test_1.scala b/test/files/pos/t5604b/Test_1.scala new file mode 100644 index 0000000000..f7c58ebe83 --- /dev/null +++ b/test/files/pos/t5604b/Test_1.scala @@ -0,0 +1,7 @@ +// sandbox/t5604/Test.scala +package t6504 + +object Test { + def blerg1(a: Any): Any = if (foo) blerg1(0) + def blerg2(a: Any): Any = if (t6504.foo) blerg2(0) +} diff --git a/test/files/pos/t5604b/Test_2.scala b/test/files/pos/t5604b/Test_2.scala new file mode 100644 index 0000000000..f7c58ebe83 --- /dev/null +++ b/test/files/pos/t5604b/Test_2.scala @@ -0,0 +1,7 @@ +// sandbox/t5604/Test.scala +package t6504 + +object Test { + def blerg1(a: Any): Any = if (foo) blerg1(0) + def blerg2(a: Any): Any = if (t6504.foo) blerg2(0) +} diff --git a/test/files/pos/t5604b/pack_1.scala b/test/files/pos/t5604b/pack_1.scala new file mode 100644 index 0000000000..f50d568bfa --- /dev/null +++ b/test/files/pos/t5604b/pack_1.scala @@ -0,0 +1,5 @@ +// sandbox/t5604/pack.scala +package t6504 + +object `package` extends T { +} diff --git a/test/files/run/t5604.check b/test/files/run/t5604.check new file mode 100644 index 0000000000..53a2fc8894 --- /dev/null +++ b/test/files/run/t5604.check @@ -0,0 +1,8 @@ +long +double +long +double +long +double +long +double diff --git a/test/files/run/t5604.scala b/test/files/run/t5604.scala new file mode 100644 index 0000000000..a06c8aab3e --- /dev/null +++ b/test/files/run/t5604.scala @@ -0,0 +1,50 @@ +// a.scala +// Fri Jan 13 11:31:47 PST 2012 + +package foo { + object regular extends Duh { + def buh(n: Long) = println("long") + def buh(n: Double) = println("double") + } + class regular { + import regular._ + + duh(33L) + duh(3.0d) + foo.regular.duh(33L) + foo.regular.duh(3.0d) + buh(66L) + buh(6.0d) + foo.regular.buh(66L) + foo.regular.buh(6.0d) + } + + trait Duh { + def duh(n: Long) = println("long") + def duh(n: Double) = println("double") + } + package object bar extends Duh { + def buh(n: Long) = println("long") + def buh(n: Double) = println("double") + } + package bar { + object Main { + def main(args:Array[String]) { + duh(33L) + duh(3.0d) + foo.bar.duh(33L) + foo.bar.duh(3.0d) + buh(66L) + buh(6.0d) + foo.bar.buh(66L) + foo.bar.buh(6.0d) + } + } + } +} + +object Test { + def main(args: Array[String]): Unit = { + foo.bar.Main.main(null) + } +} -- cgit v1.2.3