Skip to content

Type inference involving wildcards and SAMs #9756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
scabug opened this issue Apr 15, 2016 · 5 comments
Open

Type inference involving wildcards and SAMs #9756

scabug opened this issue Apr 15, 2016 · 5 comments
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)
Milestone

Comments

@scabug
Copy link

scabug commented Apr 15, 2016

> console
[info] Starting scala interpreter...
Welcome to Scala 2.12.0-M4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.

scala> import java.util.stream.Collectors
import java.util.stream.Collectors

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> 1.to(10).asJava.stream().map(_ + 1).collect(Collectors.toList[Int])
<console>:26: error: type mismatch;
 found   : java.util.stream.Collector[Int,?0(in value res0),java.util.List[Int]] where type ?0(in value res0)
 required: java.util.stream.Collector[_ >: ?0(in value x$1), ?, ?]
Note: Int <: Any, but Java-defined trait Collector is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
       1.to(10).asJava.stream().map(_ + 1).collect(Collectors.toList[Int])
                                                                    ^
@scabug
Copy link
Author

scabug commented Apr 15, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9756?orig=1
Reporter: @hseeberger
Affected Versions: 2.12.0-M4

@scabug
Copy link
Author

scabug commented Apr 19, 2016

@SethTisue said:
Note that the problem is in the map call, the compiler never even reaches the collect at the end. And it isn't an Int vs Integer thing, the same thing happens with e.g. String.

One workaround is to explicitly annotate the return type in the call to map:

scala> 1.to(10).asJava.stream().map[Int](_ + 1).collect(Collectors.toList[Int])
res3: java.util.List[Int] = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
scala> Seq("foo").asJava.stream().map[String](_.reverse)
res4: java.util.stream.Stream[String] = java.util.stream.ReferencePipeline$3@69d2c460

But note that java.util.List[Int] isn't really a proper type since Java doesn't allow primitive types as type parameters. What type you might want instead depends on what you're doing.

A more generally applicable workaround here is to use scala-java8-compat (https://github.com/scala/scala-java8-compat), which exists exactly to improve interop in situations like this:

scala> import scala.compat.java8.StreamConverters._
scala> 1.to(10).seqStream.map(_ + 1).toScala[Vector]
res0: Vector[Int] = Vector(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

scala> import java.util.stream.Collectors
scala> 1.to(10).seqStream.map(_ + 1).boxed.collect(Collectors.toList())
res1: java.util.List[Integer] = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

and so on.

@scabug
Copy link
Author

scabug commented Apr 20, 2016

@szeiger said:
This looks like a bug with the SAM type inference. Compare:

scala> 1.to(10).asJava.stream().map(_ + 1)
res7: java.util.stream.Stream[?0] = java.util.stream.ReferencePipeline$3@2c991465

scala> 1.to(10).asJava.stream().map[Int](_ + 1)
res8: java.util.stream.Stream[Int] = java.util.stream.ReferencePipeline$3@f171912

Here's the signature of Stream.map:

<R> Stream<R> 	map(Function<? super T,? extends R> mapper)

It looks like the existential type from the call-site variance on R leaks out into the return type instead of being replaced by the inferred type R = Int.

@scabug
Copy link
Author

scabug commented Jun 28, 2016

@adriaanm said:
The problem is that without definition-site variance, it's not sound to replace ? extends R with R. We could try to be smarter in type inference and basically infer the variance of type parameters of java-defined types, so that we can extrapolate the bounded wildcard away to its bound, but that's pretty tricky. Let's experiment in the 2.12.x series, but I won't be able to fix this for 2.12.0

@scabug scabug added this to the 2.12.3 milestone Apr 7, 2017
@adriaanm adriaanm modified the milestones: Backlog, 2.12.3 Jun 26, 2017
@adriaanm adriaanm modified the milestones: Backlog, 2.13.0-RC1 Sep 28, 2018
@adriaanm adriaanm modified the milestones: 2.13.0-RC1, Backlog Jan 8, 2019
@smarter smarter added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Apr 5, 2019
aloknnikhil added a commit to aloknnikhil/kafka that referenced this issue Dec 3, 2020
aloknnikhil added a commit to confluentinc/kafka that referenced this issue Dec 10, 2020
…ager listener callback (#464)

* KC-1184: Consume metadata log and queue for BrokerMetadataListener

* Cleanup test

* Addressing comments

* Controller: Fix BrokerRegistration + BrokerHeartbeat RPC

* Workaround for Scala 2.12 SAM type-inference bug

scala/bug#9756

* Address comments + fix BrokerLifecycleManagerTest failure

* ControllerApis: Fix BrokerRegistrationResponse lease duration

* KC-1270: Make use of the MetaLogListener callback that supplies us with new leader info

- Integrate w/ the BrokerMetadataListener/MetadataCache for the broker
to be notified through RAFT
- Remove active controller ID from the heartbeat response

* WIP: KC-1270

* Revert "WIP: KC-1270"

This reverts commit 82fff44.

* KC-1270

* Fix post-merge compilation error w/ Scala 2.12

* KC-1270: Fix BrokerMetadataListenerTest

* Fix Broker Controller discovery w/ LocalLogManager

- Configure broker/controller to use a common `metadata.log.dir`
- Fix metadata checkpoints discovery to include the `metadata.log.dir`
- Minor fix in `BrokerToControllerChannelManager` to use the correct
controller for ManualMetadataUpdate in the NetworkClient

* KC-1270: Add a test

* Address review comments: Race condition in updating controller ID and
PartitionMetadata
@He-Pin
Copy link
Contributor

He-Pin commented Oct 5, 2022

When call java.util.concurrent.CompletionStage#handle in scala 2.12.16
[error] --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error] found : java.util.function.BiFunction[T,Throwable,Unit]
[error] required: java.util.function.BiFunction[_ >: T, Throwable, _ <: ?U]
[error] Note: T <: Any, but Java-defined trait BiFunction is invariant in type T.
[error] You may wish to investigate a wildcard type such as _ <: Any. (SLS 3.2.10)
[error] stage.handle((value: T, ex: Throwable) => {
[error] ^

Have to insert the Unit

          stage.handle[Unit]((value, ex) => {
            if (ex != null) {
              callback(scala.util.Failure[T](ex))
            } else {
              callback(scala.util.Success(value))
            }
          })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)
Projects
None yet
Development

No branches or pull requests

4 participants