Skip to content
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

Propagate dependencies through implicit parameters #5601

Merged
merged 1 commit into from
Dec 12, 2018

Conversation

milessabin
Copy link
Contributor

Fixes #5427.

If an implicit parameter list is dependent, we must propagate inferred types through the remainder of the parameter list, similarly to how it's done for non-implicit parameter lists in Applications#matchArgs#addTyped.

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.

Thanks for taking care of this!

// done for non-implicit parameter lists in Applications#matchArgs#addTyped.
val formals2 =
if (wtp.isParamDependent && arg.tpe.exists)
formals1 mapconserve {f1 => safeSubstParam(f1, wtp.paramRefs(n), arg.tpe)}
Copy link
Member

Choose a reason for hiding this comment

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

style nitpick:

Suggested change
formals1 mapconserve {f1 => safeSubstParam(f1, wtp.paramRefs(n), arg.tpe)}
formals1.mapconserve(f1 => safeSubstParam(f1, wtp.paramRefs(n), arg.tpe))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

I suggest pressing "Resolve conversation" below instead of saying "Done.", it reduces the number of emails we get :).

// types through the remainder of the parameter list similarly to how it's
// done for non-implicit parameter lists in Applications#matchArgs#addTyped.
val formals2 =
if (wtp.isParamDependent && arg.tpe.exists)
Copy link
Member

Choose a reason for hiding this comment

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

I don't think arg.tpe.exists can occur here unlike addTyped, but we should check arg.tpe.isError since in case of implicit failure, the type will be an instance of SearchFailureType which is a subtype of ErrorType:

Suggested change
if (wtp.isParamDependent && arg.tpe.exists)
if (wtp.isParamDependent && !arg.tpe.isError)

I also suggest adding some negative test cases that exercises this code path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do need exists here. Switching to !arg.tpe.isError results in an assertion for a non-existent getter denotation.

I'll add some negative test cases.

if (wtp.isParamDependent && arg.tpe.exists)
formals1 mapconserve {f1 => safeSubstParam(f1, wtp.paramRefs(n), arg.tpe)}
else formals1
arg :: implicitArgs(formals2, n+1)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
arg :: implicitArgs(formals2, n+1)
arg :: implicitArgs(formals2, n + 1)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -2348,7 +2348,7 @@ class Typer extends Namer
def dummyArg(tp: Type) = untpd.Ident(nme.???).withTypeUnchecked(tp)

def addImplicitArgs(implicit ctx: Context) = {
def implicitArgs(formals: List[Type]): List[Tree] = formals match {
def implicitArgs(formals: List[Type], n: Int): List[Tree] = formals match {
Copy link
Member

Choose a reason for hiding this comment

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

either give a more explicit name for this parameter or add some documentation for this method (something that would be nice to have anyway :))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to argIndex.

@milessabin
Copy link
Contributor Author

@smarter incorporated your feedback.

@allanrenucci
Copy link
Contributor

We prefix Dotty issues with i (e.g. i5427.scala). Issues that start with t come from scalac

@smarter
Copy link
Member

smarter commented Dec 12, 2018

@milessabin Now that github shows diffs when push-forcing commits, I prefer when commits are amended and push-forced to address the feedback of reviewers instead of making new commits just for that (it keeps the history tidy)

@milessabin
Copy link
Contributor Author

Okey doke. I'll reprefix the tests to i, squash and force-push.

Fixes scala#5427.

If an implicit parameter list is dependent, we must propagate inferred
types through the remainder of the parameter list, similarly to how it's
done for non-implicit parameter lists in
Applications#matchArgs#addTyped.
@milessabin
Copy link
Contributor Author

@smarter do you want to do the honours?

@milessabin milessabin merged commit 7c8dee5 into scala:master Dec 12, 2018
@biboudis biboudis added this to the 0.12 Tech Preview milestone Jan 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants