Nim icon indicating copy to clipboard operation
Nim copied to clipboard

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

Open stoneface86 opened this issue 10 months ago • 4 comments

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

stoneface86 avatar Apr 10 '24 03:04 stoneface86

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

ringabout avatar Apr 10 '24 03:04 ringabout

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

Araq avatar Apr 10 '24 08:04 Araq

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)

beef331 avatar Apr 10 '24 09:04 beef331

sameBackendType should return true for array types (with the same element type) that have the same length regardless of index type. Currently it's not special cased.

Compilation should also error from the type mismatch, but as pointed out in the comment above, there's still an issue in the backend.

metagn avatar Oct 07 '24 03:10 metagn