Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic converters limited to one type at a time #19517

Open
Nekroze opened this issue Feb 12, 2022 · 0 comments
Open

Generic converters limited to one type at a time #19517

Nekroze opened this issue Feb 12, 2022 · 0 comments

Comments

@Nekroze
Copy link

Nekroze commented Feb 12, 2022

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants