Skip to content

Inlining an extension method produces bad bytecode #15585

Open
@strelec

Description

@strelec

Compiler version

3.1.3

Minimized code

Simple code, with a simple isEven function, that is also inline.

opaque type Number = Int

object Number {
	extension (n: Number) {
		inline def isEven = n % 2 == 0
	}
	def apply(n: Int): Number = n
}

// another file:
object Test {
	def f(a: Number, b: Number) = if (a.isEven && b.isEven) println("OK")
}

Output

Decompiling function f we get this:

    public void f(final int a, final int b) {
        final Test$package$ module$ = Test$package$.MODULE$;
        final int n$proxy1 = a;
        boolean b2 = false;
        Label_0052: {
            if (n$proxy1 % 2 == 0) {
                final Test$package$ module$2 = Test$package$.MODULE$;
                final int n$proxy2 = b;
                if (n$proxy2 % 2 == 0) {
                    b2 = true;
                    break Label_0052;
                }
            }
            b2 = false;
        }
        if (b2) {
            Predef$.MODULE$.println((Object)"OK");
        }
    }

Expectation

A more reasonable and efficient version would be this:

    public void f(final int a, final int b) {
        if (a % 2 == 0 && b % 2 == 0) {
            Predef$.MODULE$.println((Object)"OK");
        }
    }

I thought extension functions were static and trivially inlineable, same as in Kotlin.
As it stands right now, it is risky to make anything inline, as it might have the opposite effect on performance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions