diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2012-12-04 20:19:01 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2012-12-04 20:19:01 +0100 |
commit | 327083df40d1854f28c00983aed5734fa6a7e6f9 (patch) | |
tree | 7c73e838f328014a79c36d71dde35b0fba3b3963 | |
parent | fd57069a3a49de1757a518b573a0cd8cb98bbbd5 (diff) | |
download | scala-327083df40d1854f28c00983aed5734fa6a7e6f9.tar.gz scala-327083df40d1854f28c00983aed5734fa6a7e6f9.tar.bz2 scala-327083df40d1854f28c00983aed5734fa6a7e6f9.zip |
SI-5361 Avoid cyclic type with malformed refinement
The statement `val x = this` in the refinment type:
(new {}): {val x = this}
is lazily typechecked, in order to, according to the comment
in `typedRefinment, "avoid cyclic reference errors".
But the approximate type used ends up with:
Refinment@1(
parents = [...]
decls = { val x: Refinement@1 })
This commit eagerly checks that there is no term definitions
in type refinments, rather than delaying this.
This changes the error message for SI-3614.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 8 | ||||
-rw-r--r-- | test/files/neg/t3614.check | 4 | ||||
-rw-r--r-- | test/files/neg/t5361.check | 4 | ||||
-rw-r--r-- | test/files/neg/t5361.scala | 3 |
4 files changed, 16 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 5714c2c109..e358917aef 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2710,6 +2710,12 @@ trait Typers extends Modes with Adaptations with Tags { def typedRefinement(templ: Template) { val stats = templ.body namer.enterSyms(stats) + + // This is also checked later in typedStats, but that is too late for SI-5361, so + // we eagerly check this here. + for (stat <- stats if !treeInfo.isDeclarationOrTypeDef(stat)) + OnlyDeclarationsError(stat) + // need to delay rest of typedRefinement to avoid cyclic reference errors unit.toCheck += { () => val stats1 = typedStats(stats, NoSymbol) @@ -5068,7 +5074,7 @@ trait Typers extends Modes with Adaptations with Tags { 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 => } +} |