Skip to content

Fix #6900: Support chained polymorphic extension methods #6901

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 1 commit into from
Jul 22, 2019

Conversation

smarter
Copy link
Member

@smarter smarter commented Jul 21, 2019

Given a tree qual.foo, when we typecheck qual we now that the result
must have a member named foo, if it doesn't we'll try to adapt it
through implicit conversion / extension method selection to something
which does have such a member.

Given a tree qual.foo.bar, the same process happens, but when we
perform the conversion on qual we actually now more about the member
foo: it must have a member named bar. However in general we cannot
use this information: this member might actually require another
conversion and as a rule we don't chain conversions. Therefore, we need
to ignore the expected type of foo, this is implemented by
ProtoTypes#selectionProto wrapping the expected member type in
IgnoredProto.

However, the following failed before this commit:

given bla[A] { def (a: A) foo[C]: C => A = _ => a }
1.foo[String].foo[String]

This happens because when Applications#extMethodApply extracts the
type arguments of the extension method from its expected type, it might
end up unpealing an IgnoredProto. The solution is to rewrap the new
expeted type into an IgnoredProto if the original was ignored.

Given a tree `qual.foo`, when we typecheck `qual` we now that the result
must have a member named `foo`, if it doesn't we'll try to adapt it
through implicit conversion / extension method selection to something
which does have such a member.

Given a tree `qual.foo.bar`, the same process happens, but when we
perform the conversion on `qual` we actually now more about the member
`foo`: it must have a member named `bar`. However in general we cannot
use this information: this member might actually require another
conversion and as a rule we don't chain conversions. Therefore, we need
to ignore the expected type of `foo`, this is implemented by
`ProtoTypes#selectionProto` wrapping the expected member type in
`IgnoredProto`.

However, the following failed before this commit:

    given bla[A] { def (a: A) foo[C]: C => A = _ => a }
    1.foo[String].foo[String]

This happens because when `Applications#extMethodApply` extracts the
type arguments of the extension method from its expected type, it might
end up unpealing an `IgnoredProto`. The solution is to rewrap the new
expeted type into an `IgnoredProto` if the original was ignored.
@odersky odersky merged commit a13d60f into scala:master Jul 22, 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.

2 participants