-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Strange type inference for extension method with a leading using clause #11718
Comments
Actually this seems to be a problem also if we define def foo[A](using fa: Foo[A])(a: A)(b: Boolean) = ??? Here we can't put the second type parameters section but this doesn't seem to matter. |
I don't get how this is a bug. You describe the behavior of the type inferencer. In what sense is this wrong? I believe for situations like this, it's better to leave things as they are unless you have a concrete, implemented change proposal that we can discuss. Otherwise this reduces the bandwidth of maintainers who are already overloaded. |
In general trait Foo[A]
def foo[A](using fa: Foo[A])(a: A)(b: Boolean) = ???
given Foo[Int] with {}
given Foo[Boolean] with {}
val y = foo(1)(true) returns the error
while there's no reason the instance for trait Foo[A]
def foo[A](using fa: Foo[A])(a: A)(b: Boolean) = ???
given Foo[Int] with {}
given Foo[String] with {}
val y = foo(1)(true)
Here it's obviously not true that there is no instance of Generally it looks as if unless there's there's exactly one given instance matching the type of the first explicit parameter |
I still see nothing to act on. You need to be a lot more specific what particular step of the inferencer should be changed, or you need to produce a single program that you think is mis-inferred with a good explanation how to do better. |
See also #11713 |
@rjolly actually I found this issue while playing around with the one you had reported but the reason of this problem seems to be different as here using non-extension methods doesn't work either |
Compiler version
3.0.0-RC2-bin-20210311-cc87d06-NIGHTLY
Minimized code
Output
Depending on the given instances of
Foo[A]
we uncomment the compilation results are as follows:Output more or less as one might expect except that there are
[Foo[?]]
andFoo[A]
instead ofFoo[Int]
Instance only for
Int
- compiles successfullyInstance only for
Boolean
:The error makes sense assuming that the compiler first tries to find the implicit, finds the only existing instance and uses it to instantiate the type variable. Although it would be nice if we could infer the type correctly here.
String
:Result analogous to case 3
String
andBoolean
:This obviously should not compile because there's no instance for
Int
. Alternatively the compiler could complain that there are 2 given instances and it doesn't know which one to pick. This would be somehow consistent with cases 3 and 4. But here instead for some reason the type parameterA
gets inferred asBoolean
, which seems to be taken from the type of the parameterb
.String
andInt
:Now the compiler tries to instantiate
A
as a supertype ofBoolean
(which again doesn't make sense) instead of successfully choosing the instance forInt
or complaining about the ambiguity. Also note that theNote
message doesn't seem to make sense asgiven_Foo_String
is declared in the current scope.Int
andBoolean
Same as case 5 but here the instance for
Int
could in theory be chosen to make this compile.Additionally for all cases with more than one instance (5-8) we do indeed get an ambiguous implicit error like this
if we pass a dummy type argument to the invocation of foo like
val x = 1.foo[Any](true)
.Also if we try to invoke the extension method
foo
as a normal method (val y = foo(1)(true)
) this doesn't work either unless there's only an instance forInt
.Expectation
There is a simple workaround to make this work as expected by putting the first using section after the receiver parameter like this
but this seems to only hide the problem instead of actually resolving it.
In general we could either try to make the code example compile as long as there is an available given instance for
Int
(even if there are also instances for other types) or at least uniformly show correct error messages (the message about ambiguous implicits might be good enough but a message about not being able to infer the type parameter based on arguments from a parameters list which does not directly follow the type parameters list would be even better)The text was updated successfully, but these errors were encountered: