-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restrict captureWildcards to only be used if needed (#16799)
Rather than blindly using the newly wildcard-captured type, check that it's compatible with the proto/formal type. That way values that have wildcard types can be passed, uncast, to extension methods that don't require the capture. For instance in specs2, a value of type `Class[? <: Foo]` needn't become `Class[?1.CAP]` just so it can be applied to `def theValue[T](t: => T)`. For the zio-http case, despite knowing that JFuture is morally covariant, we don't have any way to knowing that - so we must be safe and error.
- Loading branch information
Showing
5 changed files
with
46 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Minimisation of how the fix for t9419 affected zio-http | ||
import java.util.concurrent.Future as JFuture | ||
|
||
trait Test: | ||
def shutdownGracefully(): JFuture[_] | ||
|
||
def executedWildcard(jFuture: => JFuture[_]): Unit | ||
def executedGeneric[A](jFuture: => JFuture[A]): Unit | ||
def executedWildGen[A](jFuture: => JFuture[? <: A]): Unit | ||
|
||
// Even though JFuture is morally covariant, at least currently, | ||
// there's no definition-side variance, so it's treated as invariant. | ||
// So we have to be concerned that two different values of `JFuture[A]` | ||
// with different types, blowing up together. So error in `fails`. | ||
def works = executedWildcard(shutdownGracefully()) | ||
def fails = executedGeneric(shutdownGracefully()) // error | ||
def fixed = executedGeneric(shutdownGracefully().asInstanceOf[JFuture[Any]]) // fix | ||
def best2 = executedWildGen(shutdownGracefully()) // even better, use use-site variance in the method |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Minimisation of how the fix for t9419 affected specs2 | ||
class MustExpectable[T](tm: () => T): | ||
def must_==(other: => Any) = tm() == other | ||
|
||
class Foo | ||
|
||
object Main: | ||
implicit def theValue[T](t: => T): MustExpectable[T] = new MustExpectable(() => t) | ||
def main(args: Array[String]): Unit = | ||
val cls = classOf[Foo] | ||
val instance = new Foo() | ||
val works = cls must_== cls | ||
val fails = instance.getClass must_== cls |