score:0

Accepted answer

If you want scalac to show an error at compile time when a wrong Feature is supplied, AND you cannot alter anything other than Service1 then it is not possible. The compiler accepts or rejects a call to Service1.containsFeature based on its interface, but its interface is already defined in Service where it says that it will accept any Feature.

If you CAN change things about the other code, there are some ways to do this. For instance if you can change everything:

scala> :paste
// Entering paste mode (ctrl-D to finish)

abstract class Service[Allowed <: Feature] {
  def containsFeatures(x: Allowed*): Unit
} 

object Service1 extends Service[S1Feature] {
  def containsFeatures(x: S1Feature*): Unit = println("ok")
}

object Service2 extends Service[S2Feature] {
  def containsFeatures(x: S2Feature*): Unit = println("ok")
}

sealed trait Feature
sealed trait S1Feature extends Feature
sealed trait S2Feature extends Feature

case object A extends S1Feature
case object B extends S2Feature
case object C extends S1Feature
case object D extends S2Feature
case object E extends S1Feature
case object F extends S2Feature
case object G extends S1Feature

// Exiting paste mode, now interpreting.

scala> Service1.containsFeatures(A,B,C)
<console>:16: error: type mismatch;
 found   : B.type
 required: S1Feature
       Service1.containsFeatures(A,B,C)
                                   ^

scala> Service1.containsFeatures(A,C,G)
ok

Related Query

More Query from same tag