Skip to content

Generic converters limited to one type at a time #19517

Closed
@Nekroze

Description

@Nekroze

Using the same generic converter with different types in one line like an argument list only automatically uses the converter for the first instance.

Noticed this when making a generic wrapping container type that I wanted to be usable as the type it contained using a converter which works but not when using multiple at once as args like in the following demonstration.

Example

type thing [T] = object
  value: T

converter asValue[T](o: thing[T]): T =
  o.value

proc mycall(num, num2: int) =
  echo ($(num.type) & " | " & $(num2.type))

proc mycall(num: int, str: string) =
  echo ($(num.type) & " | " & $(str.type))

mycall( # This call uses asValue[int] converter automatically fine
  thing[int](value: 1),
  thing[int](value: 42),
)

mycall( # This gives a type error as if the converter was not defined and I tried to pass in a thing directly
  thing[int](value: 2),
  thing[string](value: "foo"),
)

mycall( # This can be fixed by calling the converter explicitly for everything but the first use
  thing[int](value: 2),
  thing[string](value: "foo").asValue,
)

Current Output

Error: type mismatch: got <thing[system.int], thing[system.string]>
but expected one of:
proc mycall(num, num2: int)
  first type mismatch at position: 2
  required type for num2: int
  but expression 'thing[string](value: "foo")' is of type: thing[system.string]
proc mycall(num: int; str: string)
  first type mismatch at position: 2
  required type for str: string
  but expression 'thing[string](value: "foo")' is of type: thing[system.string]

expression: mycall(thing[int](value: 2), thing[string](value: "foo"))

Expected Output

int | int
int | string
int | string

Additional Information

Using named arguments and reordering has no effect, whatever uses the converter first finds it by inference, after that it any other use of the converter by other types must be explicit in that call, subsequent calls seem fine. I also found it could be oddly inferred again by providing a more strongly version of the converter alongside the existing one in the example, however this kinda defeats the purpose of using a generic.

converter asValue[T: string](o: thing[T]): T =
  o.value

This is my daily driver nim compiler:

Nim Compiler Version 1.6.2 [Linux: amd64]
Compiled at 2021-12-17
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

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