The type of output in the argument list in combination with a broken setter

Imagine the following elements in scope:

object Thing { var data: Box[String] = Empty } def perform[T](setter: Box[T] => Unit) { // doesn't matter } 

Failed to compile the following:

 perform(Thing.data = _) 

Error message:

 <console>:12: error: missing parameter type for expanded function ((x$1) => Thing.data = x$1) perform(Thing.data = _) ^ <console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error. perform(Thing.data = _) ^ 

While the following compilation:

 perform(Thing.data_=) 

Since then I have surpassed this question by creating a better abstraction, but my curiosity still remains.

Can someone explain why this is?

+7
source share
1 answer

Highlight what you do in the first example:

 Thing.data = _ 

is an abbreviation for defining an anonymous function that looks like this:

 def anon[T](x: Box[T]) { Thing.data = x } 

Therefore when you call

 perform(Thing.data = _) 

this is the same as

 perform(anon) 

The task of anon and perform to take a parameter of type T and in no case to declare what T . The compiler can only deduce type parameters in a function call from the passed arguments, and not from the function body, so it cannot conclude in anon that T must be a String .

Please note that if you call

 perform[String](Thing.data = _) 

the compiler does not have a problem, because now it knows that there must be a T , and if you try to use any type other than a string, you will get a type mismatch error, but the error occurs in the body of an anonymous function, and not when perform called.

However, when you call

 perform(Thing.data_=) 

you are passing the Thing.data_= method, which is explicitly defined as Box[String] => Unit , so the compiler can output the perform type parameter because it comes from the function argument.

+3
source