Skip to content

macro crushes invariant type variables to Nothing  #12343

Closed
@tpolecat

Description

@tpolecat

Skunk's sql interpolator has a bug in which I am unable to abstract over interpolated Encoder[A]s because the type arguments are crushed to Nothing. I have minimized it in the following dumb but small macros.

Compiler version

3.0.0-RC3

Minimized code

Here is a pair of transparent macros. One takes any expression, and if it's a Set it returns it, annotated with its own type. The other does the same, but with List.

package test

import scala.quoted._

object Test {

  // Invariant (Set)

  def inv(arg: Expr[Any])(using Quotes): Expr[Any] =
    arg match {
      case '{ $h : Set[h] } => '{ $h : Set[h] }
    }

  transparent inline def inv(inline arg: Any): Any =
    ${ inv('arg) }

  // Covariant (List)

  def cov(arg: Expr[Any])(using Quotes): Expr[Any] =
    arg match {
      case '{ $h : List[h] } => '{ $h : List[h] }
    }

  transparent inline def cov(inline arg: Any): Any =
    ${ cov('arg) }

}

Here are some examples. In both cases calling the macros with concrete types works correctly; the passed expression is inlined with the correct type annotation. But in the case where the type argument is a type variable the covariant case works (the type is List[A]) but in the invariant case the type is Set[Nothing] rather than Set[A].

package test

val inv1: Set[Boolean] = Test.inv(Set(true))
def inv2[A](a: Set[A]): Set[A] = Test.inv(a) // doesn't compile; Set[Nothing] is inferred

val cov1: List[Boolean] = Test.cov(List(true))
def cov2[A](a: List[A]): List[A] = Test.cov(a)

Expectation

My expectation is that this mechanism shouldn't be sensitive to variance.

Notes

The annotated type is important in the code I generate. If I simplify the returned expressions above to simply h then the examples work, but I can't do this in the actual macro because it causes inference failures downstream.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions