Protecting a lazy value only from inside the class

The implementation above did not allow multiple definitions with the implicit Post calling one another. Here is a fixed implementation that still uses ambiguity slightly differently with the help of shapeless’s LowPriority:

Generic solution

trait PostConstruction
object PostConstruction {
  implicit def ev(implicit lp : shapeless.LowPriority) : PostConstruction = new PostConstruction {}
}

trait HasPostConstructionOnlyMembers {
  @scala.annotation.implicitAmbiguous("This is a post-construction definition only!")
  final protected implicit def __PostConstruction1(implicit lp : shapeless.LowPriority) : PostConstruction = new PostConstruction {}
  final protected implicit def __PostConstruction2(implicit lp : shapeless.LowPriority) : PostConstruction = new PostConstruction {}
}

Library

class DSLClass extends HasPostConstructionOnlyMembers  {
  private lazy val runOncePostConstruction : Int = 0 //Do something here
  protected def post1(implicit p : PostConstruction) : Int = runOncePostConstruction 
  def post2(implicit p : PostConstruction) : Int = post1
}

User code

new DSLClass{}.post2 //compiles
new DSLClass{post1} //error: This is a post-construction definition only!
new DSLClass{post2} //error: This is a post-construction definition only!