scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

polymorphic expression cannot be instantiated to expected type when using Id[A] type alias #12885

Open ingemaradahl opened 8 months ago

ingemaradahl commented 8 months ago

Reproduction steps

Scala version: 2.13.11, 2.13.12 Works in: 3.3.1

type Id[A] = A

trait Extract[T, F[_]] {
  def apply(json: AnyRef): F[T]
}

object Extract {
  implicit val extractString: Extract[String, Id] =
    (json: AnyRef) => "baz"
}

final class PartiallyAppliedExtract[T](val entity: Entity) extends AnyVal {
  def apply[F[_]](key: String)(implicit extract: Extract[T, F]): F[T] =
    extract(null)
}

trait Entity {
  final def extract[T]: PartiallyAppliedExtract[T] =
    new PartiallyAppliedExtract(this)
}

val e: Entity = new Entity {}

printf(e.extract[String]("foo"))

Scastie

Problem

The type constructor used for the return type is inferred by the implicit chosen by the compiler, meaning we can use different effects based on the return type. When using the type Id[A] = A type alias (to indicate that there is no effect), the compiler seems to "forget" the type constructor used, and cannot infer that Id[String] is the same as String.

In the example above, adding an implicit conversion Id[A] => A allows the snippet above to compile, however with one warning: the implicit conversion is unused. But the fact that the code compiles with the implicit conversion in scope hints that the compiler in fact knows that the type constructor is Id[_], and uses the implicit conversion.

Scastie using Scala 2.13.12 Scastie using Scala 3.3.1