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

Invoking generic procedure that uses varargs implicit conversion acts incorrectly #11154

Open
SolitudeSF opened this issue May 1, 2019 · 3 comments

Comments

@SolitudeSF
Copy link
Contributor

SolitudeSF commented May 1, 2019

Invoking generic procedure that uses varargs implicit conversion breaks.

Example

a.nim

proc convert(arg: HSlice): string = discard

proc implicitConvert(args: varargs[string, convert]) = discard

proc test*(range: HSlice) = implicitConvert range

b.nim

import a

test 0..1

Current Output

a.nim(1, 6) Hint: 'convert' is declared but not used [XDeclaredButNotUsed]
b.nim(3, 6) template/generic instantiation of `test` from here
a.nim(3, 44) Error: undeclared identifier: 'convert'

Expected Output

Should compile.

Additional Information

Adding explicit generic parameters to HSlice in test proc makes program compile.

Nim Compiler Version 0.19.9 [Linux: amd64]
Compiled at 2019-05-01
@disruptek
Copy link
Contributor

Adding a call to test() inside a.nim causes it to compile and run correctly.

@krux02
Copy link
Contributor

krux02 commented May 1, 2019

At first sight I thought this would be the same thing as #11155, but it isn't. The convert symbol is resolved in test, which is defined in a.nim, a totally valid context to use the unexported convert function.

Btw a non generic version of test will make this example compile.

proc convert(arg: HSlice): string = discard

proc implicitConvert(args: varargs[string, convert]) = discard

# non generic version of ``test``
proc test*(arg: HSlice[int,int]) =
  implicitConvert(arg)

@maxtidev
Copy link

maxtidev commented May 7, 2024

Any leads on how to address this? I seem to be suffering from the same or a similar issue.

My error

Expression: select(dbConn, relatedEntries, sqlCondition, oneEntry.id)
  [1] dbConn: DbConn
  [2] relatedEntries: seq[Player]
  [3] sqlCondition: string
  [4] oneEntry.id: int64

Expected one of (first mismatch at [position]):
[1] proc select[T: Model](dbHandler; colName: string; value: string): Option[T]
[2] proc select[T: Model](dbConn; obj: var T; cond: string;
                      params: varargs[DbValue, dbValue])
[4] proc select[T: Model](dbConn; objs: var seq[T]; cond: string;
                      params: varargs[DbValue, dbValue])

dbValue should convert int64 to DbValue but the compiler doesn't agree.
select is being called in a generic proc inside a module (norm/postgres.nim#L527 ). I import this module and call this generic proc with my own generic proc:

proc selectOneToMany*[O: Model, T: Model](dbHandler; oneEntry: O): Option[seq[T]] =
    var objs = @[
        when T is Lobby: newLobby()
        elif T is Player: newPlayer()
        elif T is Game: newGame()
        elif T is Participation: newParticipation()]
    try:
        dbHandler.dbConn.selectOneToMany[:O, T](oneEntry, objs)
    except NotFoundError:
        return none(seq[T])

    result = some(objs)

Edit:
Adding an unused non-generic call to the generic proc makes it compile correctly.
Exporting the conversion proc also does.

My work-around

either

proc selectOneToManyShunt(dbHandler) =
    ## this proc is never used and exists solely to please the compiler
    var arg = @[newPlayer()]
    dbHandler.dbConn.selectOneToMany(newLobby(), arg)

or right after imports

export dbValue

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

6 participants