diff --git a/changelog.md b/changelog.md index 8acd2120aef2..e1f40bb385f5 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,32 @@ ## Language changes +- With the experimental option `--experimental:typedTypeMacroPragma`, + macro pragmas in type definitions now receive a unary `nnkTypeSection` as + the argument instead of `nnkTypeDef`, which means `typed` arguments are now + possible for these macros. + + ```nim + {.experimental: "typedTypeMacroPragma".} + + import macros + + macro foo(def: typed) = + assert def.kind == nnkTypeSection # previously nnkTypeDef + assert def.len == 1 + assert def[0].kind == nnkTypeDef + result = def + + type Obj {.foo.} = object + x, y: int + + let obj = Obj(x: 1, y: 2) + ``` + + To keep compatibility, macros can be updated to accept either one of + `nnkTypeDef` or `nnkTypeSection` as input. Note that these macros can + still only return `nnkTypeDef` or `nnkTypeSection` nodes. + ## Compiler changes diff --git a/compiler/options.nim b/compiler/options.nim index b77bdd2a3371..5736b8b2f8ce 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -229,6 +229,7 @@ type # alternative to above: genericsOpenSym vtables + typedTypeMacroPragma LegacyFeature* = enum allowSemcheckedAstModification, diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f5f8fea0c608..8ce6d91926f4 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1447,7 +1447,10 @@ proc typeDefLeftSidePass(c: PContext, typeSection: PNode, i: int) = s.typ = newTypeS(tyForward, c) s.typ.sym = s # process pragmas: if name.kind == nkPragmaExpr: - let rewritten = applyTypeSectionPragmas(c, name[1], typeDef) + var macroArg = typeDef + if typedTypeMacroPragma in c.features: + macroArg = newTreeI(nkTypeSection, typeDef.info, typeDef) + let rewritten = applyTypeSectionPragmas(c, name[1], macroArg) if rewritten != nil: case rewritten.kind of nkTypeDef: @@ -1712,8 +1715,8 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = obj.flags.incl sfPure obj.typ = objTy objTy.sym = obj - for sk in c.skipTypes: - discard semTypeNode(c, sk, nil) + for i in 0..