Skip to content

Commit d938c64

Browse files
authored
fix #15326 (#15341)
1 parent 913ffbb commit d938c64

File tree

2 files changed

+75
-59
lines changed

2 files changed

+75
-59
lines changed

compiler/semtypes.nim

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,72 +2055,80 @@ proc semGenericConstraints(c: PContext, x: PType): PType =
20552055
result = newTypeWithSons(c, tyGenericParam, @[x])
20562056

20572057
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
2058+
2059+
template addSym(result: PNode, s: PSym): untyped =
2060+
if father != nil: addSonSkipIntLit(father, s.typ)
2061+
if sfGenSym notin s.flags: addDecl(c, s)
2062+
result.add newSymNode(s)
2063+
20582064
result = copyNode(n)
20592065
if n.kind != nkGenericParams:
20602066
illFormedAst(n, c.config)
20612067
return
20622068
for i in 0..<n.len:
2063-
var a = n[i]
2064-
if a.kind != nkIdentDefs: illFormedAst(n, c.config)
2065-
var def = a[^1]
2066-
let constraint = a[^2]
2067-
var typ: PType
2069+
var a = n[i]
2070+
case a.kind
2071+
of nkSym: result.addSym(a.sym)
2072+
of nkIdentDefs:
2073+
var def = a[^1]
2074+
let constraint = a[^2]
2075+
var typ: PType
2076+
2077+
if constraint.kind != nkEmpty:
2078+
typ = semTypeNode(c, constraint, nil)
2079+
if typ.kind != tyStatic or typ.len == 0:
2080+
if typ.kind == tyTypeDesc:
2081+
if typ[0].kind == tyNone:
2082+
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
2083+
incl typ.flags, tfCheckedForDestructor
2084+
else:
2085+
typ = semGenericConstraints(c, typ)
20682086

2069-
if constraint.kind != nkEmpty:
2070-
typ = semTypeNode(c, constraint, nil)
2071-
if typ.kind != tyStatic or typ.len == 0:
2072-
if typ.kind == tyTypeDesc:
2073-
if typ[0].kind == tyNone:
2074-
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
2075-
incl typ.flags, tfCheckedForDestructor
2087+
if def.kind != nkEmpty:
2088+
def = semConstExpr(c, def)
2089+
if typ == nil:
2090+
if def.typ.kind != tyTypeDesc:
2091+
typ = newTypeWithSons(c, tyStatic, @[def.typ])
20762092
else:
2077-
typ = semGenericConstraints(c, typ)
2093+
# the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]``
2094+
# from manyloc/named_argument_bug/triengine:
2095+
def.typ = def.typ.skipTypes({tyTypeDesc})
2096+
if not containsGenericType(def.typ):
2097+
def = fitNode(c, typ, def, def.info)
20782098

2079-
if def.kind != nkEmpty:
2080-
def = semConstExpr(c, def)
20812099
if typ == nil:
2082-
if def.typ.kind != tyTypeDesc:
2083-
typ = newTypeWithSons(c, tyStatic, @[def.typ])
2084-
else:
2085-
# the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]``
2086-
# from manyloc/named_argument_bug/triengine:
2087-
def.typ = def.typ.skipTypes({tyTypeDesc})
2088-
if not containsGenericType(def.typ):
2089-
def = fitNode(c, typ, def, def.info)
2090-
2091-
if typ == nil:
2092-
typ = newTypeS(tyGenericParam, c)
2093-
if father == nil: typ.flags.incl tfWildcard
2094-
2095-
typ.flags.incl tfGenericTypeParam
2100+
typ = newTypeS(tyGenericParam, c)
2101+
if father == nil: typ.flags.incl tfWildcard
2102+
2103+
typ.flags.incl tfGenericTypeParam
2104+
2105+
for j in 0..<a.len-2:
2106+
let finalType = if j == 0: typ
2107+
else: copyType(typ, typ.owner, false)
2108+
# it's important the we create an unique
2109+
# type for each generic param. the index
2110+
# of the parameter will be stored in the
2111+
# attached symbol.
2112+
var paramName = a[j]
2113+
var covarianceFlag = tfUnresolved
2114+
2115+
if paramName.safeLen == 2:
2116+
if not nimEnableCovariance or paramName[0].ident.s == "in":
2117+
if father == nil or sfImportc notin father.sym.flags:
2118+
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
2119+
covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
2120+
else: tfCovariant
2121+
if father != nil: father.flags.incl tfCovariant
2122+
paramName = paramName[1]
2123+
2124+
var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
2125+
newSymG(skGenericParam, paramName, c).linkTo(finalType)
2126+
else:
2127+
newSymG(skType, paramName, c).linkTo(finalType)
20962128

2097-
for j in 0..<a.len-2:
2098-
let finalType = if j == 0: typ
2099-
else: copyType(typ, typ.owner, false)
2100-
# it's important the we create an unique
2101-
# type for each generic param. the index
2102-
# of the parameter will be stored in the
2103-
# attached symbol.
2104-
var paramName = a[j]
2105-
var covarianceFlag = tfUnresolved
2106-
2107-
if paramName.safeLen == 2:
2108-
if not nimEnableCovariance or paramName[0].ident.s == "in":
2109-
if father == nil or sfImportc notin father.sym.flags:
2110-
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
2111-
covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
2112-
else: tfCovariant
2113-
if father != nil: father.flags.incl tfCovariant
2114-
paramName = paramName[1]
2115-
2116-
var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
2117-
newSymG(skGenericParam, paramName, c).linkTo(finalType)
2118-
else:
2119-
newSymG(skType, paramName, c).linkTo(finalType)
2120-
2121-
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
2122-
if def.kind != nkEmpty: s.ast = def
2123-
if father != nil: addSonSkipIntLit(father, s.typ)
2124-
s.position = result.len
2125-
result.add newSymNode(s)
2126-
if sfGenSym notin s.flags: addDecl(c, s)
2129+
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
2130+
if def.kind != nkEmpty: s.ast = def
2131+
s.position = result.len
2132+
result.addSym(s)
2133+
else:
2134+
illFormedAst(n, c.config)

tests/macros/tmacro2.nim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ const t = mac("HEllo World")
2626
echo s, " ", t
2727

2828

29+
#-----------------------------------------------------------------------------
30+
# issue #15326
31+
macro m(n:typed):auto =
32+
result = n
33+
34+
proc f[T](x:T): T {.m.} = x
35+
36+
discard f(3)

0 commit comments

Comments
 (0)