views:

224

answers:

5

The following Scala code fails to compile in Scala 2.7.7, with a type mismatch error "found: Null(null) required: T" on the last line:

/**
 * @param [T] key type
 */
class Key[T] 

class Entry[T](val k: Key[T], val v: T)

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null)

I'm fully aware of the evilness of nulls, but suffice it to say that I actually need to do this. Is this a compiler bug or programmer error?

Edit: Just to clarify, T is a type parameter and not a concrete type. I didn't realize this was ambiguous in the original question until I read Carl's response more carefully.

A: 

Why don't you try using "None?" See here

http://www.scala-lang.org/docu/files/api/scala/None$object.html

wheaties
Thanks for the quick response, but I actually **need** to pass a null. The Key and Entry classes are defined in a Java library that can't access the scala library.
Aaron Novstrup
For a quick hack then, why not instantiate a variable, set it to null, and then pass it in. I know, it's ugly and a total hack... Actually, I'd use whatever someone else suggests first. I hate suggesting hacks.
wheaties
Yeah, I have a workaround (null.asInstanceOf[T]), but I wanted to make sure I wasn't hacking around a flaw in my understanding.
Aaron Novstrup
+1  A: 

Have you tried this?

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null: T)
Mitch Blevins
Same problem using REPL and scala 2.7.5.
paradigmatic
I didn't realize that was valid syntax. :) Just tried it, and it doesn't work either.
Aaron Novstrup
I don't have 2.7 handy to test, but I would also try null.asInstanceOf[T]
Mitch Blevins
+3  A: 

Here's the definition that covers null:

Type Null is a subtype of all reference types; its only instance is the null reference. Since Null is not a subtype of value types, null is not a member of any such type. For instance, it is not possible to assign null to a variable of type Int.

In English, this is saying you can't assign null to a value type but it's valid to assign to any reference type.

I'm having some trouble figuring out whether T is a value or reference type; but that would answer your question.

As you define T to be a subtype of AnyRef, I guess it's a ref and the "bug" explanation seems the more likely; especially as Mitch Blevins just said the code works under 2.8 .

Carl Smotricz
It seems to be the consensus that this should work, so I'm going to accept your answer unless contrary evidence comes along.
Aaron Novstrup
+1  A: 

Try this:

class Key[T <: AnyRef]

class Entry[T <: AnyRef](val k: Key[T], val v: T)

def makeEntry[T <: AnyRef] = new Entry[T](new Key[T], null.asInstanceOf[T])

I'm not sure why the "asInstanceOf[T]" is required, but it seems to be.

Erik Engbrecht
Didn't work in Scala (and I actually can't use that technique anyway because Key and Entry are really Java classes defined in another library)
Aaron Novstrup
+3  A: 

Apparently the correct way to do this in 2.7 is:

class Key[T]

class Entry[T](val k: Key[T], val v: T)

def makeEntry[T >: Null] = new Entry(new Key[T], null)
Aaron Novstrup