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

Template findFirst fails to compile, proc with same code works fine #19576

Closed
gryphis opened this issue Mar 1, 2022 · 2 comments · Fixed by #22535
Closed

Template findFirst fails to compile, proc with same code works fine #19576

gryphis opened this issue Mar 1, 2022 · 2 comments · Fixed by #22535

Comments

@gryphis
Copy link

gryphis commented Mar 1, 2022

Hi
I wrote a template findFirst() to find the first element in a seq[T] which fulfills a predicate - minimal source attached.
Compilation of template code raises:

$ nim c -r nimbug.nim 
Hint: used config file '.../.choosenim/toolchains/nim-1.6.4/config/nim.cfg' [Conf]
Hint: used config file '.../.choosenim/toolchains/nim-1.6.4/config/config.nims' [Conf]
.............................................................
.../nimbug.nim(31, 21) template/generic instantiation of `findFirst` from here
.../nimbug.nim(16, 18) Error: type mismatch: got <RegistryKey>
but expected one of:
proc none(T: typedesc): Option[T]
  first type mismatch at position: 1
  required type for T: typedesc
  but expression 'T' is of type: RegistryKey
proc none[T](): Option[T]
  first type mismatch at position: 1
  extra argument given

expression: none(T)

If template code is copied to a "proc" and all "T" replaced by "RegistryKey" (the type), it works well. You can simply check that by changing a const "failure" in the source.

I work with nim-1.6.4

Thanks for help!

Source:
nimbug.zip

@beef331
Copy link
Collaborator

beef331 commented Mar 2, 2022

Well there are two issues here, the generic none(T) and also the using result inside a template, templates do not have result, so the above code is not proper. Slight work around ahead.

import options

type
  RegistryKey = object
    key : string
    val : string
var regKey = @[
  RegistryKey(key:"ica.sflogin.debug", val:"true"),
]
template findFirst[T](s: seq[T], pred: proc(x: T): bool): Option[T] =
  var res = none(typeof T)  # if no items satisfy the predicate
  for x in s:
    if pred(x):
      res = some(x)
      break
  res

proc getval(searchKey: string): Option[string] =
  let found = regKey.findFirst(proc (rk: RegistryKey): bool = rk.key == searchKey)
  if found.isNone: none(string)
  else: some(found.get().val)

when isMainModule:
  assert(getval("strange") == none(string))
  assert(getval("ica.sflogin.debug") == some("true"))

@gryphis
Copy link
Author

gryphis commented Mar 2, 2022 via email

metagn added a commit to metagn/Nim that referenced this issue Aug 23, 2023
metagn added a commit to metagn/Nim that referenced this issue Aug 25, 2023
@Araq Araq closed this as completed in 1cc4d3f Aug 25, 2023
narimiran pushed a commit that referenced this issue Dec 1, 2023
* fix generic param substitution in templates

fixes #13527, fixes #17240, fixes #6340, fixes #20033, fixes #19576, fixes #19076

* fix bare except in test, test updated packages in CI

(cherry picked from commit 1cc4d3f)
narimiran pushed a commit that referenced this issue Dec 1, 2023
* fix generic param substitution in templates

fixes #13527, fixes #17240, fixes #6340, fixes #20033, fixes #19576, fixes #19076

* fix bare except in test, test updated packages in CI

(cherry picked from commit 1cc4d3f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants