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

Options codegen error: ‘tyObject_Option__xxxx’ has no member named ‘has’ #21558

Open konradmb opened 1 year ago

konradmb commented 1 year ago

Description

Minimal reproduction:

import options

type
  Node[T] = ref object
    value: T
    previous: Option[Node[T]]
    next: Option[Node[T]]
  LinkedList*[T] = object ## A doubly linked list.
    first: Option[Node[T]]
    last: Option[Node[T]]

var list = LinkedList[int]()
# let qwerqwer = list.first.get.next 
# This ^ line errors on stable (1.6.12), but not on current devel 1.9.1 (f7e3af0c2d68035a649cf9449cc4e02a7ea59e84)
let newNode = Node[int](value: 0,
                      next: list.first.get.next,
                      previous: Node[int].none).some

Nim Version

Nim Compiler Version 1.9.1 [Linux: amd64] Compiled at 2023-03-21 Copyright (c) 2006-2023 by Andreas Rumpf

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

Current Output

nim r -f -r "/home/konrad/.config/VSCodium/User/globalStorage/buenon.scratchpads/scratchpads/56b8016bc5c16deae167b5cfb0a76e9f/scratch8.nim"
Hint: used config file '/home/konrad/.choosenim/toolchains/nim-#devel/config/nim.cfg' [Conf]
Hint: used config file '/home/konrad/.choosenim/toolchains/nim-#devel/config/config.nims' [Conf]
..........................................................................
/home/konrad/.config/VSCodium/User/globalStorage/buenon.scratchpads/scratchpads/56b8016bc5c16deae167b5cfb0a76e9f/scratch8.nim(14, 5) Hint: 'newNode' is declared but not used [XDeclaredButNotUsed]
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/system/exceptions.nim
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/std/private/digitsutils.nim
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/std/assertions.nim
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/system/dollars.nim
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/system.nim
CC: ../../../../../../../.choosenim/toolchains/nim-#devel/lib/pure/options.nim
CC: scratch8.nim
/home/konrad/.cache/nim/scratch8_d/@mscratch8.nim.c: In function ‘NimMainModule’:
/home/konrad/.cache/nim/scratch8_d/@mscratch8.nim.c:574:20: error: ‘tyObject_Option__iPwdvoo5DamSoOdiAagILA’ has no member named ‘has’
  574 |         (*T1_).next.has = colontmpD_.has;
      |                    ^
/home/konrad/.cache/nim/scratch8_d/@mscratch8.nim.c:574:37: error: ‘tyObject_Option__iPwdvoo5DamSoOdiAagILA’ has no member named ‘has’
  574 |         (*T1_).next.has = colontmpD_.has;
      |                                     ^
Error: execution of an external compiler program 'gcc -c  -w -fmax-errors=3 -pthread   -I'/home/konrad/.choosenim/toolchains/nim-#devel/lib' -I/home/konrad/.config/VSCodium/User/globalStorage/buenon.scratchpads/scratchpads/56b8016bc5c16deae167b5cfb0a76e9f -o /home/konrad/.cache/nim/scratch8_d/@mscratch8.nim.c.o /home/konrad/.cache/nim/scratch8_d/@mscratch8.nim.c' failed with exit code: 1

Expected Output

No error

Possible Solution

Elegantbeef from Matrix says it is a "cgen bug For some reason it's calling .has for a Option[ref] even though it shouldnt"

Additional Information

ghost commented 1 year ago

Might be a duplicate of https://github.com/nim-lang/Nim/issues/16754

konradmb commented 1 year ago

@Yardanico I can reproduce this one on --gc:none, --gc:arc, --gc:orc, --gc:refc. Although error messages are slightly different, it still generally boils down to "...has no member named ‘has’" Also, compiler probably crashes with normal object (not ref).

metagn commented 1 year ago

This:

import options

type
  NodeObj[T] = object
    value: T
    previous: Option[ref NodeObj[T]]
    next: Option[ref NodeObj[T]]
  Node[T] = ref NodeObj[T]
  LinkedList*[T] = object ## A doubly linked list.
    first: Option[Node[T]]
    last: Option[Node[T]]

var list = LinkedList[int]()
let newNode = Node[int](value: 0,
                      next: list.first.get.next,
                      previous: Node[int].none).some

gives:

prog.nim(17Error: unhandled exception: Can't obtain a value from a `none` [UnpackDefect]

While a similar workaround works for #16754

Edit: Actually this is probably the expected behavior of this code, so this workaround seems to work here as well