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

Be still more careful when computing denotations of class parameters #16112

Merged
merged 1 commit into from
Sep 27, 2022

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Sep 27, 2022

Be still more careful when intersecting info and arguments of a class type parameter. This is the latest installment of a never-ending story.

The problem is this: Given

class C[T >: L1 <: H1] { val x: T }
def f(): C[? >: L2 <: H2]

what is the type of f().x?

With capture conversion (an extremely tricky aspect of the type system forced on us since Java does it), the type is something like ?1.T where ?1 is a skolem variable of type C[? >: L2 <: H2]. OK, but what is the underlying (widened) type of ?1.T?

We used to say it's C[T >: L1 <: H1]. I.e. we forgot about the actual arguments. But then we had to change untupling desugarings from defs to vals in #14816 to fix #14783 and it turned out that was not good enough, we needed the information of the actual arguments, i.e. the type should be C[T >: L2 <: H2]. Then something else started failing which relied on the formal arguiment bounds being preserved. So the new resolution was that the type would be the intersection of the formal parameter bounds and the actual bounds, i.e. C[T >: L1 | L2 <: H1 & H2]. Then there was a series of problems where that failed, either because the parameter bound was F-bounded or because the intersection was an empty type. The latest installment is that the parameter bounds refer to another parameter in the same class, which requires a simultaneous substitution of all skolemized bounds for all dependent parameter references in the parameter bounds. But that's impossible or at least very hard to achieve since we are looking at the type of a single parameter after capture conversion here. So the current solution is to also back out of the intersection if there are cross-parameter references and to use just the argument bounds instead.

Be still more careful when intersecting info and arguments of a class type parameter.
This is the latest installment of a never-ending story.

The problem is this: Given
```scala
class C[T >: L1 <: H1] { val x: T }
def f(): C[? >: L2 <: H2]
```
what is the type of `f().x`?

With capture conversion (an extremely tricky aspect of the type system forced on us
since Java does it), the type is something like `?1.T` where `?1` is a skolem variable
of type `C[? >: L2 <: H2]`. OK, but what is the underlying (widened) type of `?1.T`?

We used to say it's `C[T >: L1 <: H1]`. I.e. we forgot about the actual arguments.
But then we had to change untupling desugarings from defs to vals in scala#14816 to fix
scala#14783 and it turned out that was not good enough, we needed the information of the
actual arguments, i.e. the type should be `C[T >: L2 <: H2]. Then something else started
failing which relied on the formal arguiment bounds being preserved. So the new resolution
was that the type would be the intersection of the formal parameter bounds and the actual
bounds, i.e. `C[T >: L1 | L2 <: H1 & H2]`. Then there was a series of problems where _that_
failed, either because the parameter bound was F-bounded or because the intersection was an
empty type. The latest installment is that the parameter bounds refer to another parameter
in the same class, which requires a simultaneous substitution of all skolemized bounds for
all dependent parameter references in the parameter bounds. But that's impossible or at least
very hard to achieve since we are looking at the type of a single parameter after capture conversion here.
So the current solution is to also back out of the intersection if there are cross-parameter
references and to use just the argument bounds instead.
@jchyb jchyb linked an issue Sep 27, 2022 that may be closed by this pull request
@odersky odersky merged commit 731522a into scala:main Sep 27, 2022
@odersky odersky deleted the fix-16105 branch September 27, 2022 14:28
@jchyb jchyb added the backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. label Sep 27, 2022
@Kordyjan Kordyjan added this to the 3.2.1 backports milestone Sep 27, 2022
@Kordyjan Kordyjan added backport:accepted This PR needs to be backported, once it's been backported replace this tag by "backport:done" and removed backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. labels Oct 17, 2022
Kordyjan added a commit that referenced this pull request Oct 17, 2022
@Kordyjan Kordyjan added backport:done This PR was successfully backported. and removed backport:accepted This PR needs to be backported, once it's been backported replace this tag by "backport:done" labels Oct 17, 2022
@Kordyjan Kordyjan modified the milestones: 3.2.1 backports, 3.2.2 Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:done This PR was successfully backported.
Projects
None yet
3 participants