Skip to content

Don't lose info in bounds when pruning #8828

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 22 commits into from
May 7, 2020

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 29, 2020

A refactoring of the code for constraints and constraint handling. No more solutions are lost when adding a bound to a constraint. This means that the only source of cutoff of the solution space is now either, which is well understood.

The improvements were made possible by systematically avoiding cyclic constraints in Constraint itself.
"Cyclic" means that a type parameter A appears in its own bound at the toplevel (i.e. as a factor in some combination of & and | types. Any such occurrences can be replaced by the bottom or top types without loss of solutions. E.g.,

   A <: A | T  <=>  A <: AnyKind | T  <=>  A <: AnyKind
   A <: A & T  <=>  A <: AnyKind & T  <=>  A <: T
   A | T <: A  <=>  Nothing | T <: A  <=>  T <: A
   A & T <: A  <=>  A & Nothing <: A  <=>  Nothing <: A

New cyclic bounds can also appear as a consequence of unification.
The latter goes through addOneBound, but not through addConstraint.
So the prune logic that avoids cycles should go to addOneBound.

ExprType checking could logically stay with addConstraint but it
was simpler to move it as well.
odersky added 3 commits April 29, 2020 18:08
Instead of checking that constraints are "separated"
in addOneBound, we now ensure that they are.
The dropped lines were added as an intermediate stage before we
settled on doing this in addOneBound.
Need to take into account type parameters that are not bound
by constraint
odersky added 5 commits April 30, 2020 15:53
Make sure cycles are detected and avoided in OrderingConstraint itself
Half of what it does is now handled in constraint itself
Without the additional case, scalatest fails.
@odersky
Copy link
Contributor Author

odersky commented Apr 30, 2020

test performance please

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/8828/ to see the changes.

Benchmarks is based on merging with master (d7c0574)

@odersky odersky marked this pull request as ready for review April 30, 2020 21:18
@smarter
Copy link
Member

smarter commented Apr 30, 2020

Exciting! I haven't had a deep look at the changes yet, but one thing I noticed last time I looked at the pruning logic is that it didn't handle cases like T <: Id[T] where type Id[T] = T. Adding .dealias should fix it, but the documentation of addConstraint claims that no aliases can appear in that position (https://github.com/lampepfl/dotty/blob/6f51dbb8f261f7ee8e3c9bb664d3dc6cb5d33b1f/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala#L416), so maybe something worth digging into.

@smarter
Copy link
Member

smarter commented Apr 30, 2020

Hmm it's possibly the problematic unhandled form is actually T <: A | Id[T], in which case .dealias would be justified.

Also detect cycles containing aliases and annotated types.
@odersky
Copy link
Contributor Author

odersky commented May 1, 2020

@AleksanderBG I assigned you as reviewer since knowing about the changes in ConstraintHandler should be useful for your planned GADT refactorings wrt AbstractContext.

@odersky
Copy link
Contributor Author

odersky commented May 6, 2020

@AleksanderBG How about that review? I would like to merge this week.

@abgruszecki
Copy link
Contributor

LGTM! Hearing your explanation on Monday about this change helped understand what's going on. Merging now.

@abgruszecki abgruszecki merged commit ef255d3 into scala:master May 7, 2020
@abgruszecki abgruszecki deleted the fix-prune branch May 7, 2020 17:28
Comment on lines -279 to +266
.orElse(if (isUpper) defn.AnyType else defn.NothingType)
.orElse(if (isUpper) defn.AnyKindType else 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.

@AleksanderBG Does this change remove the need for f94606a ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was planning on testing that. I'm not completely sure how to make myself certain that now there's no need for f94606a - AFAIU, the above change will make the bounds of an unconstrained variable be >: Nothing <: AnyKind, but I'm not sure if it's not possible to still get a <: Any constraint, because other TypeBounds default to >: Nothing <: Any anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Ah right, those need to be fixed too, I have a wip branch wĥere I attempted that but I don't know when I'll be able to get back to it: https://github.com/dotty-staging/dotty/commits/wildcard-bounds

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.

4 participants