Skip to content

Adding a useless assignment statement alters program behavior. #21649

Closed
@jrlemieux

Description

@jrlemieux

Compiler version

3.5.0, 3.5.1

Minimized code

This is a follow-up on an issue reported by Tomassino on the Scala users.scala-lang.org forum.

I created this small demo Github project to showcase this issue: https://github.com/jrlemieux/scala-weird

The two classes Test1 and Test2 inherit common code that is calling their virtual partial function outerPf_2.

The only difference between the two classes is the commenting of the useless statement "val something = p".

class Test1() extends TestTrait:

  val outerPf_2: PartialFunction[Any, Any] = p =>
    val something = p
    innerPf(p) match
      case Some(_) => println("Something")

class Test2() extends TestTrait:

  val outerPf_2: PartialFunction[Any, Any] = p =>
    // val something = p
    innerPf(p) match
      case Some(_) => println("Something")

Expectation

It was expected that Test1.outerPf_2 would behave exactly as Test2.outerPf_2, but it doesn't.

The compiler generates very different code for the isDefinedAt method of the outerPf_2 partial functions.

For Test1:

  public final boolean isDefinedAt(java.lang.Object);
    Code:
       0: aload_1
       1: astore_2
       2: iconst_1
       3: ireturn

For Test2:

  public final boolean isDefinedAt(java.lang.Object);
    Code:
       0: aload_0
       1: getfield      #24                 // Field $outer:Lcom/playzone/some-common-name;
       4: invokevirtual #33                 // Method com/playzone/some-common-name.innerPf:()Lscala/PartialFunction;
       7: aload_1
       8: invokeinterface #39,  2           // InterfaceMethod scala/PartialFunction.apply:(Ljava/lang/Object;)Ljava/lang/Object;
      13: checkcast     #41                 // class scala/Option
      16: astore_2
      17: aload_2
      18: instanceof    #43                 // class scala/Some
      21: ifeq          26
      24: iconst_1
      25: ireturn
      26: iconst_0
      27: ireturn

The difference might be due to the fact that one PF is inlining code. But whether the compiler optimizes with inlining or not should not affect the behavior of the code. Adding an extra useless assignment statement should not affect the code's behavior.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions