That error's from compiler/lowerings.nim , where we find this test for flowVars:
    
    
    proc flowVarKind(t: PType): TFlowVarKind =
      if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC
      elif containsGarbageCollectedRef(t): fvInvalid
      else: fvBlob
    
    
    Run

In English: strings are OK. seqs are OK. Refs are OK. Anything not containing a 
GC'd thing is not OK.

So what are Option[string]s? To simplify the code in lib/pure/options.nim 
slightly,
    
    
    type
      Option*[T] = object
        val: T
        has: bool
    
    
    Run

Options are objects. They are, critically, not _ref Objects_. And they contain 
strings, which are GC 'd. So they get classified as fvInvalid

Here's some slightly long code that duplicates sufficient code from 
lib/pure/options.nim to run the example, while using ref options so that the 
example actually works:
    
    
    import strformat, threadpool
    
    import typetraits
    
    type
      SomePointer = ref | ptr | pointer
    
    type
      OptionObj*[T] = object
        when T is SomePointer:
          val: T
        else:
          val: T
          has: bool
      Option[T] = ref OptionObj[T]
    
    proc some*[T](val: T): Option[T] =
      when T is SomePointer:
        assert(not val.isNil)
        new(result)
        result.val = val
      else:
        new(result)
        result.has = true
        result.val = val
    
    proc none*[T]: Option[T] =
      new(result)
      when T isnot SomePointer:
        result.has = false
    
    proc get*[T](self: Option[T]): T =
      if self.isNone:
        raise newException(UnpackError, "Can't obtain a value from a `none`")
      self.val
    
    proc isSome*[T](self: Option[T]): bool {.inline.} =
      when T is SomePointer:
        result = not self.val.isNil
      else:
        result = self.has
    
    proc readLineSafe(): Option[string] =
      try: return some(stdin.readLine()) except EOFError: return none[string]()
    
    while true:
      let message = spawn readLineSafe()
      let input = ^message
      if input.isSome:
        echo &"Sending \"{input.val}\""
      else: break
    
    
    Run

Reply via email to