-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Extension methods can't be chained when the the first has an explicit type parameter but no other parameters #6900
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
Labels
Comments
smarter
added a commit
to smarter/dotty
that referenced
this issue
Jul 21, 2019
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
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 implicit conversion on `qual` we actually know 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 we don't chain conversions as a rule. Therefore, we need to ignore the expected type of the member, 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.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
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 implicit 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 we don't chain conversions as a rule. Therefore, we need to ignore the expected type of the member, 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.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
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 implicit 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 we don't chain conversions as a rule. Therefore, we need to ignore the expected type of the member, 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.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
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.
smarter
added a commit
to dotty-staging/dotty
that referenced
this issue
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.
Thanks for the report! PR and explanations of what happened here: #6901 |
odersky
added a commit
that referenced
this issue
Jul 22, 2019
Fix #6900: Support chained polymorphic extension methods
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
minimized code
Fails to compile with:
expectation
It should compile.
Note that defining an intermediate
val
works:As does letting
C
be inferred:It's also just fine if you add an empty parameter list:
The text was updated successfully, but these errors were encountered: