summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2012-12-15 11:15:58 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2012-12-15 11:15:58 -0800
commit14b804556e3522042413a1d5e689d3e4db1e1635 (patch)
tree075de34a22172d94dcb3f8452e5c5a47e997ce72
parent14aa26ca0c346adbc79ccf4c0c9c35bbdd80c201 (diff)
parent8b7f0acb73147b7a779fd79e61485c191740ac4e (diff)
downloadscala-14b804556e3522042413a1d5e689d3e4db1e1635.tar.gz
scala-14b804556e3522042413a1d5e689d3e4db1e1635.tar.bz2
scala-14b804556e3522042413a1d5e689d3e4db1e1635.zip
Merge pull request #1706 from retronym/ticket/5361
SI-5361 Avoid cyclic type with malformed refinement
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
-rw-r--r--test/files/neg/t3614.check4
-rw-r--r--test/files/neg/t5361.check4
-rw-r--r--test/files/neg/t5361.scala3
4 files changed, 18 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e4744de1b8..f8adcaa25b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2835,6 +2835,7 @@ trait Typers extends Modes with Adaptations with Tags {
def typedRefinement(templ: Template) {
val stats = templ.body
namer.enterSyms(stats)
+
// need to delay rest of typedRefinement to avoid cyclic reference errors
unit.toCheck += { () =>
val stats1 = typedStats(stats, NoSymbol)
@@ -5180,14 +5181,20 @@ trait Typers extends Modes with Adaptations with Tags {
def typedCompoundTypeTree(tree: CompoundTypeTree) = {
val templ = tree.templ
val parents1 = templ.parents mapConserve (typedType(_, mode))
- if (parents1 exists (_.isErrorTyped)) tree setType ErrorType
+
+ // This is also checked later in typedStats, but that is too late for SI-5361, so
+ // we eagerly check this here.
+ for (stat <- templ.body if !treeInfo.isDeclarationOrTypeDef(stat))
+ OnlyDeclarationsError(stat)
+
+ if ((parents1 ++ templ.body) exists (_.isErrorTyped)) tree setType ErrorType
else {
val decls = newScope
//Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id)
val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos)
newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ)
templ updateAttachment CompoundTypeTreeOriginalAttachment(parents1, Nil) // stats are set elsewhere
- tree setType self
+ tree setType (if (templ.exists(_.isErroneous)) ErrorType else self) // Being conservative to avoid SI-5361
}
}
diff --git a/test/files/neg/t3614.check b/test/files/neg/t3614.check
index 0f9c83aa0d..81628ef37f 100644
--- a/test/files/neg/t3614.check
+++ b/test/files/neg/t3614.check
@@ -1,4 +1,4 @@
-t3614.scala:2: error: class type required but AnyRef{def a: Int} found
+t3614.scala:2: error: only declarations allowed here
def v = new ({ def a=0 })
- ^
+ ^
one error found
diff --git a/test/files/neg/t5361.check b/test/files/neg/t5361.check
new file mode 100644
index 0000000000..d7fee87ccd
--- /dev/null
+++ b/test/files/neg/t5361.check
@@ -0,0 +1,4 @@
+t5361.scala:2: error: only declarations allowed here
+ val x : { val self = this } = new { self => }
+ ^
+one error found
diff --git a/test/files/neg/t5361.scala b/test/files/neg/t5361.scala
new file mode 100644
index 0000000000..1705c09df3
--- /dev/null
+++ b/test/files/neg/t5361.scala
@@ -0,0 +1,3 @@
+class A {
+ val x : { val self = this } = new { self => }
+}