Skip to content

Fix #6238 (take 3): Strip WildcardType when applying arguments #6252

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

Conversation

smarter
Copy link
Member

@smarter smarter commented Apr 6, 2019

Here's my alternative to #6240 inspired by the other alternative: #6250 :). There's a single test failure which I haven't figured out:

> run tests/pos/typeclass-encoding3.scala
-- Error: tests/pos/typeclass-encoding3.scala:284:25 ---------------------------
284 |    ev.inject(Monad.by[F].pure(x)).map(f)
    |                         ^
    |no implicit argument of type Test.Monad.Common{This = F} was found for parameter ev of method by in object Monad
-- Error: tests/pos/typeclass-encoding3.scala:288:30 ---------------------------
288 |    f => ev.inject(Monad.by[F].pure(x)).flatMap(f)
    |                              ^
    |no implicit argument of type Test.Monad.Common{This = F} was found for parameter ev of method by in object Monad

@odersky Could you take a look and see if the change to wildApprox makes any sense ?

smarter added 3 commits April 6, 2019 18:19
Given:

    type F[X] = Foo[X]

We've always been able to reduce `F[_]` to `Foo[_]` if `Foo` is a class.
This commit does something similar for refinements, given:

    type G[X] = Bla { type R = X }

We can reduce `G[_]` to `Bar { type R }` (previously we reduced it to
`Bar { type R = Any }` which is incorrect).
I'm not entirely sure why this fixes the issue but the previous behavior
seems dubious to me: what's the meaning of applying a WildcardType
argument to a type lambda ? By contrast, applying a TypeBounds has a
well-defined behavior (`appliedTo` will call `TypeApplication#Reducer` to
get rid of the type lambda).
Observed when running the pos tests after the previous commit, the test
suite didn't say which test caused the stackoverflow, but the stack
trace ended with:

at dotty.tools.dotc.core.Decorators$ListDecorator$.loop$2(Decorators.scala:90)
at dotty.tools.dotc.core.Decorators$ListDecorator$.loop$2(Decorators.scala:90)
at dotty.tools.dotc.core.Decorators$ListDecorator$.filterConserve$extension(Decorators.scala:97)
at dotty.tools.dotc.core.OrderingConstraint.$anonfun$remove$1(OrderingConstraint.scala:453)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237)
at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:36)
at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:198)
at scala.collection.TraversableLike.map(TraversableLike.scala:237)
at scala.collection.TraversableLike.map$(TraversableLike.scala:230)
at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:198)
at dotty.tools.dotc.core.OrderingConstraint.removeFromBoundss$1(OrderingConstraint.scala:453)
at dotty.tools.dotc.core.OrderingConstraint.$anonfun$remove$4(OrderingConstraint.scala:456)
at dotty.tools.dotc.util.SimpleIdentityMap$MapMore.mapValuesNow(SimpleIdentityMap.scala:209)
at dotty.tools.dotc.core.OrderingConstraint.removeFromOrdering$1(OrderingConstraint.scala:456)
at dotty.tools.dotc.core.OrderingConstraint.remove(OrderingConstraint.scala:458)
at dotty.tools.dotc.core.OrderingConstraint.replace(OrderingConstraint.scala:440)
at dotty.tools.dotc.core.OrderingConstraint.replace(OrderingConstraint.scala:132)
at dotty.tools.dotc.core.Types$TypeVar.instantiateWith(Types.scala:3712)
at dotty.tools.dotc.core.Types$TypeVar.instantiate(Types.scala:3724)
at dotty.tools.dotc.typer.Inferencing.$anonfun$interpolateTypeVars$2(Inferencing.scala:450)
...
@odersky
Copy link
Contributor

odersky commented Apr 7, 2019

I am still not sure what goes on here. Both fixes disable wildcarding in some instances (or, rather, this one reverses it). But (a) I am not sure why this helps and (b) this is dangerous. We risk getting a cache miss and with it failing to find an implicit. I think we need to come up with a complete explanation what goes wrong and why the fix is both complete and safe before proceeding.

@milessabin
Copy link
Contributor

@odersky my intuition was that it's incorrect to approximate type parameter refs of type parameters bound in the type itself. My understanding is that the point of approximating with wildcards (in Implicits.scala at least) is to avoid adding bogus constraints to type vars bound outside the type being approximated.

I restricted my fix to HKTypeLamdas simply to make the most conservative change possible to fix clearly broken cases wrt kinding, but I can believe that the problem might be more general.

@odersky
Copy link
Contributor

odersky commented Apr 7, 2019

my intuition was that it's incorrect to approximate type parameter refs of type parameters bound in the type itself.

That looks reasonable. So maybe do just that? We can keep bound type parameters in a set in wildApprox and keep them unchanged if we see them.

Given the subtlety of wildApprox it's important to find a solution that clarifies things and whose correctness is evident.

@milessabin
Copy link
Contributor

@odersky

So maybe do just that?

That's pretty much what I did. The complication is that the internally bound type params might have bounds which are bound externally, and those do need to be wildcarded. I think that accounts for most of the additional complexity that you're seeing in #6240.

And again, I restricted this to just HKTypeLambdas as the conservative option. If you'd prefer that I cover all the similar binders as well I'd be happy to give that a try.

@milessabin
Copy link
Contributor

@odersky @smarter more thoroughgoing attempt at "just doing that" here: #6271.

@smarter
Copy link
Member Author

smarter commented Apr 11, 2019

Closing in favor of the now-merged #6271

@smarter smarter closed this Apr 11, 2019
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