I'm wrapping C code that returns owned cstring.

If I convert wrapped distinct cstring type to nim string, destructor is not 
called. If I return distinct cstring type, destructor is called.
    
    
    {.
      emit: [
        """
    
    char *allocCString() {
        char *result = malloc(10 + 1);
        strcpy(result, "HelloWorld");
        return result;
    }
    
    """
      ]
    .}
    
    proc rawWrapper(): cstring {.importc: "allocCString", cdecl.}
    
    # -------------------------
    
    type OwnedString = distinct cstring
    
    proc `=destroy`(s: OwnedString) =
      dealloc(s.cstring)
      echo "Deallocating OwnedString"
    
    func `$`(s: OwnedString): string {.borrow.}
    
    proc idiomaticWrapper(): OwnedString =
      rawWrapper().OwnedString
    
    proc leakyWrapper(): string =
      let ostring = rawWrapper().OwnedString
      $ostring
    
    # -------------------------
    
    proc main() =
      when true:
        # destructor not called - definitely lost: 11 bytes in 1 blocks
        # doesn't leak with --cursorInference:off
        let s = leakyWrapper()
      else:
        # destructor called - All heap blocks were freed -- no leaks are 
possible
        let s = idiomaticWrapper()
      echo s
    
    main()
    
    
    
    Run
    
    
    --expandArc: leakyWrapper
    
    var ostring_cursor
    ostring_cursor = OwnedString(rawWrapper())
    result = $ostring_cursor
    -- end of expandArc ------------------------
    
    
    Run

could you please explain what is happening here? if `$` generates a copy, why 
ARC is not adding destructor call?

Reply via email to