Content-Length: 263310 | pFad | https://github.com/scala/scala3/issues/22304

85 Type computed to `Any`, expect `T` · Issue #22304 · scala/scala3 · GitHub
Skip to content

Type computed to Any, expect T #22304

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

Closed
He-Pin opened this issue Jan 3, 2025 · 2 comments
Closed

Type computed to Any, expect T #22304

He-Pin opened this issue Jan 3, 2025 · 2 comments

Comments

@He-Pin
Copy link
Contributor

He-Pin commented Jan 3, 2025

Compiler version

If you're not sure what version you're using, run print scalaVersion from sbt
(if you're running scalac manually, use scalac -version instead).

3.3.4 & 3.6.2

Minimized code

Works code 1:

import scala.util.Try
import scala.concurrent.Future
import scala.concurrent.Awaitable

object CompletedFuture {
  def unapply[T](f: Future[T]): Option[Try[T]] = f.value
}

def result[T](future: Awaitable[T]): T = future match {
  case CompletedFuture(result:Try[T] @unchecked) => result.get
  case _                       => ???
}

println(result(Future.successful(1)))

Works code 2:

import scala.util.Try
import scala.concurrent.Future
import scala.concurrent.Awaitable

object CompletedFuture {
  def unapply[T](f: Future[T]): Option[Try[T]] = f.value
}

def result[T](future: Awaitable[T]): T = future match {
  case CompletedFuture(result:Try[T] ) => result.get
  case _                       => ???
}

println(result(Future.successful(1)))

Works code 3:

import scala.util.Try
import scala.concurrent.Future
import scala.concurrent.Awaitable

object CompletedFuture {
  def unapply[T](f: Future[T]): Option[Try[T]] = f.value
}

def result[T](future: Future[T]): T = future match {
  case CompletedFuture(result) => result.get
  case _                       => ???
}

println(result(Future.successful(1)))

Bad code :

import scala.util.Try
import scala.concurrent.Future
import scala.concurrent.Awaitable

object CompletedFuture {
  def unapply[T](f: Future[T]): Option[Try[T]] = f.value
}

def result[T](future: Awaitable[T]): T = future match {
  case CompletedFuture(result) => result.get
  case _                       => ???
}

println(result(Future.successful(1)))

https://scastie.scala-lang.org/He-Pin/2UboOKGuRp2CXe5XS3ZCXQ/1

image

Output

Found:    Any
Required: T

Expectation

Works as 2.13.x

@He-Pin He-Pin added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 3, 2025
@Gedochao Gedochao added area:typer regression:scala2 and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jan 7, 2025
@Linyxus
Copy link
Contributor

Linyxus commented Feb 14, 2025

A minimisation:

trait Awaitable[+T]
trait Future[+T] extends Awaitable[T]

object CompletedFuture:
  def unapply[T](f: Future[T]): Option[T] = ???

def result1[T](future: Awaitable[T]): T = future match
  case CompletedFuture(result) => result  // error
  case _ => ???

@Linyxus
Copy link
Contributor

Linyxus commented Feb 14, 2025

This is actually the intended behavior. This is due to the "old paradox" of GADT in Scala. The question is: given a value future: Awaitable[T], if, via pattern-matching, we come to know that this value is also of type Future, then can we be sure that it is of type Future[T]?

Actually no. The crux of the problem is that both Future and Awaitable can be further extended. For instance:

object Unsound extends Future[Any] with Awaitable[Int]

It will be an Awaitable[Int], but it is unsound to assume that it is also of Future[Int]. In the previous example, it is sound to say what we get is a Future[Any].

If we made Future a final class, the code will compile:

trait Awaitable[+T]
final class Future[+T] extends Awaitable[T]

//object Unsound extends Future[Any] with Awaitable[Int]

object CompletedFuture:
  def unapply[T](f: Future[T]): Option[T] = ???

def result1[T](future: Awaitable[T]): T = future match
  case CompletedFuture(result) => result  // no error any more!
  case _ => ???

@Linyxus Linyxus closed this as not planned Won't fix, can't repro, duplicate, stale Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/scala/scala3/issues/22304

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy