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

Typed type section macro doesn't work #18864

Open
alaviss opened this issue Sep 19, 2021 · 3 comments · May be fixed by #24245
Open

Typed type section macro doesn't work #18864

alaviss opened this issue Sep 19, 2021 · 3 comments · May be fixed by #24245
Labels

Comments

@alaviss
Copy link
Collaborator

alaviss commented Sep 19, 2021

Example

import std/macros

macro test(n: typed): untyped =
  echo treeRepr n
  result = n

type
  X {.test.} = object

Current Output

test.nim(8, 14) Error: invalid expression: X {..} = object

Additional Information

$ nim -v
Nim Compiler Version 1.5.1 [Linux: amd64]
Compiled at 2021-09-19
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: 6cd219c3a38c5f1a0712b0b5d07a3ea4ab02ff74
active boot switches: -d:release -d:nimUseLinenoise
@alaviss alaviss added the Macros label Sep 19, 2021
@shirleyquirk
Copy link
Contributor

shirleyquirk commented Oct 16, 2021

should it work? the type section can't be typed until it exists, i.e. has been processed through the macro. if type X already exists, when the macro runs, and tries to replace X, there'll be a redefinition error.

does it need to work? one has access to the full type declaration, what other information could you get?

Edit: I'm convinced. Yes and yes. Bringing them up to parity with proc macros would be a nice feature.

@alaviss
Copy link
Collaborator Author

alaviss commented Oct 16, 2021

Yes it should work.

the type section can't be typed until it exists, i.e. has been processed through the macro.

Why can't it be? There is nothing stopping the compiler from performing semantic checking and resolving symbols, as well as running any macros prior to the current one. This is how typed macros already work for proc and friends.

If type X already exists, when the macro runs, and tries to replace X, there'll be a redefinition error.

There shouldn't be a redefinition error. Think of types created in a typed macro context as created in a "shadow" scope, which is like an overlay on top of the current scope, and only after the macro have been run would the resulting AST be introduced to the real scope, which should eliminate all redefinition concerns. Again, typed macros for proc, var, etc. already works like this.

one has access to the full type declaration, what other information could you get?

I need the type symbols as resolved by the compiler, as well as other untyped/typed macros to have been resolved.

@metagn
Copy link
Collaborator

metagn commented Aug 28, 2023

The problem is really obvious (compiler tries to type nkTypeDef, can't because it's not a standalone expression) but really annoying to fix.

We could always just pass a type section (as in #13830) but this would break every macro that only accepts an nkTypeDef, and every macro that expects nkTypeSection but returns anything that isn't nkTypeDef or nkTypeSection.

We could form a type section from the single typedef first, type it, then extract the single typedef from that and pass that to the macro, but this sounds hacky.

For now we have this ugly workaround (although I like the Impl idiom in general):

import std/macros

macro testImpl(n: typed): untyped =
  result = n

macro test(n: untyped): untyped =
  result = newTree(nnkTypeDef, ident"_", newEmptyNode(), newStmtList(
    newCall(bindSym"testImpl", newTree(nnkTypeSection, n)),
    ident"void"))
  echo result.treeRepr

type
  X {.test.} = object

Edit: Same issue: #15334

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

Successfully merging a pull request may close this issue.

3 participants