I've got a problem calling "$" on some range type. It all looks perfectly fine to me. Atm I would tend to think it's a compiler error. Here is the simplified code: const MAX_THREADS* = 64 const MAX_TOPICS* = 1048576 const MAX_PROCESSES* = int(4294967296'i64 div int64(MAX_THREADS * MAX_TOPICS)) type ThreadID* = range[0'u8..uint8(MAX_THREADS-1)] ## Thread ID, within process. ProcessID* = range[0'u16..uint16(MAX_PROCESSES-1)] ## Process ID of thread. TopicID* = range[0'u32..uint32(MAX_TOPICS-1)] ## TopicID, within thread. proc `$` *(id: ThreadID): string {.inline.} = ## Somehow, default `$` is ambiguous. $uint8(id) proc `$` *(id: ProcessID): string {.inline.} = ## Somehow, default `$` is ambiguous. $uint16(id) proc `$` *(id: TopicID): string {.inline.} = ## Somehow, default `$` is ambiguous. $uint32(id) type QueueID* = distinct uint32 ## The complete queue ID, containing the process ID, thread ID and topic ID. proc tid*(queue: QueueID): ThreadID {.inline, noSideEffect.} = ## Dummy simplified impl! ThreadID(uint8(queue)) proc pid*(queue: QueueID): ProcessID {.inline, noSideEffect.} = ## Dummy simplified impl! ProcessID(uint16(queue)) proc cid*(queue: QueueID): TopicID {.inline, noSideEffect.} = ## Dummy simplified impl! TopicID(uint32(queue)) proc `$` *(queue: QueueID): string = ## String representation of a QueueID. let p = $pid(queue) let tt: ThreadID = tid(queue) let t = $tt # ERROR LINE let c = $cid(queue) p & "." & t & "." & c
And it fails to compile with: kueues.nim(356, 13) Error: ambiguous call; both kueues.$(id: ThreadID)[declared in kueues.nim(130, 5)] and kueues.$(id: ProcessID)[declared in kueues.nim(134, 5)] match for: (ThreadID) ThreadID is a range of uint8, and ProcessID is a range of uint16. I do not see how I could possibly be more explicit than I already am, which is IMO already "too" explicit. The original (working) code, used to look like this: const MAX_THREADS* = 64 const MAX_TOPICS* = 1048576 # ... const MAX_PROCESSES* = int(4294967296'i64 div int64(MAX_THREADS * MAX_TOPICS)) type ThreadID* = range[0..MAX_THREADS-1] ## Thread ID, within process. ProcessID* = range[0..MAX_PROCESSES-1] ## Process ID of thread. TopicID* = range[0..MAX_TOPICS-1] ## TopicID, within thread. type QueueID* = distinct uint32 ## The complete queue ID, containing the process ID, thread ID and topic ID. proc tid*(queue: QueueID): ThreadID {.inline, noSideEffect.} = ## Dummy simplified impl! ThreadID(uint8(queue)) proc pid*(queue: QueueID): ProcessID {.inline, noSideEffect.} = ## Dummy simplified impl! ProcessID(uint16(queue)) proc cid*(queue: QueueID): TopicID {.inline, noSideEffect.} = ## Dummy simplified impl! TopicID(uint32(queue)) proc `$` *(queue: QueueID): string = ## String representation of a QueueID. $pid(queue) & "." & $tid(queue) & "." & $cid(queue) Then I decided to change ThreadID, ProcessID and TopicID from range of int, to range of appropriate specific size (uint8/uint16/uint32). That is when I got the error. First I added the explicit $(ThreadID), $(ProcessID) and $(TopicID) procs and then tried to break the $(QueueID) proc into multiple steps. But I cannot get rid of the error.