These might be workarounds and/or opportunities for compiler enhancement. A 
pure alias doesn't respect `requiresInit` itself, though maybe that could be 
changed. A distinct wrapper does work if you don't mind that. Unfortunately 
converting `FooBarImpl` to `FooBarO` doesn't seem to work, though that seems 
like it might be the cleanest solution if it did.
    
    
    # foo.nim
    type Foo* {.requiresInit.} = object of RootObj
      foo: int
    proc newFoo*[F:Foo=Foo](f: int): F = F(foo: f)
    
    # bar.nim
    import foo
    
    type FooBarImpl = object of Foo
      bar: int
    type FooBar* {.requiresInit.} = FooBarImpl
    type FooBarD* {.requiresInit.} = distinct FooBarImpl
    type FooBarC* {.requiresInit.} = distinct FooBarImpl
    converter toFooBarImpl*(x: FooBarC): FooBarImpl = FooBarImpl(x)
    type FooBarO* {.requiresInit.} = object of FooBarImpl
    
    proc newFooBar*(f: int, b: int): FooBar =
      var r = newFoo[FooBarImpl](f)
      r.bar = b
      result = FooBar(r)
    
    proc newFooBarD*(f: int, b: int): FooBarD =
      var r = newFoo[FooBarImpl](f)
      r.bar = b
      result = FooBarD(r)
    
    proc newFooBarC*(f: int, b: int): FooBarC =
      var r = newFoo[FooBarImpl](f)
      r.bar = b
      result = FooBarC(r)
    
    proc newFooBarO*(f: int, b: int): FooBarO =
      var r = newFoo[FooBarImpl](f)
      r.bar = b
      result = FooBarO(r)
    
    # baz.nim
    import bar
    
    block:
      var x = newFooBar(1, 2)
      echo x
      #var y: FooBar  # fails due to Foo not FooBar
    
    block:
      var x = newFooBarD(1, 2)
      # echo x  # need to borrow
      # var y: FooBarD  # not allowed
    
    block:
      var x = newFooBarC(1, 2)
      echo x
      # var y: FooBarC  # not allowed
    
    block: discard
      # var x = newFooBarO(1, 2)  # invalid object conversion
    
    
    Run

Reply via email to