-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid bidirectional GADT typebounds from fullBounds #15683
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
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
I'd prefer if @smarter could take a look when he has time |
This now fixes 3 bugs. Can we merge it? |
I can review it this week. |
@smarter Sorry, I slightly misrepresented what I said. I said that I knew, loosely, how reproduce the problem with regular type variables. But what I had found is that if you change |
Sorry, I'm not sure I understand what changes you have in mind that would lead to the same issue with non-gadt type variables. To me, it still seems like this is purely an issue with gadt handling. The whole point of having an ordering between type variables in OrderingConstraint is to avoid cyclic bounds, in fact if I print uninstantiated variables: A$1(param)1, B$1(param)1
constrained types: [A$1(param)1 <: B$1(param)1, B$1(param)1]: Any
bounds:
A$1(param)1
B$1(param)1
ordering:
A$1(param)1 <: B$1(param)1
co-deps:
contra-deps: But then, we end up setting the bounds of GADT symbols using We could change TypeMap itself to handle this, but to me the real issue is the way we set the info of GADT symbols. It should be morally equivalent to something the user could write if we don't want to end up with more puzzling bugs. For example I can write: def foo =
type A
type B >: A
val a: A = ???
val b: B = a or: def foo =
type B
type A <: B
val a: A = ???
val b: B = a and both will be handled gracefully by the compiler and compile as expected, because TypeComparer knows it needs to check the bounds of both abstract types involved to determine whether they're in a subtyping relationship (fun fact: this means it's possible for subtype checking to take an amount of time exponential in the number of abstract types in your program [Abel 2017, p.4]). I think we could achieve something similar if we replaced |
db7c99c
to
944c77b
Compare
I wasn't able to find a solution based on that. I also know that removing GADT information about symbols changes type comparing, because we trust GADT info, but not abstract symbol info, because we can't distinguish it from unsound, user-defined, info. But I found a solution based on using and tweaking |
e7a2ea2
to
1389bb8
Compare
Nevermind, found a solution! (finally) |
d737a7a
to
715bca8
Compare
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.
Very nice fix! Thanks a lot for doing all the hard work on this!
// B$2 had info <: B$1 and fullBounds <: B$1 | ||
// We can use the info of B$2 to drop the lower-bound of B$1 | ||
// and return non-bidirectional bounds B$1 <: X and B$2 <: B$1. | ||
if tp.name.is(UniqueName) && !tp.info.hiBound.isExactlyAny && self <:< tp.info.hiBound => acc |
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.
Can we use tp.symbol.isPatternBound
instead of relying on the name kind?
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.
Also, would checking self =:= tp.info.hiBound
be enough for all our test cases? That would remove the need for isExactlyAny
which I'm a bit wary of (what if the symbols involved have another common upper-bound like AnyRef?)
b7ce616
to
37aeb3d
Compare
constraint.minLower(param).foldLeft(nonParamBounds(param).lo) { (acc, p) => | ||
externalize(p) match | ||
// drop any lower param that is a GADT symbol | ||
// and is upper-bounded by a non-Any super-type of the original parameter |
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.
hmm looks like we still need to update the comment after changing <:< to =:=
No description provided.