Is there a generic way to hack discriminant assignment in a way that works for 
both VM and C backend (and Js backend as well if possible). I've come up with a 
solution that works for a C backend, but it fails in a VM.
    
    
    type
      Obj = object
        notKind: bool
        case kind: bool
          of true: discard
          of false: discard
    
    
    template setKind*[T, K](t: var T, kind: untyped, target: K) =
      cast[ptr K](cast[int](addr t) + offsetOf(typeof(t), kind))[] = target
    
    
    var test = Obj()
    echo test
    setKind test, kind, true
    echo test
    
    
    Run
    
    
    (notKind: false, kind: false)
    (notKind: false, kind: true)
    
    
    Run

I need this to fix another issue -
    
    
    type
      Requires {.requiresinit.} = object
        # Object MUST be a requiresinit for a reasons that are out of the scope 
of this
        # question (and the code I have to write now as well). It is a given 
requirement.
      
      Obj = object
        case kind: bool
          of true:
            req: Requires
          
          of false: discard
    
    func build(inKind: bool): Obj =
      # I need to init `Obj` with a runtime value for a discriminant, but it is 
not possible
      # because
      
      Obj(kind: inKind, req: default(Requires)) # Error: The Obj type requires 
the following fields to be initialized: req.
      
      Obj(kind: inKind, req: default(Requires)) # Error: cannot prove that it's 
safe to initialize 'req' with the runtime value for the discriminator 'kind'
      
      # I'm cornered by 'requires init' and 'cannot change discriminant', so I 
need hack around this
      # limitation using
      setKind(result, kind, inKind)
      if result.kind == true:
        result.req = default(Requires)
      
      # Which is possible on a C backend, not on other ones.
    
    
    Run

Reply via email to