Skip to content

Unsoundness due to GADT bounds being inferred too optimistically #5667

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
abgruszecki opened this issue Jan 2, 2019 · 2 comments · Fixed by #5736
Closed

Unsoundness due to GADT bounds being inferred too optimistically #5667

abgruszecki opened this issue Jan 2, 2019 · 2 comments · Fixed by #5736
Assignees

Comments

@abgruszecki
Copy link
Contributor

abgruszecki commented Jan 2, 2019

object Test {
  enum Base {
    case Case1
    case Case2
  }

  enum Invariant[T] {
    case Inv(t: T)
  }

  def unsound[T](t: T): T = Inv(t) match {
    case Inv(_: Base) =>
      // here we still shouldn't know anything about T
      Case1 // but instead, we have a bound T === Base, which is bogus 
  }

  val notCase2: Case2.type = unsound(Case2) // == Case1
}

There are probably many variations on the above - for example, T could be used in another function argument as well.

The issue appears to be caused by Dotty inferring GADT bounds based on pattern types - it decides that:

  • T in Invariant[T] is GADT-valid
  • type of Inv(_: Base) pattern is Invariant[Base]
    and then based on an Invariant[T] <: Inv[Base] check it infers that T === Base.

A possible fix might be to assign better types to patterns - Inv(_: Base) can match values of Inv[T] type, not Inv[Base].

Another avenue might be noticing that from the pattern matching we should know only that:

  • $scrutinee.type <: Inv[T]
  • $scrutinee.t.type <: Base
@Blaisorblade
Copy link
Contributor

$scrutinee.t.type <: Int

Whence Int? Typo for what?

@abgruszecki
Copy link
Contributor Author

Right, it was supposed to be Base. For clarity, there are two nested patterns - Inv(_), and _: Base - one matches on $scrutinee and the other on $scrutinee.t.

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.

2 participants