Skip to content

undefined behavior when passing a generic with auto-return to a proc #16906

Open
@timotheecour

Description

@timotheecour

Example 1

(EDIT: consequence of Example 3)
sugar.=> doesn't work well with void return type

when true:
  import sugar
  proc bar4(f: int -> int) = discard
  bar4(x => x) # ok

  proc bar5(f: int -> void) = discard
  bar5(x => (discard)) # bug: error
  # bar5(x => echo x) # ditto
  # bar5((x: int) => (discard)) # workaround: works

Current Output

t11794.nim(11, 7) Error: type mismatch: got <proc (x: GenericParam): untyped>
but expected one of:
proc bar5(f: int -> void) [proc declared in t11794.nim(10, 8)]
  first type mismatch at position: 1
  required type for f: proc (i0: int){.closure.} [proc]
  but expression 'proc (x: auto): auto =
  discard' is of type: proc (x: GenericParam): untyped [proc]

expression: bar5(proc (x: auto): auto =
  discard )
    bar5(x => (discard)) # bug: error

Expected Output

works

Example 2

in above example, the error mentions proc (x: GenericParam): untyped, which is suspicious (proc can't have untyped return type).

Example 3: undefined behavior

(added this after further investigation)
this example is more troubling, and shows what's probably the root cause for all examples here:
when passing a generic with auto-return type to a proc, the generic return type is implicitly cast to the return type of the param instead of instantiating the generic and type-checking the return type against the param return type.

This results in undefined behavior:

when true:
  proc bar(f: proc(a: string): (float, float)): (float, float) = f("abc")
  proc fun(x: string or int8): auto = x
  # proc fun[T](x: T): auto = x # ditto
  # proc fun(x: auto): auto = x # ditto
  # proc fun(x: string): auto = x # would correctly give CT error
  echo bar(fun) # prints stack garbage (0.0, 3.237859210020609e-319)
  echo bar(fun) # prints (0.0, 0.0)

Additional Information

1.5.1 91ace21
/cc @hlaaftana

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions