-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Check bounds in match type case bodies #17602
Conversation
84365e8
to
a1eb832
Compare
00957b5
to
23e00c3
Compare
1a849d6
to
6642d65
Compare
75e7c41
to
538a8bd
Compare
@sjrd will you review if I rebase this? 😄 |
Oh yes, sorry. |
b97343a
to
76c8268
Compare
@@ -21,6 +21,7 @@ object TypeEval: | |||
case tp: TypeProxy => | |||
val tp1 = tp.superType | |||
if tp1.isStable then tp1.fixForEvaluation else tp | |||
case AndType(tp1: ConstantType, tp2) if tp1.frozen_<:<(tp2) => tp1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AndType
is supposed to be commutative, so if we do this we must also do the mirror:
case AndType(tp1: ConstantType, tp2) if tp1.frozen_<:<(tp2) => tp1 | |
case AndType(tp1: ConstantType, tp2) if tp1.frozen_<:<(tp2) => tp1 | |
case AndType(tp1, tp2: ConstantType) if tp2.frozen_<:<(tp1) => tp2 |
withMode(Mode.Pattern)(super.transform(x)).asInstanceOf[CaseDef] | ||
def transformCase(x: CaseDef): CaseDef = | ||
val gadtCtx = x.pat.removeAttachment(typer.Typer.InferredGadtConstraints) match | ||
case Some(gadt) => ctx.fresh.setGadtState(GadtState(gadt)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this enough to ensure that, after PostTyper
, the trees are well-kinded without resorting to GADT reasoning? I'm not familiar with what are the consequences of doing setGadtState
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not inserting any casts, if that's what you're asking. And I'm hoping we can handle things like:
class Foo
class Bar
class Res[X <: Bar]
type MT[X <: Foo | Bar] = X match
case Foo => Unit
case Bar => Res[X] // X vs bounds check <: Bar
in part also because I've found adding a type intersection (for types) doesn't fix errors like adding a type casting (for terms) fixes errors...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we can either:
- disallow such reasoning, force users to insert type intersections, and then decide how much to work on the limitations of those intersections
- allow these things to require GADT reasoning
- deal with how to force types to honour bounds, and perhaps in a way that is accessible to users too
- return to the AssumeInfo tree idea
😭
Fixes #13741