Skip to content

Fix #2142: Skolemize arguments of dependent methods if necessary #2215

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 5 commits into from
Apr 11, 2017

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 10, 2017

This PR detects errors around unstable argument types to dependent methods that were
not reported before.

odersky added 4 commits April 10, 2017 16:14
These were not printed before, fell back to toString method.
Strictly speaking, all the info about a skolem type is printed, e.g.

    A(?2)

But it's reassuring to have an explanation line like

    ?2 is an unknown value of type A
This was missing before, led to errors not being detected.
We now consider a type also as stable if it refers
to an ExprType whose result type is stable.

The previous commit made pos/z1720.scala break, because it
skolemized unstable argument types. This commit makes the test
pass again.
@odersky odersky requested a review from smarter April 10, 2017 14:24
Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM.

/** Substitute argument type `argType` for parameter `pref` in type `tp`,
* skolemizing the argument type if it is not stable and `pref` occurs in `tp`.
*/
def substArgForParam(tp: Type, argType: Type, pref: ParamRef)(implicit ctx: Context) = {
Copy link
Member

Choose a reason for hiding this comment

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

Minor suggestion: all the subst* methods have the from argument before the to argument, here it's the reverse order which can be a bit confusing. If this is changed it probably makes sense to rename the method to substParamWithArg too.

def substArgForParam(tp: Type, argType: Type, pref: ParamRef)(implicit ctx: Context) = {
val tp1 = tp.substParam(pref, argType)
if ((tp1 eq tp) || argType.isStable) tp1
else tp.substParam(pref, SkolemType(argType.widen))
Copy link
Member

Choose a reason for hiding this comment

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

I would have expected widenSingleton here but I don't know if that makes sense or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For SkolemTypes, it's widen also elsewhere. We don't want to get ExprTypes in there.

@tailrec final def isStable(implicit ctx: Context): Boolean = stripTypeVar match {
case tp: TermRef => tp.termSymbol.isStable && tp.prefix.isStable
final def isStable(implicit ctx: Context): Boolean = stripTypeVar match {
case tp: TermRef => tp.termSymbol.isStable && tp.prefix.isStable || tp.info.isStable
Copy link
Member

Choose a reason for hiding this comment

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

Was this change also needed to make a test pass? It seems more suspicious.

Copy link
Contributor Author

@odersky odersky Apr 10, 2017

Choose a reason for hiding this comment

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

Yes, pos/z1720 started failing without the fix. The commit comment indicates this.

def assignType(tree: untpd.Apply, fn: Tree, args: List[Tree])(implicit ctx: Context) = {
val ownType = fn.tpe.widen match {
case fntpe: MethodType =>
if (sameLength(fntpe.paramInfos, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to change the definition of instantiate to do the skolemization?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I think that's too low-level. By analogy, asSeenFrom does not do skolemization, but reports back that skolemization is needed, and then Typer does it.

Change name and align order of parameters.
@odersky odersky changed the title Fix #2142: Skolemize arguments of dependent methods of necessary Fix #2142: Skolemize arguments of dependent methods if necessary Apr 10, 2017
@odersky odersky merged commit 4ff6561 into scala:master Apr 11, 2017
@allanrenucci allanrenucci deleted the #2142 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.

2 participants