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

mixin transforms lazy vals incorrectly under specialization: crash

    Details

      Description

      trait Bug1[@specialized +A] extends TraversableOnce[A] {  
        def ++[B >: A](that: TraversableOnce[B]): Iterator[B] = new Iterator[B] {
          lazy val it = that.toIterator
          def hasNext = it.hasNext
          def next = it.next
        }
      }
      

      [running phase cleanup on bug1.scala]
      [running phase icode on bug1.scala]
      error: java.lang.Error: Unknown type: [<deferred> <param> T0 >: ? <: ?]()T0, [<deferred> <param> T0 >: ? <: ?]()T0 [class scala.reflect.internal.Types$PolyType, class scala.reflect.internal.Types$PolyType] TypeRef? false
      at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:31)
      at scala.tools.nsc.backend.icode.TypeKinds$class.toTypeKind(TypeKinds.scala:390)

      Analysis points the finger at mixin.

      // before mixin - asInstanceOf[Iterator]
      private <stable> <accessor> lazy def it(): Iterator = {
        Bug1$mcD$sp$$anon$10.this.it _=(Bug1$mcD$sp$$anon$10.this.that$10.toIterator());
        Bug1$mcD$sp$$anon$10.this.it .$asInstanceOf[Iterator]()
      };
      
      // after mixin - asInstanceOf is unapplied, polytype reaches back end
      private lazy var it : Iterator = _;
      private <stable> <accessor> lazy def it(): Iterator = {
        if (Bug1$mcD$sp$$anon$10.this.bitmap$priv$0.&(4).==(0))
          {
            Bug1$mcD$sp$$anon$10.this.synchronized({
              if (Bug1$mcD$sp$$anon$10.this.bitmap$priv$0.&(4).==(0))
                {
                  Bug1$mcD$sp$$anon$10.this.it _=(Bug1$mcD$sp$$anon$10.this.that$10.toIterator());
                  Bug1$mcD$sp$$anon$10.this.bitmap$priv$0 = Bug1$mcD$sp$$anon$10.this.bitmap$priv$0.|(4);
                  ()
                };
              scala.runtime.BoxedUnit.UNIT
            });
            Bug1$mcD$sp$$anon$10.this.that$10 = null
          };
        Bug1$mcD$sp$$anon$10.this.$asInstanceOf
      };
      

        Activity

        Hide
        Paul Phillips added a comment -

        Closed SI-4123 as a duplicate. Here's retronym's even more minimized case from that.

        trait Bounds[@specialized A] {
          // okay without `>: A`
          def x[B >: A]: Unit = new Bounds[B] {
            lazy val it = ???  // def or val okay
            it
          }
        }
        
        Show
        Paul Phillips added a comment - Closed SI-4123 as a duplicate. Here's retronym's even more minimized case from that. trait Bounds[@specialized A] { // okay without `>: A` def x[B >: A]: Unit = new Bounds[B] { lazy val it = ??? // def or val okay it } }
        Hide
        Aleksandar Prokopec added a comment - - edited

        I'm getting:

        error: scala.reflect.internal.Types$TypeError: value it  is not a member of Bounds[B]{}
        

        For some reason the `typedThis` in the typechecker:

              def typedThis(qual: Name) = tree.symbol orElse qualifyingClass(tree, qual, packageOK = false) match {
                case NoSymbol => tree
                case clazz    =>
                  log("typedThis: " + qual)
                  tree setSymbol clazz setType clazz.thisType.underlying
                  if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree
              }
        

        does not add `lazy val it` to the list of members. I'm trying to figure this out.

        Show
        Aleksandar Prokopec added a comment - - edited I'm getting: error: scala.reflect.internal.Types$TypeError: value it is not a member of Bounds[B]{} For some reason the `typedThis` in the typechecker: def typedThis(qual: Name) = tree.symbol orElse qualifyingClass(tree, qual, packageOK = false) match { case NoSymbol => tree case clazz => log("typedThis: " + qual) tree setSymbol clazz setType clazz.thisType.underlying if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree } does not add `lazy val it` to the list of members. I'm trying to figure this out.
        Hide
        Aleksandar Prokopec added a comment -

        I think the `lazy val` gets assigned the wrong owner in the `invalidate` method in `Duplicators`.

        Show
        Aleksandar Prokopec added a comment - I think the `lazy val` gets assigned the wrong owner in the `invalidate` method in `Duplicators`.
        Hide
        Aleksandar Prokopec added a comment -
        Show
        Aleksandar Prokopec added a comment - Should be fixed here: https://github.com/scala/scala/pull/576

          People

          • Assignee:
            Aleksandar Prokopec
            Reporter:
            Paul Phillips
          • Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development