Skip to content

Preserve TypeLambdas in wildApprox #6271

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

Merged
merged 3 commits into from
Apr 11, 2019
Merged

Conversation

milessabin
Copy link
Contributor

wildApprox should not replace TypeParamRefs which are bound by TypeLambdas which are contained in the type being approximated.

Fixes #6238.

wildApprox should not replace TypeParamRefs which are bound by
TypeLambdas which are contained in the type being approximated.

Fixes #i6238.
@odersky
Copy link
Contributor

odersky commented Apr 9, 2019

test performance please

@odersky
Copy link
Contributor

odersky commented Apr 9, 2019

This looks like its on the right track. Let's see what the performance tests say.

@dottybot
Copy link
Member

dottybot commented Apr 9, 2019

performance test scheduled: 2 job(s) in queue, 1 running.

case tl: TypeLambda =>
val internal1 = internal + tl
val paramInfos = tl.paramInfos
val paramInfos1 = tl.paramInfos.mapConserve {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can drop the tl. here.

case _: HKTypeLambda => HKTypeLambda(tl.paramNames)(tl1 => paramInfos.map(substBounds(tl1)), tl1 => res1.subst(tl, tl1))
case _: PolyType => PolyType(tl.paramNames)(tl1 => paramInfos.map(substBounds(tl1)), tl1 => res1.subst(tl, tl1))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think all this machinery is already provided by derivedLambdaType. Can you try this instead as the case for TypeLambda?

  val internal1 = internal + tl
  val paramInfos1 = tl.paramInfos.mapConserve {
    case tb @ TypeBounds(lo, hi) =>
          tb.derivedTypeBounds(
            wildApprox(lo, theMap, seen, internal1),
            wildApprox(hi, theMap, seen, internal1)
          )
      }
  val res1 = wildApprox(tl.resultType, theMap, seen, internal1)
  tl.derivedLambdaType(paramInfos = paramInfos1, resType = res1)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Damn. That's what I expected, and I looked for it, but somehow managed to miss newLikeThis and then ended up rewriting it inline :-(

Copy link
Contributor

Choose a reason for hiding this comment

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

It can even be simplified further, it seems. See 85c641f.

@dottybot
Copy link
Member

dottybot commented Apr 9, 2019

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/6271/ to see the changes.

Benchmarks is based on merging with master (95fd03e)

 - Use derivedLambdaType
 - Drop parameters of PolyTypes altogether
@odersky
Copy link
Contributor

odersky commented Apr 10, 2019

test performance please

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 0 running.

@milessabin
Copy link
Contributor Author

@odersky I'm fine with your simplifications wrt HKTypeLambda, but I don't understand why it's safe to handle PolyTypes in the way you're suggesting.

@odersky
Copy link
Contributor

odersky commented Apr 10, 2019

@odersky I'm fine with your simplifications wrt HKTypeLambda, but I don't understand why it's safe to handle PolyTypes in the way you're suggesting.

We always reduce PolyTypes to their result type, inferring type parameters. Since the type parameter references of PolyTypes are eliminated anyway by wildApprox, there's no need to keep the parameters around. That's the thinking behind it, anyway.

@milessabin
Copy link
Contributor Author

milessabin commented Apr 10, 2019

Since the type parameter references of PolyTypes are eliminated anyway by wildApprox, there's no need to keep the parameters around

Right, but these type parameters are being bound internally to the type being approximated, so do they really need to be wildcarded out? My understand was that the point of the approximation was only to eliminate references to type parameters bound externally to the type being approximated.

@dottybot
Copy link
Member

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/6271/ to see the changes.

Benchmarks is based on merging with master (2f557b5)

@odersky
Copy link
Contributor

odersky commented Apr 10, 2019

Right, but these type parameters are being bound internally to the type being approximated, so do they really need to be wildcarded out? My understand was that the point of the approximation was only to eliminate references to type parameters bound externally to the type being approximated.

I think it could go either way, but I did not find an instance where we would actually call wildApprox on a PolyType. So I agree, it's better to simplify and treat PolyTypes just like other TypeLambdas.

I think it could go either way, but I did not find an instance where we would
actually call wildApprox on a PolyType. So it's better to simplify and treat
PolyTypes just like other TypeLambdas.
@milessabin
Copy link
Contributor Author

This LGTM ... happy with this being merged if you are :-)

@odersky odersky merged commit b40b519 into scala:master Apr 11, 2019
@allanrenucci allanrenucci deleted the topic/i6238 branch April 11, 2019 17:18
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