Skip to content
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

Type inference fails with SAM and wildcard subtyping, works in 2.13 #18096

Closed
bishabosha opened this issue Jun 29, 2023 · 6 comments · Fixed by #18201
Closed

Type inference fails with SAM and wildcard subtyping, works in 2.13 #18096

bishabosha opened this issue Jun 29, 2023 · 6 comments · Fixed by #18201

Comments

@bishabosha
Copy link
Member

bishabosha commented Jun 29, 2023

see original forum post reported by @mdedetrich

Compiler version

3.3.0

Minimized code

package pekko

// package org.apache.pekko.japi.function
@FunctionalInterface
trait Function[-T, +R] extends java.io.Serializable {
  @throws(classOf[Exception])
  def apply(param: T): R
}

// package org.apache.pekko.javadsl
final class Source[Out, Mat]() {
  def mapConcat[T](f: pekko.Function[Out, _ <: java.lang.Iterable[T]]): Source[T, Mat] =
    ???
}

// package com.google.pubsub.v1
final class ReceivedMessage

// package com.google.pubsub.v1
final class StreamingPullResponse {
  def getReceivedMessagesList: java.util.List[ReceivedMessage] = ???
}

// package example
class Materialised

// package example
object Test {
  val streamingPullResult: Source[StreamingPullResponse, Materialised] = ???

  def test =
    streamingPullResult
      .mapConcat(((response: StreamingPullResponse) => response.getReceivedMessagesList))
}

Output

Compiling project (Scala 3.3.0, JVM)
[error] ./foo.scala:37:21
[error] Found:    pekko.StreamingPullResponse => java.util.List[pekko.ReceivedMessage]
[error] Required: pekko.Function[pekko.StreamingPullResponse, ? <: Iterable[T]]
[error] 
[error] where:    T is a type variable
[error]         .mapConcat(((response: StreamingPullResponse) => response.getReceivedMessagesList))
[error]                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

adding the explicit type pekko.Function[StreamingPullResponse, java.util.List[pekko.ReceivedMessage]] fixes the error,

also inference works if the signature of mapConcat changes to

def mapConcat[F[X] <: java.lang.Iterable[X], T](f: pekko.Function[Out, F[T]]): Source[T, Mat]

Expectation

it should compile, like it did in scala 2.13.10

@bishabosha bishabosha added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 29, 2023
@bishabosha bishabosha changed the title Type inference fails with SAM, works in 2.13 Type inference fails with SAM and wildcard subtyping, works in 2.13 Jun 29, 2023
@bishabosha bishabosha added area:typer and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 29, 2023
@bishabosha
Copy link
Member Author

@smarter asking your opinion here

@mdedetrich
Copy link

compiling with scala 2.13.10 works

Shouldn't this be compiling with scala 3 works?

@He-Pin
Copy link

He-Pin commented Jun 29, 2023

@mdedetrich or as compiling with scala 2.13.10 works

@bishabosha
Copy link
Member Author

I updated the expectation, sorry for the confusion

@dwijnand
Copy link
Member

dwijnand commented Jun 29, 2023

Minimised further

trait F1[-T1, +R] extends AnyRef { def apply(v1: T1): R }
class R { def l: List[Any] = Nil }
class S { def m[T](f: F1[R, ? <: List[T]]): S = this }
class T1 { def t1(s: S) = s.m((r: R) => r.l) }

@smarter
Copy link
Member

smarter commented Jun 30, 2023

I'm working on a fix for #16065 that also fixes this issue.

smarter added a commit to dotty-staging/dotty that referenced this issue Jul 13, 2023
When typing a closure with an expected type containing a wildcard, the closure
type itself should not contain wildcards, because it might be expanded to an
anonymous class extending the closure type (this happens on non-JVM backends as
well as on the JVM itself in situations where a SAM trait does not compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by the
SAMType extractor, but to fix this issue we had to change the extractor to
perform the approximation on the expected type itself to generate a valid
parent type. The SAMType extractor now returns both the approximated parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque type
extracted from Inferencing#variances.

Fixes scala#16065.
Fixes scala#18096.
smarter added a commit to dotty-staging/dotty that referenced this issue Jul 13, 2023
When typing a closure with an expected type containing a wildcard, the closure
type itself should not contain wildcards, because it might be expanded to an
anonymous class extending the closure type (this happens on non-JVM backends as
well as on the JVM itself in situations where a SAM trait does not compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by the
SAMType extractor, but to fix this issue we had to change the extractor to
perform the approximation on the expected type itself to generate a valid
parent type. The SAMType extractor now returns both the approximated parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque type
extracted from Inferencing#variances.

Fixes scala#16065.
Fixes scala#18096.
smarter added a commit to dotty-staging/dotty that referenced this issue Jul 14, 2023
When typing a closure with an expected type containing a wildcard, the closure
type itself should not contain wildcards, because it might be expanded to an
anonymous class extending the closure type (this happens on non-JVM backends as
well as on the JVM itself in situations where a SAM trait does not compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by the
SAMType extractor, but to fix this issue we had to change the extractor to
perform the approximation on the expected type itself to generate a valid
parent type. The SAMType extractor now returns both the approximated parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque type
extracted from Inferencing#variances.

Fixes scala#16065.
Fixes scala#18096.
smarter added a commit to dotty-staging/dotty that referenced this issue Jul 15, 2023
When typing a closure with an expected type containing a wildcard, the closure
type itself should not contain wildcards, because it might be expanded to an
anonymous class extending the closure type (this happens on non-JVM backends as
well as on the JVM itself in situations where a SAM trait does not compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by the
SAMType extractor, but to fix this issue we had to change the extractor to
perform the approximation on the expected type itself to generate a valid
parent type. The SAMType extractor now returns both the approximated parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque type
extracted from Inferencing#variances.

Fixes scala#16065.
Fixes scala#18096.
smarter added a commit that referenced this issue Jul 15, 2023
When typing a closure with an expected type containing a wildcard, the
closure
type itself should not contain wildcards, because it might be expanded
to an
anonymous class extending the closure type (this happens on non-JVM
backends as
well as on the JVM itself in situations where a SAM trait does not
compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by
the
SAMType extractor, but to fix this issue we had to change the extractor
to
perform the approximation on the expected type itself to generate a
valid
parent type. The SAMType extractor now returns both the approximated
parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque
type
extracted from Inferencing#variances.

Fixes #16065.
Fixes #18096.
@Kordyjan Kordyjan added this to the 3.4.0 milestone Aug 1, 2023
Kordyjan pushed a commit that referenced this issue Nov 30, 2023
[Cherry-picked 89735d0][modified]

When typing a closure with an expected type containing a wildcard, the closure
type itself should not contain wildcards, because it might be expanded to an
anonymous class extending the closure type (this happens on non-JVM backends as
well as on the JVM itself in situations where a SAM trait does not compile down
to a SAM interface).

We were already approximating wildcards in the method type returned by the
SAMType extractor, but to fix this issue we had to change the extractor to
perform the approximation on the expected type itself to generate a valid
parent type. The SAMType extractor now returns both the approximated parent
type and the type of the method itself.

The wildcard approximation analysis relies on a new `VarianceMap` opaque type
extracted from Inferencing#variances.

Fixes #16065.
Fixes #18096.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants