Skip to content

forward declarations don't work for constrained generic procs #12416

Closed
@krux02

Description

@krux02

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions