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

add a procedure with the same name as a generic template and then calling this generic template from a generic identifier, compilation gives error #19737

Closed
rockcavera opened this issue Apr 21, 2022 · 1 comment · Fixed by #23988

Comments

@rockcavera
Copy link
Contributor

rockcavera commented Apr 21, 2022

When a procedure with the same name as a generic template is added and then this generic template is called from a generic identifier, the compilation gives an error.

Example

# myint128.nim
type
  UInt128* = object
    lo, hi: uint64

func `<`*(x, y: UInt128): bool =
  (x.hi < y.hi) or ((x.hi == y.hi) and (x.lo < y.lo))

when not defined(works):
  func `>`*(x, y: UInt128): bool =
    (x.hi > y.hi) or ((x.hi == y.hi) and (x.lo > y.lo))
# bug.nim
import ./myint128

var m: seq[uint64]

proc test[T: uint64|uint32](s: var seq[T]) =
  var tmp = newSeq[T](1)
  s = newSeq[T](1)

  echo s[0] > tmp[0]

test(m)

Current Output

nim c bug
Hint: used config file 'D:\Nim\config\nim.cfg' [Conf]
Hint: used config file 'D:\Nim\config\config.nims' [Conf]
..........................................................
C:\Users\josep\Desktop\bug.nim(11, 5) template/generic instantiation of `test` from here
C:\Users\josep\Desktop\bug.nim(9, 13) Error: type mismatch: got <uint64, T>
but expected one of:
proc `<`(x, y: uint64): bool
  first type mismatch at position: 2
  required type for y: uint64
  but expression 's[0]' is of type: T
21 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them

expression: tmp[0] < s[0]

Expected Output

Must compile and when run return false

Additional Information

  • The problem is present in version 1.0.0 up to the current devel.
  • if compiled with -d:works, compilation proceeds correctly as it is not declared myint128.>
@metagn
Copy link
Collaborator

metagn commented Aug 20, 2024

This might be specific to seq and UncheckedArray similar to what was encountered in #23854 and #23855

More isolated test code:

# mseq1.nim
proc foo*(x: int) = discard
template templ*(x: untyped) =
  foo(x)
# mseq2.nim
# string can be any type other than what test receives:
proc templ*(x: string) = discard
import mseq1
import mseq2

proc test[T](s: seq[T]) =
  templ s[0]

test(@[0])

I think it has to do with the use of the subscript operator

Edit: Definitely, the T in the error is the T from the definition of the subscript operator:

proc `[]`*[I: Ordinal;T](a: T; i: I): T {.noSideEffect, magic: "ArrGet".}

metagn added a commit to metagn/Nim that referenced this issue Aug 20, 2024
@Araq Araq closed this as completed in 04da0a6 Aug 22, 2024
narimiran pushed a commit that referenced this issue Dec 16, 2024
fixes #19737

As in the diff, `semResolvedCall` sets the return type of a call to a
proc to the type of the call. But in the case of the [subscript
magic](https://nim-lang.org/docs/system.html#%5B%5D%2CT%2CI), this type
is the first generic param which is also supposed to be the type of the
first argument, but this is invalid, the correct type is the element
type eventually given by `semSubscript`. Some lines above also [prevent
the subscript magics from instantiating their
params](https://github.com/nim-lang/Nim/blob/dda638c1ba985a77eac3c7518138992521884172/compiler/semcall.nim#L699)
so this type ends up being an unresolved generic param.

Since the type of the node is not `nil`, `prepareOperand` doesn't try to
type it again, and this unresolved generic param type ends up being the
final type of the node. To prevent this, we just never set the type of
the node if we encountered a subscript magic.

Maybe we could also rename the generic parameters of the subscript
magics to stuff like `DummyT`, `DummyI` if we want this to be easier to
debug in the future.

(cherry picked from commit 04da0a6)
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