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

GADT matching with variant type parameters is not supported #2985

Closed
Jacoby6000 opened this issue Aug 15, 2017 · 2 comments · Fixed by #5736
Closed

GADT matching with variant type parameters is not supported #2985

Jacoby6000 opened this issue Aug 15, 2017 · 2 comments · Fixed by #5736

Comments

@Jacoby6000
Copy link

Jacoby6000 commented Aug 15, 2017

This works fine if you make Expr invariant. It will not work with Covariance or Invariance. They both fail with the same error.

  trait Value

  sealed trait Expr[-I]
  case class Lit(i: Int) extends Expr[Value]

  def matchExpr[I](expr: Expr[I]): Expr[I] = 
    expr match {
      case Lit(i) => Lit(i)
    }

Error:

-- [E007] Type Mismatch Error: /tmp/scastie6519525892041936582/src/main/scala/main.scala:11:24 
11 |      case Lit(i) => Lit(i)
   |                     ^^^^^^
   |                     found:    Main.Lit
   |                     required: Main.Expr[I]
@Jacoby6000 Jacoby6000 changed the title GADTs with a covariant phantom type are not properly constructed GADTs with a co(ntra)variant phantom type are not properly constructed Aug 15, 2017
@Jacoby6000 Jacoby6000 changed the title GADTs with a co(ntra)variant phantom type are not properly constructed GADTs with a co(ntra)variant phantom type are not properly constructed in a pattern match Aug 15, 2017
@smarter
Copy link
Member

smarter commented Aug 15, 2017

Our current implementation of GADTs is limited to invariant type parameters, which is hopefully a limitation we can lift (though this has to be done carefully to avoid issues like in section 3 of http://lampwww.epfl.ch/%7Ehmiller/scala2013/resources/pdfs/paper5.pdf), from Typer.scala:

    /** gadtSyms = "all type parameters of enclosing methods that appear
     *              non-variantly in the selector type" todo: should typevars
     *              which appear with variances +1 and -1 (in different
     *              places) be considered as well?
     */
    val gadtSyms: Set[Symbol] = ctx.traceIndented(i"GADT syms of $selType", gadts) {
      val accu = new TypeAccumulator[Set[Symbol]] {
        def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
          val tsyms1 = t match {
            case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
              tsyms + tr.symbol
            case _ =>
              tsyms
          }
          foldOver(tsyms1, t)
        }
      }
      accu(Set.empty, selType)
    }

@smarter smarter changed the title GADTs with a co(ntra)variant phantom type are not properly constructed in a pattern match GADT matching with variant type parameters is not supported Aug 15, 2017
@abgruszecki
Copy link
Contributor

Fixed in PR mentioned above.

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.

3 participants