question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CollectionConverters conversion between java.lang.Long and scala.Long

See original GitHub issue

Compiler version

Scala compiler version 3.2.1 – Copyright 2002-2022, LAMP/EPFL

Minimized code

create java file in ./test/L.java

package test;

import java.util.Map;

public class L {

    public static Long y() {
        return 123L;
    }

    public static Map<String, Long> maps() {
        return Map.of("A", 1L);
    }
}

create following scala file in ./Call.scala

import test._

class Call {

  def x(): Long = L.y()

  import scala.jdk.CollectionConverters._

//  def mmap(): Map[String, Long] = L.maps().asScala.toMap
  def maps(): Map[String, Long] = L.maps().asScala.toMap.collect { case (k, v) if v > 0L => (k, v)}

}

Run the following:

javac -d classes test/L.java
scalac -classpath ./classes Call.scala

Output

-- [E007] Type Mismatch Error: Call.scala:9:65 ---------------------------------
9 |  def maps(): Map[String, Long] = L.maps().asScala.toMap.collect { case (k, v) if v > 0L => (k, v)}
  |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                Found:    PartialFunction[(String, Long), (String, Long)]
  |                Required: PartialFunction[(String, Long), (String, Long²)]
  |
  |                where:    Long  is a class in package java.lang
  |                          Long² is a class in package scala
  |
  | longer explanation available when compiling with `-explain`
2 errors found

Expectation

Scala compiler can convert java.lang.Long to scala.Long, just as the case with the single statement in the example file.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
lrytzcommented, Nov 24, 2022

Ah, thanks. Yes, that example compiles with 2.13.10, and compilation fails with 3.2.1.

-- [E007] Type Mismatch Error: A.scala:9:65 ------------------------------------
9 |  def maps(): Map[String, Long] = L.maps().asScala.toMap.collect { case (k, v) if v > 0L => (k, v)}
  |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                Found:    PartialFunction[(String, Long), (String, Long)]
  |                Required: PartialFunction[(String, Long), (String, Long²)]
  |
  |                where:    Long  is a class in package java.lang
  |                          Long² is a class in package scala
0reactions
DieBauercommented, Nov 29, 2022

I diffed the output after the typer phase for both scala 2 and 3, and in scala 2 the value type (java Long) gets an implicit conversion applied scala.Tuple2.apply[String, Long](k, scala.Predef.Long2long(v)). While in Scala 3 that doesn’t happen Tuple2.apply[String, Long](k, v), even though the guard on the value 0L does get the conversion applied.

Scala 3 output

package <empty> {
  class B() extends Object() {
    import scala.jdk.CollectionConverters.*
    def maps(): Map[String, Long] = 
      jdk.CollectionConverters.MapHasAsScala[String, Long](L.maps()).asScala.
        toMap
      [String, Long](<:<.refl[(String, Long)]).collect[String, Long](
        {
          def $anonfun(x$1: (String, Long)): (String, Long) = 
            x$1:(x$1 : (String, Long)) @unchecked match 
              {
                case Tuple2.unapply[String, Long](k @ _, v @ _) if 
                  Long2long(v).>(0L)
                 => 
                  Tuple2.apply[String, Long](k, v)
              }
          closure($anonfun:PartialFunction[(String, Long), (String, Long)])
        }
      )
  }
}

Scala 2 output

package <empty> {
  class B extends scala.AnyRef {
    def <init>(): B = {
      B.super.<init>();
      ()
    };
    import scala.jdk.CollectionConverters._;
    def maps(): Map[String,Long] = scala.jdk.CollectionConverters.MapHasAsScala[String, Long](L.maps()).asScala.toMap[String, Long](scala.this.<:<.refl[(String, Long)]).collect[String, Long](({
      @SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[(String, Long),(String, Long)] with java.io.Serializable {
        def <init>(): <$anon: ((String, Long)) => (String, Long)> = {
          $anonfun.super.<init>();
          ()
        };
        final override def applyOrElse[A1 <: (String, Long), B1 >: (String, Long)](x1: A1, default: A1 => B1): B1 = ((x1.asInstanceOf[(String, Long)]: (String, Long)): (String, Long) @unchecked) match {
          case (_1: String, _2: Long): (String, Long)((k @ _), (v @ _)) if scala.Predef.Long2long(v).>(0L) => scala.Tuple2.apply[String, Long](k, scala.Predef.Long2long(v))
          case (defaultCase$ @ _) => default.apply(x1)
        };
        final def isDefinedAt(x1: (String, Long)): Boolean = ((x1.asInstanceOf[(String, Long)]: (String, Long)): (String, Long) @unchecked) match {
          case (_1: String, _2: Long): (String, Long)((k @ _), (v @ _)) if scala.Predef.Long2long(v).>(0L) => true
          case (defaultCase$ @ _) => false
        }
      };
      new $anonfun()
    }: PartialFunction[(String, Long),(String, Long)]))
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Conversions Between Java and Scala Collections
It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the JavaConverters object.
Read more >
Implicit conversion between Scala.Long and Java.lang.Long ...
Scala has implicit conversions between scala.Long and java.lang.Long , but they won't convert collections of those types.
Read more >
Converting Java Collections to Scala Collections - Baeldung
A quick and practical guide to convenient Java/Scala collections conversions.
Read more >
CollectionConverters - Scala 3 - EPFL
This object provides extension methods that convert between Scala and Java collections. When writing Java code, use the explicit conversion methods defined ...
Read more >
How to go to and from Java collections in Scala
CollectionConverters object to convert from Scala collections classes to Java collections classes. While those classes/objects have changed, the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found