diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-04-22 09:54:59 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-04-23 09:12:03 +0200 |
commit | d3aa9a7639c3c26b42a8faa9566d0d43a998b723 (patch) | |
tree | 4ac01a84c73fb4056cd7cd979481f4b887c93227 /test/files | |
parent | 5147bb278c326e60956bac93cba95d4e07d95e84 (diff) | |
download | scala-d3aa9a7639c3c26b42a8faa9566d0d43a998b723.tar.gz scala-d3aa9a7639c3c26b42a8faa9566d0d43a998b723.tar.bz2 scala-d3aa9a7639c3c26b42a8faa9566d0d43a998b723.zip |
Warn on selection of vals from DelayedInit subclasses.
Which are likely to yield null, if the program didn't start.
This is a common source of confusion for people new to
the language, as was seen during the Coursera course.
The test case shows that the usage pattern within Specs2
won't generate these warnings.
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/neg/delayed-init-ref.check | 10 | ||||
-rw-r--r-- | test/files/neg/delayed-init-ref.flags | 1 | ||||
-rw-r--r-- | test/files/neg/delayed-init-ref.scala | 42 |
3 files changed, 53 insertions, 0 deletions
diff --git a/test/files/neg/delayed-init-ref.check b/test/files/neg/delayed-init-ref.check new file mode 100644 index 0000000000..42ccabed1b --- /dev/null +++ b/test/files/neg/delayed-init-ref.check @@ -0,0 +1,10 @@ +delayed-init-ref.scala:17: error: Selecting value vall from object O, which extends scala.DelayedInit, is likely to yield an uninitialized value + println(O.vall) // warn + ^ +delayed-init-ref.scala:19: error: Selecting value vall from object O, which extends scala.DelayedInit, is likely to yield an uninitialized value + println(vall) // warn + ^ +delayed-init-ref.scala:40: error: Selecting value foo from trait UserContext, which extends scala.DelayedInit, is likely to yield an uninitialized value + println({locally(()); this}.foo) // warn (spurious, but we can't discriminate) + ^ +three errors found diff --git a/test/files/neg/delayed-init-ref.flags b/test/files/neg/delayed-init-ref.flags new file mode 100644 index 0000000000..7949c2afa2 --- /dev/null +++ b/test/files/neg/delayed-init-ref.flags @@ -0,0 +1 @@ +-Xlint -Xfatal-warnings diff --git a/test/files/neg/delayed-init-ref.scala b/test/files/neg/delayed-init-ref.scala new file mode 100644 index 0000000000..f2aa804e28 --- /dev/null +++ b/test/files/neg/delayed-init-ref.scala @@ -0,0 +1,42 @@ +trait T { + val traitVal = "" +} + +object O extends App with T { + val vall = "" + lazy val lazyy = "" + def deff = "" + + println(vall) // no warn + new { + println(vall) // no warn + } +} + +object Client { + println(O.vall) // warn + import O.vall + println(vall) // warn + + println(O.lazyy) // no warn + println(O.deff) // no warn + println(O.traitVal) // no warn +} + +// Delayed init usage pattern from Specs2 +// See: https://groups.google.com/d/msg/scala-sips/wP6dL8nIAQs/ogjoPE-MSVAJ +trait Before extends DelayedInit { + def before() + override def delayedInit(x: => Unit): Unit = { before; x } +} +object Spec { + trait UserContext extends Before { + def before() = () + val foo = "foo" + } + new UserContext { + println(foo) // no warn + println(this.foo) // no warn + println({locally(()); this}.foo) // warn (spurious, but we can't discriminate) + } +} |