Skip to content

[Do not merge] Aborted Experiment: Native AppliedType #2947

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

Closed
wants to merge 18 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Aug 2, 2017

A more developed version of #2898.

In the end I did not go ahead with this. Here's a summary why:

First, there are other parts of the compiler that rely on the refinement encoding in interesting ways. In particular, the way we compute findMember relies on the fact that the member type
of x in class C is a function of the member types of x in the parent classes of C. This is no longer true when we instantiate arguments immediately. To pick an example from collections: The type of toCollection has the form

 toCollection: (x: Repr)T

where Repr is a parameter to all collections. If we see that type from a specific
collection sc we get (x: sc.Repr)T. The inherited types of toCollection are
all of the form (x: P.this.Repr)T where P is a parent class. The specific collection
type is obtained by joining the patent types with & after replacing P.this with sc.type.

But if we expand parameters with arguments we get (x: P)T for the parent types instead. And there is no safe operation which will allow us to recover (x: SC)T from that.

Second, there's the problem of bounds propagation (see bounds-propagation.scala test case).

Those two problems can be solved by having a mixed scheme where we keep type parameters as members, but make them private and have special types that refer to them instead. But that brings back part of the complexity of the refinement type scheme.

The decisive reason to drop is elsewhere: The Linker relies on being able to refine any parameter bounds in a class or all its base classes retro-actively through refinements. If parameters are no longer instantiated through refinements, this will not work anymore. So if we want to keep the
option of a fast and precise control-flow analysis, we need to keep parameters as refinements.

odersky added 18 commits July 29, 2017 18:41
Bonus point: No need to override applyPrefix in variances
accumulator. This means we have reduced three different ways
to compute the current variance to one.
Need to keep cycle breakers
Same principle as reading from Scala2 pickles applied = in the face
of F-bounded polymorphism we cannot assume that the type
parameters are known when we unpickle a type application.
This avoids memory leaks in unpicklers, where lazy refs
don't capture the context anymore. Other lazyrefs still need
to capture context, though.
AppliedType will be used for all type applications, higher-kinded
or not. That is, eventually, it will replace HKApply and also the
encodings of type applications as refined types.

This commit introduces AppliedType and adapts baseType computations
to take it into account. AppliedType is not yet constructed anywhere,
however.
So far, everything up to parents is adapted to new scheme. Parents is half done;
needs more work once we change layour of ClassInfo.
Simplifies usage and removes some obscure code in Types
Systematically introduce handlers for AppliedTypes where there
was a handler for HKApply.
Also, change asSeenFrom to use it for arguments
The previous type parameter representation in terms of type members
achieved bounds propagation by waiting until a type member was selected
and then taking original bounds and refinements together as its info.
This no longer works with explicit applications. Instead, we need to
propagate bounds into wildcard arguments explicitly, when a type
application is created.
@odersky
Copy link
Contributor Author

odersky commented Aug 2, 2017

Closed for the reasons given in the PR.

@odersky odersky closed this Aug 2, 2017
odersky added a commit to dotty-staging/dotty that referenced this pull request Aug 10, 2017
The test case shows that it is inadmissible to combine the infos of inherited denotations
into a new denotation. The problem here is that a type parameter CC was instantiated in
an inherited denotation to Traversable, yet the parameter was afterwards instantiated to
ListBuffer. This shows that infos from inheroted denotations are useless; instead we have
to go back to the inherited symbol's infos and map them with an asSeenFrom.

This fix also shows that one of the reasons for abandoning scala#2947 was wrong. We cannot form
denotations from parent denotations in any case, so instantiating early should be fine with
the change in this commit.
@allanrenucci allanrenucci deleted the aborted-applied-type branch December 14, 2017 15:00
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.

1 participant