The thing is I want any call to Mammal.create(e: Animal) to not compile, to enforce the user to call create(String, String) instead. I know it violates lots of stuff, but I still wonder, is it doable?
No, it is not doable because every Mammal is also an Animal. You can always “forget” you have a Mammal and treat it as an Animal and Scala will have no way to know the difference (because there isn’t any). This is a property of subtyping in general, not a Scala thing specifically.
I know all this.
But I’m still wondering if it’s possible, using som “typelevel magic”, to circumvent it for a specific overloaded method. Some mechanisme saying “Yea, I know I’m supposed to support abstract method this and that, but this implementation is different so throw an error at compile-time if someone calls this declared method on this specific subtype”.
scala> import scala.annotation.compileTimeOnly
import scala.annotation.compileTimeOnly
scala> class Mammal extends Animal {
| @compileTimeOnly("don't call this!")
| final def create(a: Animal) = ???
| }
defined class Mammal
scala> new Mammal().create(new Mammal)
^
error: don't call this!
But be warned:
scala> (new Mammal(): Animal).create(new Mammal)
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
at Mammal.create(<console>:3)
at Mammal.create(<console>:1)
... 38 elided
(BTW; This forum is horrible. My reply is shown below the wrong message, and interaction with email is a joke. Whish scala-users moved back to standard email-list, ie. mailman… Yes, I’m over 40…)