question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compiler accepts class as non-abstract, then runtime system fails saying the class is abstract

See original GitHub issue

Compiler version

3.0.1

Minimized code

import scala.collection.mutable.Builder

class DDD[S,T,A]

trait NN[S, T, A, K[_], +D <: DDD[Set[S],T,K[A]]]
class NNN[S, T, K[_], A] extends NN[S, T, A, K, DDD[Set[S],T,K[A]]]

object NN {
  def newBuilder[S, T, A, K[_]]:
      NNbuilder[S, T, K, A, DDD[Set[S],T,K[A]], NN[S,T,A,K,?], Unit] =
    new NNNbuilder[S, T, K, A]
}

// Remove the type parameter E, hardcoding in E := Unit, and the issue
// goes away.
trait NNbuilder
  [S, T, K[_], A, +D <: DDD[Set[S],T,K[A]], +N <: NN[S,T,A,K,D], E]
    extends Builder[Unit, N] {
  def clear(): Unit = throw new UnsupportedOperationException()
  final def addOne(builder: E): this.type = this
}

// Unfold this class defn, and the issue goes away
abstract class AbstractNNNbuilder
  [S, T, K[_], A, +D <: DDD[Set[S],T,K[A]], +N <: NN[S,T,A,K,D], E]
    extends NNbuilder[S,T,K,A,D,N,E]

class NNNbuilder[S, T, K[_], A] extends AbstractNNNbuilder[
  S, T, K, A, DDD[Set[S], T, K[A]], NNN[S, T, K, A], Unit
] {
  override def result(): NNN[S, T, K, A] = new NNN[S, T, K, A]
}

@main def run: Unit = {
  val builder = NN.newBuilder[String, Char, Int, Set]
  builder += ()
  builder.result()
}

Output (from sbt)

[info] compiling 1 Scala source to /home/jm/Lib/Scala/scratch/target/scala-3.0.1/classes ...
[info] done compiling
[info] running run 
[error] (run-main-56) java.lang.AbstractMethodError: Receiver class NNNbuilder does not define or inherit an implementation of the resolved method 'abstract scala.collection.mutable.Growable addOne(java.lang.Object)' of interface scala.collection.mutable.Growable.
[error] java.lang.AbstractMethodError: Receiver class NNNbuilder does not define or inherit an implementation of the resolved method 'abstract scala.collection.mutable.Growable addOne(java.lang.Object)' of interface scala.collection.mutable.Growable.
[error] 	at scala.collection.mutable.Growable.$plus$eq(Growable.scala:36)
[error] 	at scala.collection.mutable.Growable.$plus$eq$(Growable.scala:36)
[error] 	at AbstractNNNbuilder.$plus$eq(Main.scala:29)
[error] 	at Main$package$.run(Main.scala:45)
[error] 	at run.main(Main.scala:43)
[error] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
[error] 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[error] stack trace is suppressed; run last Compile / bgRun for the full output
[error] Nonzero exit code: 1

Expectation

The compiler and RTS should agree that class NNNbuilder is not abstract.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
smartercommented, Jul 15, 2021

Fascinating. Looks like Scala 2 has the same issue (had to replace ? by _ and drop an explicit result type to get it to compile): https://scastie.scala-lang.org/124mRu2nRkCaLeoqGRJreQ, could you report the issue at https://github.com/scala/bug/issues too? Hopefully they can figure it out so I don’t have to 😁.

1reaction
jphmrstcommented, Jul 15, 2021

You wrote object Main extends App { def main = ... }, this won’t execute the code in the main method, if using extends App, only the code written directly in the object outside of a def will be executed, you can also drop the extends App and use def main(args: Array[String]): Unit as in https://scastie.scala-lang.org/124mRu2nRkCaLeoqGRJreQ

Ah sorry — I’m already not used to version 2 anymore!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why no compiler error when I cast a class to an interface it ...
In .Net, a class may inherit from only one base class but may implement any number of interfaces. class Program { abstract ......
Read more >
Suggestion: abstract classes #6 - microsoft/TypeScript - GitHub
I would say prevent directly instantiating abstract classes at compile time. Otherwise let it be a run time error. It works the same...
Read more >
Can We Instantiate an Abstract Class in Java? - GeeksforGeeks
Abstract class, we have heard that abstract class are classes which can have abstract methods and it can't be instantiated.
Read more >
Abstract Class in Java with example - BeginnersBook
A class that is declared using “abstract” keyword is known as abstract class. It can have abstract methods(methods without body) as well as...
Read more >
When to Use TypeScript Abstract Classes | Khalil Stemmler
You could also say that abstraction allows us to spend more time on the declarative (asking for what we want) and less on...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found