Skip to content

Runtime regression from Scala 2: A non-closure lambda literal is no longer a constant value and is not equal to itself #19224

Closed
@neko-kai

Description

@neko-kai

Compiler version

3.3.1

Minimized code

object app extends App {
  def x(): Int => String = (i: Int) => i.toString

  locally {
    println(x() == x()) // true on Scala 2, false on Scala 3...
    println(x().hashCode -> x().hashCode) // same on Scala 2, different on Scala 3
  }
}

Output

% coursier launch scala:2.13.12 -- example.scala
true
(1240730624,1240730624)
% coursier launch scala:3.3.1 -- example.scala
false
(580212331,390994841)

Expectation

Expected repeated invocations of x() to produce the exact same lambda instance, as before in Scala 2 and currently in Java:

class app {
    static java.util.function.Function<Integer, String> x() {
        return ((Integer i) -> i.toString());
    }

    public static void main(String[] args) {
        System.out.println(x() == x());
        System.out.println(x().equals(x()));
        System.out.println(x().hashCode());
        System.out.println(x().hashCode());
    }
}

Outputs:

true
true
707610042
707610042

We rely on this property very heavily in https://github.com/7mind/izumi (since Java behaves the same way, we assumed this property couldn't be broken in the future)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions