Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-8371

Very bad: Change in variable scoping behavior in anonymous inner classes in 2.11-RC1

    Details

      Description

      Scala seems to be picking out the wrong instance variable:

      import scala.collection.mutable._
       
      class Beam { outer =>
        private val queue = new ArrayBuffer[Int]()
       
        def foo {
          outer.queue += 42
          new Beam {
            println(queue)
            assert(queue.length == 0) // boom
          }
        }
      }
       
      // 2.10: prints ArrayBuffer()
      // 2.11: prints ArrayBuffer(42) and then throws assertion error.
      (new Beam).foo() 
      
      

        Attachments

          Activity

          Show
          moors Adriaan Moors added a comment - - edited regressed fixed in https://github.com/adriaanm/scala/commit/8d96380caeb1f03da8916d494e878f57a363f459
          Hide
          moors Adriaan Moors added a comment -

          Minimized:

          class Foo[T] {
            private val bar: T = ???
           
            new Foo[String] { bar: String }
          }
          

          Show
          moors Adriaan Moors added a comment - Minimized: class Foo[T] { private val bar: T = ??? new Foo[String] { bar: String } }
          Hide
          moors Adriaan Moors added a comment -

          I was confused (again!) as well, but this is actually as specified. Here's another example of where this surprised: https://github.com/ktoso/akka/commit/e7ffaeb6fa5c181161a55c9ab41c1be3df83ebc9
          bar is private, so it won't be seen as a member of a subclass of Foo. It is however in scope due to the lexical nesting of the `bar: String` expression.

          We should probably add this to the release notes...

          Show
          moors Adriaan Moors added a comment - I was confused (again!) as well, but this is actually as specified. Here's another example of where this surprised: https://github.com/ktoso/akka/commit/e7ffaeb6fa5c181161a55c9ab41c1be3df83ebc9 bar is private, so it won't be seen as a member of a subclass of Foo. It is however in scope due to the lexical nesting of the `bar: String` expression. We should probably add this to the release notes...
          Hide
          dlwh david hall added a comment -

          Huh, sorry about that!

          The change does show up in a lot of places. So the new (implemented) semantics of private are that the name is actually totally passed over, rather than being a compile-time error? That does make more sense then the way it's been, I guess.

          Show
          dlwh david hall added a comment - Huh, sorry about that! The change does show up in a lot of places. So the new (implemented) semantics of private are that the name is actually totally passed over, rather than being a compile-time error? That does make more sense then the way it's been, I guess.

            People

            • Assignee:
              moors Adriaan Moors
              Reporter:
              dlwh david hall
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: