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

Reset GADT constraint on failing isSubType #11988

Closed
wants to merge 3 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 5, 2021

The normal constraint gets reset when isSubType fails - should the GADT constraint
not get reset as well? Subtyping is an exploration with backtracking where
some branches do not lead to a result. It seems unsound that failing explorations
can nevertheless introduce new GADT bounds.

I tried to change this in this commit, but it makes the following tests
fail with stack overflows:

tests/pos/i9740b.scala failed
tests/pos/i9740c.scala failed

I must admit I am not quite sure about whether it is enough to reset just the constraint
part of a GadtConstraint, or whether the whole constraint has to be copied. I hope not the
latter, since that would impose a heavy complexity price on subtype checking.

odersky added 3 commits April 4, 2021 22:29
 - keep the singleton type in the cast target
 - assert cast target stability if original was stable
 - fix isStable test for TypeParamRefs
 - double check if GADT logic is really needed before inserting a cast

Fixes scala#11220
Fixes scala#11955
The normal constraint gets reset when isSubType fails - should the GADT constraint
not get reset as well? Subtyping is an exploration with backtracking where
some branches do not lead to a result. It seems unsound that failing explorations
can nevertheless introduce new GADT bounds.

I tried to change this in this commit, but it makes the following tests
fail with stack overflows:

    tests/pos/i9740b.scala failed
    tests/pos/i9740c.scala failed

I must admit I am not quite sure about whether it is enough to reset just the constraint
part of a GadtConstraint, or whether the whole constraint has to be copied. I hope not the
latter, since that would impose a heavy complexity price on subtype checking.
@odersky odersky marked this pull request as draft April 5, 2021 08:50
@odersky
Copy link
Contributor Author

odersky commented Apr 5, 2021

@abgruszecki Can you comment and if necessary continue with this PR?

@odersky
Copy link
Contributor Author

odersky commented Apr 5, 2021

I think the understanding of GADT handling could be improved by aligning terminology. A GADTConstraint is really more like a ConstraintHandler than a Constraint since Constraints are immutable. The mutability of GADTConstraints seems to have some negative consequences when it comes to backup and restore. Can we make GADTConstraints immutable as well?

@abgruszecki
Copy link
Contributor

tests/pos/i9740b.scala fails with strange errors, but it seems that the errors themselves aren't incorrect:

-- [E007] Type Mismatch Error: tests/pos/i9740b.scala:10:9 -------------------------------------------
10 |    case UnitExp =>
   |         ^^^^^^^
   |         Found:    UnitExp.type
   |         Required: Exp[A]
   |
   |         where:    A is a type in method bar with bounds <: T
   |
   |         pattern type is incompatible with expected type

With this change, we now detect that the pattern is incompatible with the scrutinee, since it requires that Unit <: A <: T <: U <: Int, which cannot be the case.

tests/pos/i9740c.scala, OTOH, does fail with stack overflow errors. I'll have to take a closer look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants