nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.54k stars 1.47k forks source link

Array type alias indexed via a type class can cause infinite recursion in the compiler #13184

Open refi64 opened 4 years ago

refi64 commented 4 years ago

I don't even know how to describe this, it's pretty weird:

Example

type
  TypeClass = uint | enum | int
  ArrayAlias[I: TypeClass] = array[I, int]

proc test[I: TypeClass](points: ArrayAlias[I]) =
  discard

Current Output

Hint: used config file '/var/home/ryan/code/Nim/config/nim.cfg' [Conf]
Hint: used config file '/var/home/ryan/code/Nim/config/config.nims' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: tst [Processing]
Traceback (most recent call last)
/var/home/ryan/code/Nim/compiler/nim.nim(118) nim
/var/home/ryan/code/Nim/compiler/nim.nim(95) handleCmdLine
/var/home/ryan/code/Nim/compiler/cmdlinehelper.nim(98) loadConfigsAndRunMainCommand
/var/home/ryan/code/Nim/compiler/main.nim(189) mainCommand
/var/home/ryan/code/Nim/compiler/main.nim(92) commandCompileToC
/var/home/ryan/code/Nim/compiler/modules.nim(142) compileProject
/var/home/ryan/code/Nim/compiler/modules.nim(83) compileModule
/var/home/ryan/code/Nim/compiler/passes.nim(213) processModule
/var/home/ryan/code/Nim/compiler/passes.nim(86) processTopLevelStmt
/var/home/ryan/code/Nim/compiler/sem.nim(600) myProcess
/var/home/ryan/code/Nim/compiler/sem.nim(568) semStmtAndGenerateGenerics
/var/home/ryan/code/Nim/compiler/semstmts.nim(2240) semStmt
/var/home/ryan/code/Nim/compiler/semexprs.nim(986) semExprNoType
/var/home/ryan/code/Nim/compiler/semexprs.nim(2758) semExpr
/var/home/ryan/code/Nim/compiler/semstmts.nim(2016) semProc
/var/home/ryan/code/Nim/compiler/semstmts.nim(1830) semProcAux
/var/home/ryan/code/Nim/compiler/semstmts.nim(1365) semParamList
/var/home/ryan/code/Nim/compiler/semtypes.nim(1188) semProcTypeNode
/var/home/ryan/code/Nim/compiler/semtypes.nim(1144) semParamType
/var/home/ryan/code/Nim/compiler/semtypes.nim(1743) semTypeNode
/var/home/ryan/code/Nim/compiler/semtypes.nim(1410) semGeneric
/var/home/ryan/code/Nim/compiler/sigmatch.nim(2520) matches
/var/home/ryan/code/Nim/compiler/sigmatch.nim(2458) matchesAux
/var/home/ryan/code/Nim/compiler/sigmatch.nim(2169) paramTypesMatch
/var/home/ryan/code/Nim/compiler/sigmatch.nim(2013) paramTypesMatchAux
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1680) typeRel
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1086) typeRel
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1586) typeRel
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1075) typeRel
(clipped stack trace so it doesn't take up the whole issue)
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1075) typeRel
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1075) typeRel
/var/home/ryan/code/Nim/compiler/sigmatch.nim(1073) typeRel
/var/home/ryan/code/Nim/compiler/astalgo.nim(899) idTableGet
/var/home/ryan/code/Nim/compiler/astalgo.nim idTableRawGet
Error: call depth limit reached in a debug build (2000 function calls). You can change it with -d:nimCallDepthLimit=<int> but really try to avoid deep recursions instead.

Additional Information

When I originally stumbled upon this, the type class was SomeOrdinal.

I've reduced it to the type class needing to contain those three types. The two integral types can be swapped out with others and the issue will still appear, but the enum must remain in the middle to reproduce the error. Moving it to the beginning or end will result in successful compilation.

If you remove the I: TypeClass from the proc, the compilation will succeed.

If a constrained alias is not used (e.g. the proc contains the array directly in its signature), the compilation will succeed.

Nim Compiler Version 1.0.4 [Linux: amd64]
Compiled at 2019-12-11
Copyright (c) 2006-2019 by Andreas Rumpf

active boot switches: -d:release -d:useLinenoise

This is also reproducible on git master.

metagn commented 1 year ago

This now works? Maybe a more complex test case is needed now?