summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-09-10 00:51:42 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-09-10 00:51:42 -0700
commit68da47c7ef0ab38447b89b36af0cc37d6242604a (patch)
tree727e59dc2158887cb281366b80604911942817a2
parentb93f4bfce69e2780f440650b6047ce509ff7eaae (diff)
parentb255617a6b56af810a3f065ccb887a2b4d36e631 (diff)
downloadscala-68da47c7ef0ab38447b89b36af0cc37d6242604a.tar.gz
scala-68da47c7ef0ab38447b89b36af0cc37d6242604a.tar.bz2
scala-68da47c7ef0ab38447b89b36af0cc37d6242604a.zip
Merge pull request #2915 from retronym/ticket/7817
SI-7817 Fix regression in structural types
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
-rw-r--r--test/files/run/t7817-tree-gen.check104
-rw-r--r--test/files/run/t7817-tree-gen.flags1
-rw-r--r--test/files/run/t7817-tree-gen.scala65
-rw-r--r--test/files/run/t7817.scala31
5 files changed, 202 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 1af8c225f5..4d3e4d9563 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -185,7 +185,7 @@ abstract class TreeGen extends macros.TreeBuilder {
val needsPackageQualifier = (
(sym ne null)
&& qualsym.isPackage
- && !sym.isDefinedInPackage
+ && !(sym.isDefinedInPackage || sym.moduleClass.isDefinedInPackage) // SI-7817 work around strangeness in post-flatten `Symbol#owner`
)
val pkgQualifier =
if (needsPackageQualifier) {
diff --git a/test/files/run/t7817-tree-gen.check b/test/files/run/t7817-tree-gen.check
new file mode 100644
index 0000000000..4ed4b0d94a
--- /dev/null
+++ b/test/files/run/t7817-tree-gen.check
@@ -0,0 +1,104 @@
+
+
+Joint Compilation:
+
+ typer [ O] - O.this
+ pickler [ O] - O.this
+ refchecks [ O] - O.this
+ uncurry [ O] - O.this
+ specialize [ O] - O.this
+ explicitouter [ O] - O.this
+ erasure [ O] - O.this
+ posterasure [ O] - C.this.O()
+ flatten [ O] - C.this.O()
+ mixin [ O] - test.O()
+ cleanup [ O] - test.O()
+
+ typer [ P] - P.this
+ pickler [ P] - P.this
+ refchecks [ P] - P.this
+ uncurry [ P] - P.this
+ specialize [ P] - P.this
+ explicitouter [ P] - P.this
+ erasure [ P] - P.this
+ posterasure [ P] - D.this.P()
+ flatten [ P] - D.this.P()
+ mixin [ P] - P()
+ cleanup [ P] - P()
+
+ typer [ test2.PO] - PO.this
+ pickler [ test2.PO] - PO.this
+ refchecks [ test2.PO] - PO.this
+ uncurry [ test2.PO] - PO.this
+ specialize [ test2.PO] - PO.this
+ explicitouter [ test2.PO] - PO.this
+ erasure [ test2.PO] - PO.this
+ posterasure [ test2.PO] - test2.`package`.PO
+ flatten [ test2.PO] - test2.`package`.PO
+ mixin [ test2.PO] - test2.package$PO
+ cleanup [ test2.PO] - test2.package$PO
+
+ typer [ test2.bar] - `package`.this.bar
+ pickler [ test2.bar] - `package`.this.bar
+ refchecks [ test2.bar] - `package`.this.bar
+ uncurry [ test2.bar] - `package`.this.bar
+ specialize [ test2.bar] - `package`.this.bar
+ explicitouter [ test2.bar] - `package`.this.bar
+ erasure [ test2.bar] - `package`.this.bar
+ posterasure [ test2.bar] - test2.`package`.bar
+ flatten [ test2.bar] - test2.`package`.bar
+ mixin [ test2.bar] - test2.`package`.bar
+ cleanup [ test2.bar] - test2.`package`.bar
+
+
+
+Separate Compilation:
+
+ typer [ O] - O.this
+ pickler [ O] - O.this
+ refchecks [ O] - O.this
+ uncurry [ O] - O.this
+ specialize [ O] - O.this
+ explicitouter [ O] - O.this
+ erasure [ O] - O.this
+ posterasure [ O] - C.this.O()
+ flatten [ O] - C.this.O()
+ mixin [ O] - testSep.O()
+ cleanup [ O] - testSep.O()
+
+ typer [ P] - P.this
+ pickler [ P] - P.this
+ refchecks [ P] - P.this
+ uncurry [ P] - P.this
+ specialize [ P] - P.this
+ explicitouter [ P] - P.this
+ erasure [ P] - P.this
+ posterasure [ P] - DSep.this.P()
+ flatten [ P] - DSep.this.P()
+ mixin [ P] - P()
+ cleanup [ P] - P()
+
+ typer [ PO] - PO.this
+ pickler [ PO] - PO.this
+ refchecks [ PO] - PO.this
+ uncurry [ PO] - PO.this
+ specialize [ PO] - PO.this
+ explicitouter [ PO] - PO.this
+ erasure [ PO] - PO.this
+ posterasure [ PO] - test2.`package`.PO
+ flatten [ PO] - test2.`package`.PO
+ mixin [ PO] - test2.package$PO
+ cleanup [ PO] - test2.package$PO
+
+ typer [testSep2.bar] - `package`.this.bar
+ pickler [testSep2.bar] - `package`.this.bar
+ refchecks [testSep2.bar] - `package`.this.bar
+ uncurry [testSep2.bar] - `package`.this.bar
+ specialize [testSep2.bar] - `package`.this.bar
+ explicitouter [testSep2.bar] - `package`.this.bar
+ erasure [testSep2.bar] - `package`.this.bar
+ posterasure [testSep2.bar] - test2.`package`.bar
+ flatten [testSep2.bar] - test2.`package`.bar
+ mixin [testSep2.bar] - test2.`package`.bar
+ cleanup [testSep2.bar] - test2.`package`.bar
+
diff --git a/test/files/run/t7817-tree-gen.flags b/test/files/run/t7817-tree-gen.flags
new file mode 100644
index 0000000000..ce6e93b3da
--- /dev/null
+++ b/test/files/run/t7817-tree-gen.flags
@@ -0,0 +1 @@
+-Ynooptimise \ No newline at end of file
diff --git a/test/files/run/t7817-tree-gen.scala b/test/files/run/t7817-tree-gen.scala
new file mode 100644
index 0000000000..a8317fda6e
--- /dev/null
+++ b/test/files/run/t7817-tree-gen.scala
@@ -0,0 +1,65 @@
+import scala.tools.partest._
+
+// Testing that `mkAttributedRef` doesn't incude the package object test.`package`,
+// under joint and separate compilation.
+
+package testSep { class C { object O } }
+package testSep2 { object `package` { object PO; def bar = 0 } }
+class DSep { object P }
+
+object Test extends CompilerTest {
+ import global._
+ override def extraSettings = super.extraSettings + " -d " + testOutput.path
+ override def sources = List(
+ """
+ package test { class C { object O } }
+ class D { object P }
+ package test2 { object `package` { object PO; def bar = 0 } }
+ """
+ )
+ def check(source: String, unit: CompilationUnit) = enteringTyper {
+ def checkTree(msg: String, t: => Tree) = {
+ val run = currentRun
+ import run._
+ val phases = List(typerPhase, picklerPhase, refchecksPhase, uncurryPhase, specializePhase,
+ explicitouterPhase, erasurePhase, posterasurePhase, flattenPhase, mixinPhase, cleanupPhase)
+ for (phase <- phases) {
+ enteringPhase(phase) {
+ val error = t.exists(t => t.symbol == NoSymbol)
+ val errorStr = if (error) "!!!" else " - "
+ println(f"$phase%18s [$msg%12s] $errorStr $t")
+ }
+ }
+ println("")
+ }
+ import rootMirror._
+
+ println("\n\nJoint Compilation:\n")
+
+ {
+ val c = staticClass("test.C")
+ val o = c.info.decl(TermName("O"))
+ checkTree("O", gen.mkAttributedQualifier(o.moduleClass.thisType))
+ val d = staticClass("D")
+ val p = d.info.decl(TermName("P"))
+ checkTree("P", gen.mkAttributedQualifier(p.moduleClass.thisType))
+ val po = staticModule("test2.package").moduleClass.info.decl(TermName("PO"))
+ checkTree("test2.PO", gen.mkAttributedQualifier(po.moduleClass.thisType))
+ checkTree("test2.bar", gen.mkAttributedRef(po.owner.info.decl(TermName("bar"))))
+ }
+
+ println("\n\nSeparate Compilation:\n")
+
+ {
+ val c = typeOf[testSep.C].typeSymbol
+ val o = c.info.decl(TermName("O"))
+ checkTree("O", gen.mkAttributedQualifier(o.moduleClass.thisType))
+ val d = staticClass("DSep")
+ val p = d.info.decl(TermName("P"))
+ checkTree("P", gen.mkAttributedQualifier(p.moduleClass.thisType))
+ val po = staticModule("test2.package").moduleClass.info.decl(TermName("PO"))
+ checkTree("PO", gen.mkAttributedQualifier(po.moduleClass.thisType))
+ checkTree("testSep2.bar", gen.mkAttributedRef(po.owner.info.decl(TermName("bar"))))
+ }
+ }
+}
diff --git a/test/files/run/t7817.scala b/test/files/run/t7817.scala
new file mode 100644
index 0000000000..905b8aeb09
--- /dev/null
+++ b/test/files/run/t7817.scala
@@ -0,0 +1,31 @@
+import language.reflectiveCalls
+
+package test {
+ class C1 {
+ object O {
+ def struct(s: {def foo: Any}) = s.foo
+ }
+ }
+ trait T {
+ object O {
+ def struct(s: {def foo: Any}) = s.foo
+ }
+ }
+ object O1 extends T
+
+ object O2 {
+ object O {
+ def struct(s: {def foo: Any}) = s.foo
+ }
+ }
+}
+
+object Test extends App {
+ object fooable { def foo = "foo" }
+ def check(result: Any) = assert(result == "foo", result.toString)
+
+ val s = new test.C1
+ check(s.O.struct(fooable))
+ check(test.O1.O.struct(fooable))
+ check(test.O2.O.struct(fooable))
+}