Skip to content

Prune constraints that could turn into cycles #1058

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

Merged
merged 6 commits into from
Feb 8, 2016

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Feb 5, 2016

Fixes #864. Review by @smarter.

@odersky
Copy link
Contributor Author

odersky commented Feb 5, 2016

The issue uncovered a much deeper problem with constraint solving, which we solve by deliberatley widening narrowing the constraint.

@smarter
Copy link
Member

smarter commented Feb 5, 2016

Interesting approach, do you think that you could create a neg test that demonstrate valid code that does not compile with this patch?
I see that you added an optional cycle detection check in addOneBound, couldn't we leave addConstraint as it was before, and instead always check for cycles in addOneBound and heal them? Would that be too costly?

@odersky
Copy link
Contributor Author

odersky commented Feb 5, 2016

@smarter Logically, prune belongs where it is, because that's where we split a bound into a bound without type params and additional parameter/parameter relationships established by addLess. The cycle check in addConstraint can still fail, because TypeVars might be instantiated late.

@odersky
Copy link
Contributor Author

odersky commented Feb 5, 2016

@smarter Also note that the cycle check does not catch cycles of length > 1.

prune(bound.underlying)
case bound: PolyParam if constraint contains bound =>
if (!addParamBound(bound)) NoType
else if (fromBelow) defn.NothingType
Copy link
Member

Choose a reason for hiding this comment

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

What about narrowing a bit less by using something like prune(constraint.nonParamBounds(bound).lo) instead of defn.NothingType?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would not add anything. By recording the isLess we get the bounds anyway.

@smarter
Copy link
Member

smarter commented Feb 5, 2016

Should we add a debug log message when we narrow bounds? Otherwise it might be easy to overlook when trying to understand why some code does not compile.

@odersky
Copy link
Contributor Author

odersky commented Feb 6, 2016

I don't think we need a log message. The cases where this will fail will be really rare, and should be easily caught already by turning on the constr printer. Without constr, I think t will be impossible to diagnose.

* are tested for direct or indirect dependencies, each time a
* constraint is added in TypeComparer.
/** Make sure none of the bounds in an OrderingConstraint contains
* another constrained parameter at its toplevel (i.e. as an operand
Copy link
Member

Choose a reason for hiding this comment

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

You say "another constrained parameter" but the check does b eq param, so shouldn't you say something like "Make sure none of the bounds of a parameter in an OrderingConstraint contains this parameter at its toplevel" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, indeed. Can you make that change please? Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

Done, also fixed the documentation of addConstraint.

smarter added a commit that referenced this pull request Feb 8, 2016
Prune constraints that could turn into cycles
@smarter smarter merged commit 6e7bb3a into scala:master Feb 8, 2016
@allanrenucci allanrenucci deleted the fix-#864-v2 branch December 14, 2017 19:19
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