mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-22 15:25:22 +00:00
@@ -2055,72 +2055,80 @@ proc semGenericConstraints(c: PContext, x: PType): PType =
|
||||
result = newTypeWithSons(c, tyGenericParam, @[x])
|
||||
|
||||
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||
|
||||
template addSym(result: PNode, s: PSym): untyped =
|
||||
if father != nil: addSonSkipIntLit(father, s.typ)
|
||||
if sfGenSym notin s.flags: addDecl(c, s)
|
||||
result.add newSymNode(s)
|
||||
|
||||
result = copyNode(n)
|
||||
if n.kind != nkGenericParams:
|
||||
illFormedAst(n, c.config)
|
||||
return
|
||||
for i in 0..<n.len:
|
||||
var a = n[i]
|
||||
if a.kind != nkIdentDefs: illFormedAst(n, c.config)
|
||||
var def = a[^1]
|
||||
let constraint = a[^2]
|
||||
var typ: PType
|
||||
var a = n[i]
|
||||
case a.kind
|
||||
of nkSym: result.addSym(a.sym)
|
||||
of nkIdentDefs:
|
||||
var def = a[^1]
|
||||
let constraint = a[^2]
|
||||
var typ: PType
|
||||
|
||||
if constraint.kind != nkEmpty:
|
||||
typ = semTypeNode(c, constraint, nil)
|
||||
if typ.kind != tyStatic or typ.len == 0:
|
||||
if typ.kind == tyTypeDesc:
|
||||
if typ[0].kind == tyNone:
|
||||
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
||||
incl typ.flags, tfCheckedForDestructor
|
||||
if constraint.kind != nkEmpty:
|
||||
typ = semTypeNode(c, constraint, nil)
|
||||
if typ.kind != tyStatic or typ.len == 0:
|
||||
if typ.kind == tyTypeDesc:
|
||||
if typ[0].kind == tyNone:
|
||||
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
||||
incl typ.flags, tfCheckedForDestructor
|
||||
else:
|
||||
typ = semGenericConstraints(c, typ)
|
||||
|
||||
if def.kind != nkEmpty:
|
||||
def = semConstExpr(c, def)
|
||||
if typ == nil:
|
||||
if def.typ.kind != tyTypeDesc:
|
||||
typ = newTypeWithSons(c, tyStatic, @[def.typ])
|
||||
else:
|
||||
typ = semGenericConstraints(c, typ)
|
||||
# the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]``
|
||||
# from manyloc/named_argument_bug/triengine:
|
||||
def.typ = def.typ.skipTypes({tyTypeDesc})
|
||||
if not containsGenericType(def.typ):
|
||||
def = fitNode(c, typ, def, def.info)
|
||||
|
||||
if def.kind != nkEmpty:
|
||||
def = semConstExpr(c, def)
|
||||
if typ == nil:
|
||||
if def.typ.kind != tyTypeDesc:
|
||||
typ = newTypeWithSons(c, tyStatic, @[def.typ])
|
||||
else:
|
||||
# the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]``
|
||||
# from manyloc/named_argument_bug/triengine:
|
||||
def.typ = def.typ.skipTypes({tyTypeDesc})
|
||||
if not containsGenericType(def.typ):
|
||||
def = fitNode(c, typ, def, def.info)
|
||||
typ = newTypeS(tyGenericParam, c)
|
||||
if father == nil: typ.flags.incl tfWildcard
|
||||
|
||||
if typ == nil:
|
||||
typ = newTypeS(tyGenericParam, c)
|
||||
if father == nil: typ.flags.incl tfWildcard
|
||||
typ.flags.incl tfGenericTypeParam
|
||||
|
||||
typ.flags.incl tfGenericTypeParam
|
||||
for j in 0..<a.len-2:
|
||||
let finalType = if j == 0: typ
|
||||
else: copyType(typ, typ.owner, false)
|
||||
# it's important the we create an unique
|
||||
# type for each generic param. the index
|
||||
# of the parameter will be stored in the
|
||||
# attached symbol.
|
||||
var paramName = a[j]
|
||||
var covarianceFlag = tfUnresolved
|
||||
|
||||
for j in 0..<a.len-2:
|
||||
let finalType = if j == 0: typ
|
||||
else: copyType(typ, typ.owner, false)
|
||||
# it's important the we create an unique
|
||||
# type for each generic param. the index
|
||||
# of the parameter will be stored in the
|
||||
# attached symbol.
|
||||
var paramName = a[j]
|
||||
var covarianceFlag = tfUnresolved
|
||||
if paramName.safeLen == 2:
|
||||
if not nimEnableCovariance or paramName[0].ident.s == "in":
|
||||
if father == nil or sfImportc notin father.sym.flags:
|
||||
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
|
||||
covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
|
||||
else: tfCovariant
|
||||
if father != nil: father.flags.incl tfCovariant
|
||||
paramName = paramName[1]
|
||||
|
||||
if paramName.safeLen == 2:
|
||||
if not nimEnableCovariance or paramName[0].ident.s == "in":
|
||||
if father == nil or sfImportc notin father.sym.flags:
|
||||
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
|
||||
covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
|
||||
else: tfCovariant
|
||||
if father != nil: father.flags.incl tfCovariant
|
||||
paramName = paramName[1]
|
||||
var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
|
||||
newSymG(skGenericParam, paramName, c).linkTo(finalType)
|
||||
else:
|
||||
newSymG(skType, paramName, c).linkTo(finalType)
|
||||
|
||||
var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
|
||||
newSymG(skGenericParam, paramName, c).linkTo(finalType)
|
||||
else:
|
||||
newSymG(skType, paramName, c).linkTo(finalType)
|
||||
|
||||
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
|
||||
if def.kind != nkEmpty: s.ast = def
|
||||
if father != nil: addSonSkipIntLit(father, s.typ)
|
||||
s.position = result.len
|
||||
result.add newSymNode(s)
|
||||
if sfGenSym notin s.flags: addDecl(c, s)
|
||||
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
|
||||
if def.kind != nkEmpty: s.ast = def
|
||||
s.position = result.len
|
||||
result.addSym(s)
|
||||
else:
|
||||
illFormedAst(n, c.config)
|
||||
|
||||
@@ -26,3 +26,11 @@ const t = mac("HEllo World")
|
||||
echo s, " ", t
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# issue #15326
|
||||
macro m(n:typed):auto =
|
||||
result = n
|
||||
|
||||
proc f[T](x:T): T {.m.} = x
|
||||
|
||||
discard f(3)
|
||||
Reference in New Issue
Block a user