Skip to content

[WIP] Changes to Interpolation #4065

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 7 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Mar 3, 2018

This is an attempt to do rethink interpolation of type variables from the ground up. So far it's an experiment.

odersky added 3 commits March 3, 2018 10:57
Previously we failed if a member of a TypeParamRef did not find
anything in its upper constraint bound. We now look in the lower
bound instead, and if something is found there, add a constraint
to make sure that any future instantiation of the parameter has
the same members.
We (probably) need ephemeral only if we actually compute the current instance type, and this
instance type might be retracted later.
@@ -591,7 +591,13 @@ object Types {
ctx.typerState.constraint.entry(tp) match {
case bounds: TypeBounds if bounds ne next =>
ctx.typerState.ephemeral = true
go(bounds.hi)
Copy link
Contributor

Choose a reason for hiding this comment

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

We discussed this with Martin on a whiteboard, so a memo (and possible comment).

If X >: List[T] and x: X and we typecheck x.filter(p), how should X be instantiated? Here setting X to its lower bound works, but might violate other constraints — ideally we'd just add some constraint X <: { def filter... }, but since we don't have those, looking up List.filter's definition class (say Traversable[T]) and adding bound X <: Traversable[T] is a more general solution.

This solution is not yet complete because some other ancestor of List[T] which doesn't extend Traversable[T] might have another overload of filter. There might even be a realistic example where this happens, but I can't think of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I think it makes sense to add this. Unfortunately, it is not enough. We still need to interpolate TypeVar results in some way when selecting because otherwise we might miss an implicit conversion. E.g.

  Array(1, 2, 3).map(_ + 1).deep

The map operation with current stdlib leaves us with result type That where

That >: Array[Int]

But to typecheck deep we need to find an implicit conversion from the result to ArrayOps. There is none from That, but there is one from Array[Int].

odersky added 4 commits March 5, 2018 08:46
Allow to define what gets shown as a result on a backtrace
The previous scheme created a `val showOp = <some closure>` value for each trace
operation. It was unused if tracing was disabled. Still might be better to
avoid its creation in the first place.
-Yshow-no-inline suppresses "inlined from" parts when printing trees. This is
useful when one has deeply inlined structures, as is the case when looking at `trace`ed code.
Used for small, linked sets. Normal immutable sets
are about as fast for 0 - 4 elements, but are not linked
for larger sizes.
@odersky
Copy link
Contributor Author

odersky commented Mar 7, 2018

Superseded by #4080.

@odersky odersky closed this Mar 7, 2018
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.

2 participants