Scala Programming Language
  1. Scala Programming Language
  2. SI-3770

"final lazy val" field being written outside a constructor

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Out of Scope
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Misc Compiler
    • Labels:

      Description

      While verifying the bytecode emitted by Scala.NET I noticed a "final lazy val" field being written outside a constructor, something the .NET VM doesn't like.

      In package scala.util.regexp there's the following:

      abstract class WordExp extends Base {
      
        abstract class Label
      
        type _regexpT <: RegExp
        type _labelT <: Label
      
        case class Letter(a: _labelT) extends RegExp {
          final lazy val isNullable = false
          var pos = -1
        }
      
        case class Wildcard() extends RegExp {
          final lazy val isNullable = false
          var pos = -1
        }
      }
      

      which gets transformed into:

      
      [[syntax trees at end of cleanup]]// Scala source: WordExp.scala
      package scala.util.regexp {
        abstract class WordExp extends scala.util.regexp.Base with ScalaObject {
          . . . 
          @serializable case class Wildcard extends scala.util.regexp.Base#RegExp with ScalaObject with Product {
      
            @volatile protected var bitmap$$0: Int = 0;
      
            final lazy private[this] var isNullable: Boolean = _; /*- it's a final field */
      
            final <stable> <accessor> lazy def isNullable(): Boolean = {
              if (Wildcard.this.bitmap$$0.&(1).==(0))
                {
                  Wildcard.this.synchronized({
                    if (Wildcard.this.bitmap$$0.&(1).==(0))
                      {
                        Wildcard.this.isNullable = false; /*- yet it's written outside a constructor. 
                                                              The CLR doesn't like this. */
                        Wildcard.this.bitmap$$0 = Wildcard.this.bitmap$$0.|(1);
                        ()
                      };
                    scala.runtime.BoxedUnit.UNIT
                  });
                  ()
                };
              Wildcard.this.isNullable
            };
          . . . 
      

      Is this a bug?

        Activity

        Hide
        Lukas Rytz added a comment -

        Given

        class C { final lazy val t = "abc" }
        

        the classfile marks the private field `t` as `final`, but the getter of `t` assigns to it.

        I'ts probably not a bug, i'll let Iuli decide.

        Show
        Lukas Rytz added a comment - Given class C { final lazy val t = "abc" } the classfile marks the private field `t` as `final`, but the getter of `t` assigns to it. I'ts probably not a bug, i'll let Iuli decide.
        Hide
        Hubert Plociniczak added a comment -

        I don't think this is a bug, rather a feature But I guess we could just reset the final flag for the variable and check if overriding will still throw an error (not sure if the check is done on the accessor or the variable).

        Show
        Hubert Plociniczak added a comment - I don't think this is a bug, rather a feature But I guess we could just reset the final flag for the variable and check if overriding will still throw an error (not sure if the check is done on the accessor or the variable).
        Hide
        Hubert Plociniczak added a comment -

        if you agree, Iulian, then I can handle it if you want.

        Show
        Hubert Plociniczak added a comment - if you agree, Iulian, then I can handle it if you want.

          People

          • Assignee:
            Hubert Plociniczak
            Reporter:
            Miguel Garcia
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development