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.23k stars 1.46k forks source link

2.0 C compilation error when using seq of array with enum indices #23489

Open stoneface86 opened 2 months ago

stoneface86 commented 2 months ago

Description

The following nim code results in an error when compiling the generated C code:

type
  ChannelId = enum
    ch1, ch2, ch3, ch4

  OrderRow = array[ChannelId, uint8]
  Order = seq[OrderRow]

func test(o: Order) =
  discard

let order = @[ [0u8, 0, 0, 0], [1u8, 1, 1, 1] ]
test(order)

The generated C code fails to compile when using Nim 2.0.0 or 2.0.2, Nim 1.6.16 results in no errors whatsoever.

Nim Version

Nim Compiler Version 2.0.0 [Linux: amd64] Compiled at 2023-08-01 Copyright (c) 2006-2023 by Andreas Rumpf

git hash: a488067a4130f029000be4550a0fb1b39e0e9e7c active boot switches: -d:release

Current Output

nim r issue.nim
Hint: used config file '/home/bit/.choosenim/toolchains/nim-2.0.0/config/nim.cfg' [Conf]
Hint: used config file '/home/bit/.choosenim/toolchains/nim-2.0.0/config/config.nims' [Conf]
Hint: used config file '/home/bit/.config/nim/config.nims' [Conf]
......................................................................
CC: ../../home/bit/.choosenim/toolchains/nim-2.0.0/lib/system/exceptions.nim
CC: ../../home/bit/.choosenim/toolchains/nim-2.0.0/lib/std/private/digitsutils.nim
CC: ../../home/bit/.choosenim/toolchains/nim-2.0.0/lib/system/dollars.nim
CC: ../../home/bit/.choosenim/toolchains/nim-2.0.0/lib/system.nim
CC: issue.nim
/mnt/ramdisk/nimcache/2.0.0/d/issue/@missue.nim.c: In function ‘NimMainModule’:
/mnt/ramdisk/nimcache/2.0.0/d/issue/@missue.nim.c:164:25: error: incompatible type for argument 1 of ‘test__issue_u11’
  164 |         test__issue_u11(order__issue_u17);
      |                         ^~~~~~~~~~~~~~~~
      |                         |
      |                         tySequence__atzPT9bqVZh26epu1UBlGdg
/mnt/ramdisk/nimcache/2.0.0/d/issue/@missue.nim.c:101:84: note: expected ‘tySequence__puy72L9c7VseAknjAniYCWg’ but argument is of type ‘tySequence__atzPT9bqVZh26epu1UBlGdg’
  101 | N_LIB_PRIVATE N_NIMCALL(void, test__issue_u11)(tySequence__puy72L9c7VseAknjAniYCWg o_p0) {
      |                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
Error: execution of an external compiler program 'gcc -c  -w -fmax-errors=3 -pthread   -I/home/bit/.choosenim/toolchains/nim-2.0.0/lib -I/mnt/ramdisk -o /mnt/ramdisk/nimcache/2.0.0/d/issue/@missue.nim.c.o /mnt/ramdisk/nimcache/2.0.0/d/issue/@missue.nim.c' failed with exit code: 1

Expected Output

# when compiling with nim 1.6.16
nim r issue.nim
Hint: used config file '/home/bit/.choosenim/toolchains/nim-1.6.16/config/nim.cfg' [Conf]
Hint: used config file '/home/bit/.choosenim/toolchains/nim-1.6.16/config/config.nims' [Conf]
Hint: used config file '/home/bit/.config/nim/config.nims' [Conf]
..........................................................
CC: issue.nim
Hint:  [Link]
Hint: gc: refc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
50844 lines; 0.145s; 61.125MiB peakmem; proj: /mnt/ramdisk/issue.nim; out: /mnt/ramdisk/nimcache/1.6.16/d/issue/issue_4A2D8CE6202E3A7174E40689BBC6A80A83C99581 [SuccessX]
Hint: /mnt/ramdisk/nimcache/1.6.16/d/issue/issue_4A2D8CE6202E3A7174E40689BBC6A80A83C99581  [Exec]

Possible Solution

Should this be a nim compile error? In the example, the type of order is seq[array[0..3, uint8]], however, the type of Order is seq[array[ChannelId, uint8]], which I believe is what results in two instances of seq being generated in the C code.

Additional Information

Declaring order as type Order in the let statement does not result in any error.

This might be an ARC/ORC issue: compiling with --mm:arc or --mm:orc on 1.6.16 also results in the same error

ringabout commented 2 months ago

Related: https://github.com/nim-lang/Nim/issues/19374

Araq commented 2 months ago

This should not be allowed by the compiler, the types are not compatible.

beef331 commented 2 months ago

There is a type bug here. Even if one corrects the arrays, incorrect C is generated unless one explicitly converts to a type alias.

type
  ChannelId = enum
    ch1, ch2, ch3, ch4

  OrderRow = array[ChannelId, uint8]
  Order = seq[OrderRow]

let order = @[ [ch1: 0u8, 0, 0, 0], [ch1: 1u8, 1, 1, 1]  ]#.Order # Explicitly converting stops the cgen error
static: assert order is Order

proc test(_: Order) = discard
test(order)