Details

      Description

      Compiling

      trait Foo {
        @inline final def foo(x: Int): Unit = {
          println(x)
        }
      }
      class Bar {
        def bar(y: Foo): Unit = {
          y.foo(7)
        }
      }
      

      yields (with -Ydebug and -Ylog:inline)

      [log inliner] Treating CALL_METHOD test2.Foo.foo (dynamic)
      	receiver: trait Foo
      	icodes.available: true
      	concreteMethod.isEffectivelyFinal: true
      [log inliner] inline failed for test2.Foo.foo:
        pair.sameSymbols: false
        inc.numInlined < 2: true
        inc.hasCode: false
        isSafeToInline: false
        shouldInline: false
              
      test2.scala:12: warning: Could not inline required method foo because bytecode was unavailable.
          y.foo(7)
               ^
      [log inliner]  test2.Bar.bar blocks before inlining: 1 (4) after: 1 (4)
      [log inliner] Analyzing test2.Foo$class
      [log inliner] Not inlining into foo because it is marked @inline.
      [log inliner]  test2.Foo$class.foo blocks before inlining: 1 (7) after: 1 (7)
      

      Expected behavior would be inlining foo into bar. It all works if you change Foo to be a class instead of a trait.

      I did some digging around and apparently ICode reading does not resolve methods bodies in traits:

      scala> global.icodes.icode(global.definitions.getClass("scala.collection.immutable.MapLike"),true).methods.map(_.code)
      res0: List[global.icodes.global.icodes.Code] = List(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ICode 'companion', null, null, null, null, null, null, null, null, null, null, ...
      

      Furthermore, it looks like class file reading will never load a trait's impl class (which actually contains the method bodies):

      scala> global.definitions.getClass("scala.collection.immutable.MapLike")
      res2: global.Symbol = trait MapLike
       
      scala> res2.implClass
      res3: global.Symbol = <none>
      

      There's really no way to get at it:

      scala> global.definitions.getClass("scala.collection.immutable.MapLike$class")
      scala.reflect.internal.MissingRequirementError: class scala.collection.immutable.MapLike$class not found.
      	at scala.reflect.internal.Definitions$definitions$.getModuleOrClass(Definitions.scala:662)
      	at scala.reflect.internal.Definitions$definitions$.getClass(Definitions.scala:615)
      

      The reason is that ClassPath.scala explicitly excludes these class files (ending in $class.class):

      /** A useful name filter. */
      def isTraitImplementation(name: String) = name endsWith "$class.class"
      ...
      object DefaultJavaContext extends JavaContext {
        override def isValidName(name: String) = !isTraitImplementation(name)
      }
      

      I believe this is a bug on its own - commenting out isValidName fixes the implClass behavior but not the inlining issue altogether.

        Attachments

          Issue Links

            Activity

            Hide
            moors Adriaan Moors added a comment -

            It would be great if you could take the knowledge gained from this quest and push the current optimizer a little further down the right path.

            Show
            moors Adriaan Moors added a comment - It would be great if you could take the knowledge gained from this quest and push the current optimizer a little further down the right path.
            Hide
            moors Adriaan Moors added a comment -

            Un-assigning to foster work stealing, as announced in https://groups.google.com/forum/?fromgroups=#!topic/scala-internals/o8WG4plpNkw

            Show
            moors Adriaan Moors added a comment - Un-assigning to foster work stealing, as announced in https://groups.google.com/forum/?fromgroups=#!topic/scala-internals/o8WG4plpNkw
            Hide
            moors Adriaan Moors added a comment -

            Unassigning and rescheduling to M6 as previous deadline was missed.

            Show
            moors Adriaan Moors added a comment - Unassigning and rescheduling to M6 as previous deadline was missed.
            Hide
            malcolmgreaves Malcolm Greaves added a comment -

            Hi! I was just bitten by this bug in a Scala 2.11.7 program. I see that the last update to this ticket was over a year ago. Have any brave volunteers made a dent in this one yet?

            Show
            malcolmgreaves Malcolm Greaves added a comment - Hi! I was just bitten by this bug in a Scala 2.11.7 program. I see that the last update to this ticket was over a year ago. Have any brave volunteers made a dent in this one yet?
            Hide
            retronym Jason Zaugg added a comment -

            Yes!, Lukas Rytz has fixed this in the experimental backend ("-Ybackend:GenBCode -Yopt:l:classpath") in Scala 2.11.7. This backend will be on by default in Scala 2.12.

            See: https://github.com/scala/scala/pull/4312

            Show
            retronym Jason Zaugg added a comment - Yes!, Lukas Rytz has fixed this in the experimental backend ("-Ybackend:GenBCode -Yopt:l:classpath") in Scala 2.11.7. This backend will be on by default in Scala 2.12. See: https://github.com/scala/scala/pull/4312

              People

              • Assignee:
                rytz Lukas Rytz
                Reporter:
                rompf Tiark Rompf
              • Votes:
                9 Vote for this issue
                Watchers:
                19 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: