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

SIGSEGV on generic macro returning a type #8406

Closed
Quelklef opened this issue Jul 23, 2018 · 7 comments · Fixed by #24005
Closed

SIGSEGV on generic macro returning a type #8406

Quelklef opened this issue Jul 23, 2018 · 7 comments · Fixed by #24005
Labels

Comments

@Quelklef
Copy link
Contributor

The following SIGSEGVs:

macro f(x: static[int]): untyped = discard
proc g[X: static[int]](v: f(X)) = discard

This is valid with the type system, though, right? Since X is known at compile-time it can be used to generate a type for v? I want to do something like this:

type MyFancyConcreteType = ...
type MyFancyGenericType[N: static[int]] = ...

macro Choose(N: static[int]): untyped =
  if N == 2:
    return ident("MyFancyConcreteType")
  else:
    return nnkBracketExpr.newTree(ident("MyFancyGenericType"), newIntLitNode(N))

var x: Choose(2)  # of MyFancyConcreteType
var y: Choose(3)  # of MyFancyGenericType[3]

# Generic procs may still be written
proc doSomethingWithEither[N: static[int]](v: Choose(N)) = ...

Is this possible, SIGSEGV or no; should I abandon the idea?

@Quelklef
Copy link
Contributor Author

I should also not that this is a static[T] issue; the following compiles fine (but does not "work"):

import macros

macro f(x: untyped): untyped =
  newIdentNode("int")

proc g[X](x: f(X)) =
  discard

@mratsim
Copy link
Collaborator

mratsim commented Jul 23, 2018

I don't know if it should work or not.

At the moment you can generate the proc in the macro or use a wrapper type like I did in Stint.

In you example that would be something like this:

macro Choose(N: static[int]): untyped =
  if N == 2:
    return ident("MyFancyConcreteType")
  else:
    return nnkBracketExpr.newTree(ident("MyFancyGenericType"), newIntLitNode(N))

type MyFancyConcreteType = ...
type MyFancyGenericType[N: static[int]] = ...

type MyFancyType[N: static[int]] = object
  impl: Choose[N]

var x: Choose(2)  # of MyFancyConcreteType
var y: Choose(3)  # of MyFancyGenericType[3]

# Generic procs may still be written
proc doSomethingWithEither[N: static[int]](v: MyFancyType[N]) = ...

You should put a full working example, btw. I think your issue is linked to #7231

@Quelklef
Copy link
Contributor Author

Yes, I believe you helped me implement your solution a while back. I decided I wanted to see if I could find a solution involving no wrapper types.

What do you mean by a full working example? In regards to the bug, or to my intended feature?

@mratsim
Copy link
Collaborator

mratsim commented Jul 24, 2018

I meant:

type MyFancyConcreteType = object
type MyFancyGenericType[N: static[int]] = object
  foo: array[N, int]

Instead of type MyFancyConcreteType = ... so that we can directly copy-paste like the lazy programmers we are :).

@Quelklef
Copy link
Contributor Author

Ah, I'll be sure to keep that in mind for the future ;-)

@saem
Copy link
Contributor

saem commented Mar 24, 2021

Tested in playground, no more sigsev, an error is produced instead: /usercode/in.nim(2, 28) Error: expression '' has no type (or is ambiguous)

@metagn
Copy link
Collaborator

metagn commented Sep 1, 2023

Early generic evaluation bug again, can link #8551 and #22607 right now but there are more related issues

As described in the other issues, delegating to a generic type is a workaround

macro f(x: static[int]): untyped = discard
type FWrapper[x: static int] = f(x)
proc g[X: static[int]](v: FWrapper[X]) = discard

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