Description
Forward declarations for procedures with a generic constraint don't work always. For some constraints it does work, for other constraints it does not work. Here is a list of constraints that I tested. I don't know if there are other corner cases that I did not cover.
Example
# SomeInteger (OK)
proc foo[T : SomeInteger](arg: T)
proc foo[T : SomeInteger](arg: T) =
echo "hello some integer"
foo(123)
foo(123'u8)
# range (OK)
proc foo2[T : range[0..100]](arg: T)
proc foo2[T : range[0..100]](arg: T) =
echo "hello range"
foo2(7)
# tuple (OK)
proc foo3[T : tuple](arg: T)
proc foo3[T : tuple](arg: T) =
echo "hello tuple"
foo3((a:123,b:321))
# seq (OK)
proc foo4[T: seq](arg: T)
proc foo4[T: seq](arg: T) =
echo "hello seq"
foo4(@[1,2,3])
# object (broken)
proc foo5[T : object](arg: T)
proc foo5[T : object](arg: T) =
echo "hello object"
type MyType = object
var mt: MyType
foo5(mt)
# distinct (broken)
proc foo6[T : distinct](arg: T)
proc foo6[T : distinct](arg: T) =
echo "hello distinct"
type MyDistinct = distinct string
var md: MyDistinct
foo6(md)
# enum (broken)
proc foo7[T : enum](arg: T)
proc foo7[T : enum](arg: T) =
echo "hello enum"
type MyEnum = enum
ValueA
foo7(ValueA)
Current Output
/tmp/scratch.nim(40, 5) Error: ambiguous call; both scratch.foo5(arg: T: object) [declared in /tmp/scratch.nim(34, 6)] and scratch.foo5(arg: T: object) [declared in /tmp/scratch.nim(35, 6)] match for: (MyType)
/tmp/scratch.nim(44, 6) Error: implementation of 'scratch.foo6(arg: T: distinct) [declared in /tmp/scratch.nim(44, 6)]' expected
/tmp/scratch.nim(50, 5) Error: ambiguous call; both scratch.foo6(arg: T: distinct) [declared in /tmp/scratch.nim(44, 6)] and scratch.foo6(arg: T: distinct) [declared in /tmp/scratch.nim(45, 6)] match for: (MyDistinct)
/tmp/scratch.nim(54, 6) Error: implementation of 'scratch.foo7(arg: T: enum) [declared in /tmp/scratch.nim(54, 6)]' expected
/tmp/scratch.nim(60, 5) Error: ambiguous call; both scratch.foo7(arg: T: enum) [declared in /tmp/scratch.nim(54, 6)] and scratch.foo7(arg: T: enum) [declared in /tmp/scratch.nim(55, 6)] match for: (MyEnum)
/tmp/scratch.nim(54, 6) Error: implementation of 'scratch.foo7(arg: T: enum) [declared in /tmp/scratch.nim(54, 6)]' expected
This is not the real output of nim check. This is the accumulated output of several calls to nim check. For some reason Nim check only reports two error messages. I have to comment to see more errors.
Expected Output
Nim check should not complain with errors.
hello some integer
hello range
hello tuple
hello seq
hello object
hello distinct
hello enum
Additional Information
I my PR #12391, I wanted to use forward declarations of assignFromJson
. This bug prevents me from doing so. The alternative was to make assignFromJson
public, which for some unknown reason made it work. Where is the specification that defines this different behavior of symbol resolution for exported vs non-exported symbols?