1
votes

In Scala 2.11.5, compiling this

object Tryout {
  trait A {
    def method(a: Int): Boolean
  }

  abstract class B extends A {
    def method(a: Int) = ???
  }

  new B {
    override def method(a: Int) = true  // type mismatch here
  }
}

yields a "type mismatch: found Boolean, required Nothing" at the "true". If I replace the ??? with true or false, it compiles. It also compiles if I specify the result type of "method" in the abstract class.

This is not a big issue. However I'm curious whether anybody can explain why ??? is not inferred correctly as Boolean?

2
change it to def method(a: Int): Boolean = ??? in abstract class B.sarveshseri
This is actually a known bug. If I could find the ticket I'd link it. It is slated to be fixed in 2.12 I believe.wheaties
@wheaties Are you sure that's a bug? It seems consistent to me that the compiler would infer the most specific type (Nothing is a subtype of Boolean).Dimitri
Why do you think its a bug... ? Looks consistent...sarveshseri
Because you're overriding the type as given in the interfacewheaties

2 Answers

6
votes

Scala allows you to make the return type of an inherited method more restrictive in a sub-class.

abstract class A {
    def foo: Any
}

abstract class B {
    def foo: Int
}

new B {
    def foo = 1
}

So when you declare def method(a: Int) = ??? in B, ??? is inferred as Nothing, because the scala compiler doesn't know if you want Boolean or Nothing. This is one of the reasons why it is always a good idea to explicitly declare return types.

3
votes

Return type of def method(a: Int) = ??? is actually Nothing.

scala> def method(a: Int) = ???
method: (a: Int)Nothing

Now, method in class B is overriding the method from the parent trait. You should define your claas B like this,

abstract class B extends A {
  // def method is provided by trait A
}

or

abstract class B extends A {
  // def method with full signature
  override def method(a: Int): Boolean = ???
}