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

lambdalift crashes when Block in constructor-argument position requires outer() access

    Details

      Description

      As discussed in https://groups.google.com/d/topic/scala-internals/Ief8xGFd6fU/discussion , currently lambdalift crashes on:

      class Foo(a: Any);
      
      class IP extends Foo({
         def poorMansMH1 = ""
         object X {
           poorMansMH1	
         }
       }
      )
      
      
      Uncaught exception during compilation: scala.reflect.internal.FatalError
      error: scala.reflect.internal.FatalError: 
           while compiling: sandbox/test.scala
              during phase: global=lambdalift, atPhase=constructors
      
      
      
      no-symbol does not have an owner
      at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
      at scala.tools.nsc.Global.abort(Global.scala:253)
      at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3195)
      at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:229)
      at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerValue(ExplicitOuter.scala:215)
      at scala.tools.nsc.transform.LambdaLift$LambdaLifter.memberRef(LambdaLift.scala:327)
      at scala.tools.nsc.transform.LambdaLift$LambdaLifter.postTransform(LambdaLift.scala:472)
      

      The motivation for this ticket is an alternative lowering for closures that is amenable to MethodHandles (both the real thing and so-called "Poor Man's Method Handles" , https://groups.google.com/d/topic/scala-internals/f7TektSb26s/discussion , ie the general rule is:

          /**  Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
           *
           *  {
           *    def hoistedMethodDef(x_1: T_1, ..., x_N: T_n): R = body
           *
           *    class $anon() extends AbstractFunctionN[T_1, .., T_N, R] with Serializable {
           *      def apply(x_1: T_1, ..., x_N: T_n): R = hoistedMethodDef(x_1, ..., x_N)
           *    }
           *
           *    new $anon()
           *  }
           *
           *  By 'hoisting' the closure-body out of the anon-closure-class, lambdalift and explicitouter
           *  are prompted to add formal-params to convey values captured from the lexical environment.
           *  This amounts to 'scalar replacement of aggregates' that cuts down on heap-hops over outer() methods.
           *  TODO In case the closure-body captures nothing, it need not be hoisted out of the closure.
           *
           */
      

      Thus the following (longer) example is representative of a use case around "Poor Man's Method Handles"

      PoorMansMHs.scala
      class Foo(val bar : () => String);
      
      class IP extends {
        val baz = "bar";
      } with Foo( {
        def poorMansMH1(): String = baz;
      
        @SerialVersionUID(0) final class anonfun extends scala.runtime.AbstractFunction0[String] with Serializable {
           def apply(): String = poorMansMH1()
        };
      
        new anonfun()
      }
        );
      
      object Test extends App{
        (new IP).bar();
      }
      

        Issue Links

          Activity

          Hide
          Jason Zaugg added a comment -

          I've managed to coral a few more {{VerifyErrror}}s-in-waiting.

          https://github.com/retronym/scala/compare/scala:2.10.x...retronym:ticket/6666-wip

          Along the way I've had to reopen SI-6259 (which was flagged, correctly, by the new checks.)

          SI-6997 is not yet prevented.

          Show
          Jason Zaugg added a comment - I've managed to coral a few more {{VerifyErrror}}s-in-waiting. https://github.com/retronym/scala/compare/scala:2.10.x...retronym:ticket/6666-wip Along the way I've had to reopen SI-6259 (which was flagged, correctly, by the new checks.) SI-6997 is not yet prevented.
          Show
          James Iry added a comment - https://github.com/scala/scala/pull/2086
          Hide
          James Iry added a comment -

          2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

          Show
          James Iry added a comment - 2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.
          Hide
          James Iry added a comment -

          2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.

          Show
          James Iry added a comment - 2.10.2 is about to be cut. Kicking down the road and un-assigning to foster work stealing.
          Hide
          Jason Zaugg added a comment -

          Closing after collateral damage from this ticket was cleaned up in https://github.com/scala/scala/pull/2884

          Show
          Jason Zaugg added a comment - Closing after collateral damage from this ticket was cleaned up in https://github.com/scala/scala/pull/2884

            People

            • Assignee:
              Jason Zaugg
              Reporter:
              Miguel Garcia
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development