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

Eliminate class hierarchy in GadtConstraint #16194

Merged
merged 3 commits into from
Oct 25, 2022

Conversation

dwijnand
Copy link
Member

No description provided.

@dwijnand
Copy link
Member Author

This messes with your big PR, @Linyxus, so I'm leaving you in charge of deciding when we can merge it 😄

Copy link
Contributor

@Linyxus Linyxus left a comment

Choose a reason for hiding this comment

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

LGTM in general! There is one thing that concerns me: before this PR, calling methods like addToConstraint and addBound on EmptyGadtConstraint will issue an error. Now we would update the state of GadtConstraint.empty in such cases. I am not sure whether we would really do something ridiculous regard the empty constraint, but if that really happens then in this PR we would end up modifying the state of a constraint which we assume is always empty. This may give us errors and problems that are difficult to trace.

@Linyxus
Copy link
Contributor

Linyxus commented Oct 17, 2022

Maybe @abgruszecki would also want to have a look at this PR. :)

Regarding the conflicts with #14754, it would not be a problem: I can always redo these changes on that branch since they do not change the behavior of the constraint solver in general (except for the empty constraint as I mentioned before, but should not be a problem).

@dwijnand dwijnand self-assigned this Oct 17, 2022
@dwijnand dwijnand force-pushed the GadtConstraint/eliminate-hierarchy branch from 2177a2a to e6a9ffd Compare October 17, 2022 15:20
@dwijnand dwijnand marked this pull request as ready for review October 18, 2022 07:36
@dwijnand dwijnand removed their assignment Oct 18, 2022
Copy link
Contributor

@abgruszecki abgruszecki left a comment

Choose a reason for hiding this comment

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

Other than the minor nitpick, everything looks good to me.

@@ -10,77 +10,25 @@ import util.{SimpleIdentitySet, SimpleIdentityMap}
import collection.mutable
import printing._

import scala.annotation.internal.sharable
object GadtConstraint:
def apply(): GadtConstraint = empty
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we have a "canonical" empty GadtConstraint, to avoid allocating an extra object every time we create a new constraint?

@abgruszecki
Copy link
Contributor

LGTM in general! There is one thing that concerns me: before this PR, calling methods like addToConstraint and addBound on EmptyGadtConstraint will issue an error. Now we would update the state of GadtConstraint.empty in such cases. I am not sure whether we would really do something ridiculous regard the empty constraint, but if that really happens then in this PR we would end up modifying the state of a constraint which we assume is always empty. This may give us errors and problems that are difficult to trace.

I don't think that should cause any issues. We may even want to "dynamically" reconstruct bounds on abstract types which are not yet registered in the GadtConstraint, even if the GadtConstraint is empty, like we do in your PR.

@Linyxus
Copy link
Contributor

Linyxus commented Oct 18, 2022

LGTM in general! There is one thing that concerns me: before this PR, calling methods like addToConstraint and addBound on EmptyGadtConstraint will issue an error. Now we would update the state of GadtConstraint.empty in such cases. I am not sure whether we would really do something ridiculous regard the empty constraint, but if that really happens then in this PR we would end up modifying the state of a constraint which we assume is always empty. This may give us errors and problems that are difficult to trace.

I don't think that should cause any issues. We may even want to "dynamically" reconstruct bounds on abstract types which are not yet registered in the GadtConstraint, even if the GadtConstraint is empty, like we do in your PR.

I was concerned about this because I was thinking that there may be some cases where we really do not want any GADT reasoning (and has some assumption that the constraint is empty). But it seems that we does not have such cases in the compiler.

If so, Dale's original implementation in this PR (where there is a sharable empty GADT constraint object) should be what we want. Sorry for the noise in my first review!

@dwijnand
Copy link
Member Author

But it seems that we does not have such cases in the compiler.

We don't because any code like that could throw an exception today, i.e. without this PR. I don't think we should have a single shared, mutable empty Gadt Constraint. Because tomorrow someone could forget to call .fresh on it and we're leaking lambdas and bounds that belong to some other tree, other compilation unit, or even a previous compiler run..

@abgruszecki
Copy link
Contributor

abgruszecki commented Oct 19, 2022

Agreed, that makes sense. Then I guess this PR should be merged?

@dwijnand
Copy link
Member Author

Yeah, but let's do it after today's meeting.

@dwijnand dwijnand merged commit 292e56f into scala:main Oct 25, 2022
@dwijnand dwijnand deleted the GadtConstraint/eliminate-hierarchy branch October 25, 2022 22:30
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.

3 participants