Skip to content

Classes can't have an unfulfilled self type with unimplemented methods #4252

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

Closed
allanrenucci opened this issue Apr 5, 2018 · 6 comments
Closed

Comments

@allanrenucci
Copy link
Contributor

trait Bar { def bar: Int }
class Foo { self : Bar => }
2 |class Foo { self : Bar => }
  |      ^
  |   class Foo needs to be abstract, since def bar: => Int is not defined 
one error found

It is allowed in Scalac

@Blaisorblade Blaisorblade changed the title Classes can't have an abstract self type an unimplemented methods Classes can't have an abstract self type and unimplemented methods Apr 5, 2018
@Blaisorblade
Copy link
Contributor

Indeed, instantiating such classes is forbidden later by the spec on new c where c is a constructor of class T:

Then T must denote a (a type instance of) a non-abstract subclass of scala.AnyRef. Furthermore, the concrete self type of the expression must conform to the self type of the class denoted by T.

scala> trait Bar { def bar: Int }
defined trait Bar

scala> class Foo { self : Bar => }
defined class Foo

scala> new Foo
<console>:13: error: class Foo cannot be instantiated because it does not conform to its self-type Foo with Bar
       new Foo
       ^

Not that I see the point of this behavior, but I'd default to following Scalac.

@Blaisorblade Blaisorblade changed the title Classes can't have an abstract self type and unimplemented methods Classes can't have an unfulfilled self type with unimplemented methods Apr 5, 2018
@allanrenucci
Copy link
Contributor Author

But you can instantiate it as an anonymous class or extend it:

scala> new Foo with Bar { def bar: Int = 1 }
res0: Foo with Bar = $anon$1@6002e944

scala> class Bat extends Foo with Bar { def bar: Int = 1 }
defined class Bat

scala> new Bat
res1: Bat = Bat@5dcf0772

So there is a real use case

@Blaisorblade
Copy link
Contributor

So there is a real use case

To clarify: I mean, one could just require that the class is marked abstract and support the same use cases.

@Blaisorblade
Copy link
Contributor

Gitter isn't sure either, but it seems this might have been discussed and left as-is: https://gitter.im/scala/contributors?at=5ac65cac27c509a774df5374

@smarter
Copy link
Member

smarter commented Apr 9, 2018

After discussion in the meeting, we decided to support the Scala 2 behavior under -language:Scala2, and keep the current behavior otherwise.

@griggt
Copy link
Contributor

griggt commented Oct 28, 2020

FWIW, this compiles without error since #8332, both with and without -language:Scala2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants