Search code examples
scalamixinsselfcompanion-object

How to mix in self annotations in companion object


Consider the following situation:

trait  M { } // uses N
object M { def apply = new M { } }
trait  N { self: L =>  }
trait  L { val m: B }
type   B

M needs new trees definitions that are created in N. I don't want to pass around these new trees because the class hierarchy is in fact very long and would result in modifying a lot the code. Instead I was proposed to do:

trait  M { self: N with L => } // uses N
object M { def apply = new M with N with L { } }
trait  N { self: L => }
trait  L { val m: B }
type   B

but then I get error:

object creation impossible, since value m in trait L of type B is not defined

this is coming from the definition of object M. I have tried different combinations and none works.

How can I solve this error?

Discussion

I learn that when writing new M {} I get an anonymous class extending (object??) M, so I tried modifying to new M with N with L {} but then I get the error of unimplemented members from L.

References

You may find more details on the problem on this commit. Namely, type M is MeasureAnnotation, N is StructuralSize and L is SolverProvider.

If you want to build the program you should git clone and then run sbt followed by universal:stage. You need to have installed z3 or cvc4.


Solution

  • I think your code snippet does not accurately reflect your actual commit. In your commit you used a self type on the object, too, which does not make sense. A self-type on a trait describes a requirement that concrete instances mixing in this trait must satisfy. However, an object is already a concrete type, so there is no point in defining further requirements.

    In short: do not repeat the self-type from a trait on its companion object.