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

Multiple constraints with the first is of type void crashes compiler #7355

Open
alaviss opened this issue Mar 17, 2018 · 3 comments
Open

Multiple constraints with the first is of type void crashes compiler #7355

alaviss opened this issue Mar 17, 2018 · 3 comments

Comments

@alaviss
Copy link
Collaborator

alaviss commented Mar 17, 2018

Code snippet:

proc gen[A: void, T: void|int](a: A, b: T) = discard

gen[void, void]()     # Works
gen[void, int] 0      # Crash
gen[void, int](b = 0) # Crash

Compiler output:

Hint: used config file '/etc/nim.cfg' [Conf]
Hint: system [Processing]
Hint: crash [Processing]
Traceback from system (most recent call last)
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

nim version:

Nim Compiler Version 0.18.1 [Linux: amd64]
Copyright (c) 2006-2018 by Andreas Rumpf

git hash: cc5140d8b6ea8ca65ec9b74348cf23aec09d6723
active boot switches: -d:release -d:nativeStackTrace
@dom96
Copy link
Contributor

dom96 commented Mar 18, 2018

I have a feeling that overloading is something you should be using in this case anyway, and it's the workaround I can think of:

proc gen(a: int, b: int) = discard
proc gen(b: int) = discard

@alaviss
Copy link
Collaborator Author

alaviss commented Mar 18, 2018

My use case is something like this:

type
  Context* = object
    impl: pointer
    
  ContextError* = object of Exception
    
proc newCtxPtr(dir: cstring, cfgs: cstringArray): pointer {.importc.}

proc initContext[T: void|string, V: void|openArray[string]](ctx: var Context,
                                                            dir: T,
                                                            cfgs: V) =
  when T is void:
    const cdir = nil
  else:
    let cdir = cstring dir

  when V is void:
    const carr = nil
  else:
    let carr = allocCStringArray cfgs
    defer: deallocCstringArray carr

  ctx.impl = newCtxPtr(cdir, carr)

  if unlikely isNil ctx.impl:
    raise ContextError.newException "Cannot create a Context object"

proc initContext*(): Context =
  initContext[void, void] result

proc initContext*(dir: string): Context =
  initContext[string, void] result, dir

proc initContext*(cfgpaths: openArray[string]): Context =
  initContext[void, openArray[string]] result, cfgpaths

proc initContext*(dir: string, cfgpaths: openArray[string]): Context =
  initContext result, dir, cfgpaths

@narimiran
Copy link
Member

proc gen[A: void, T: void|int](a: A, b: T) = discard

Workaround:
Changing the order of params (proc gen[A: void, T: void|int](b: T, a: A) = discard) works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants