Aladdin - Scala Bugtracking
[#378] project: specification priority: low category: feature
submitter assigned to status date submitted
Philippe Martin fixed 2004-11-16 11:28:45.0
subject Method implementations implicitly refine the method
code
class Foo;
class FooA extends Foo;
class FooB extends Foo;

abstract class Bar1 {
  def foo: Foo;
}

class Bar2 extends Bar1 {
  def foo = new FooA;
}

class Bar3 extends Bar2 {
  override def foo = new FooB;
}
what happened
tmp/test.scala:14: method foo in class Bar3 of type FooB
 cannot override method foo in class Bar2 of type FooA
  override def foo = new FooB;
               ^
one error found
what expected

The error occurs because in class Bar2 the analyzer infers the type FooA for the return type of method foo. This type is more precise than the type given in class Bar1 thus it refines the type of foo in class Bar2. The implementation of foo in class Bar3 is refused because FooB is not an instance of the inferred type FooA of foo in class Bar2.

I wonder if we should use the inferred type only if the method is a new one and not when it's an implementation of an existing one. This would imply that missing return types in method implementations would always be replaced by the return type declared in the method that is implemented or overridden. With that rule, the program above would be legal and method foo would have type Foo in all three classes.

[back to overview]
Changes of this bug report
Martin  edited on  2004-11-19 17:42:09.0
I think this change would make the language easier to use, and more efficient to implement. It would however require significant changes in the spec and in the compiler. I am not yet sure how easy it would be, the compiler changes look tricky, at least.
Martin  edited on  2004-11-19 18:28:39.0
Martin  edited on  2006-10-30 16:34:53.0
I now tried the change, but it seems to break seveal pieces of code, in unexpected ways. It's probably better to leave things as they are, and not introduce another rule how types are inferred. I did introduce a change that an inherited return type is used as initial approximation, so that recursion for such methods is possible, even if no explicit result type is given.
Martin  edited on  2006-10-30 16:35:14.0