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

Decrement depth in subtype check withTypeVars #7291

Merged
merged 1 commit into from Dec 19, 2018

Conversation

joroKr21
Copy link
Member

Fixes scala/bug#7612

The LUB becomes Kili[_ >: A with B <: Kili[_ >: A with B <: Object]].
That makes sense to me.

@scala-jenkins scala-jenkins added this to the 2.13.0-RC1 milestone Sep 30, 2018
@joroKr21

This comment has been minimized.

Copy link
Contributor

@adriaanm adriaanm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if we can keep the depth bookkeeping in GlbLubs. Suggestion added, but not tested in depth.

@@ -528,7 +528,7 @@ trait TypeComparers {
(rt2.parents forall (isSubType(tp1, _, depth))) &&
(rt2.decls forall (specializesSym(tp1, _, depth)))
case et2: ExistentialType =>
et2.withTypeVars(isSubType(tp1, _, depth), depth) || fourthTry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works, but I'd prefer to keep the depth bookkeeping logic in GlbLubs. How about adding a .decr in this spot:

isSubType(t, lubRefined, depth) || {

In my superficial local testing, this also seems to break the cycle for this test case. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, you are right, that works too! I wonder if this check is even needed though. The comment about higher-order type parameters shouldn't be true anymore.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Definitely worth looking into getting rid of this additional check.

@joroKr21
Copy link
Member Author

joroKr21 commented Oct 2, 2018

Ok I tried to disable the check entirely. Let's see what CI says. If it's all is green we can try a community build with this change.

However the LUB looks weird now:
Kili[_ >: A with B <: Kili[_ >: A with B <: Object]]{def fili: Fili[_ >: A with M]}

@joroKr21
Copy link
Member Author

joroKr21 commented Oct 2, 2018

That failed quickly. But the errors reveal some fishy code paths.

val concretes = concreteTypes(tvar)
(concretes contains AnyRefClass) || (concretes contains site.memberType(tvar))

Checking if a list of types contains a symbol, for example?

@adriaanm
Copy link
Contributor

adriaanm commented Oct 3, 2018

contains-Any strikes again!

@joroKr21
Copy link
Member Author

joroKr21 commented Oct 3, 2018

I made only the suggested changes now, which means the LUB is:

 Kili[_ >: A with B <: Kili[_ >: A with B <: Object]]{def fili: Fili[_ >: A with M]}

I don't know why the type parameter M is leaking in the signature, but it doesn't seem to be a problem?

Apart from that I don't have any rational argument of why I prefer decrementing in withTypeVars. To me it just seems like a problematic code path altogether.

@adriaanm
Copy link
Contributor

adriaanm commented Oct 3, 2018

As far as I know, the depth argument is meant specifically for avoiding blowups in lub/glb, so I don't understand why it should be decremented in existential type subtyping (if so, why not also in polytype subtyping?)

@adriaanm
Copy link
Contributor

adriaanm commented Oct 3, 2018

The fact that M occurs in the result does sound like a(nother) bug

@joroKr21
Copy link
Member Author

joroKr21 commented Oct 3, 2018

As far as I know, the depth argument is meant specifically for avoiding blowups in lub/glb, so I don't understand why it should be decremented in existential type subtyping (if so, why not also in polytype subtyping?)

et2.withTypeVars(isSubType(tp1, _, depth), depth) uses depth twice. I meant the second one which is used when solving for the quantified variables. Of course it makes no sense to decrement in the underlying subtype check. Since we only care that there is a solution for the quantified variables but not what that solutions is, I'm not sure how much the depth matters there.

But I agree the same can be said about LUB verification.

As long as we know that it's not possible to constrain a quantified variable recursively with the existential type itself, it should be fine.

The fact that M occurs in the result does sound like a(nother) bug

One bug at a time 😃

@adriaanm
Copy link
Contributor

adriaanm commented Oct 3, 2018

My rationale comes from having the structure of the computation of the maximal depth be reflected in how it's decremented. I don't see a link between existential subtyping and typeDepth, but there is one (albeit tenuous) in recursive calls to lub/glb.

@adriaanm adriaanm merged commit d8d63b2 into scala:2.13.x Dec 19, 2018
@joroKr21 joroKr21 deleted the bug/7612 branch December 26, 2018 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants