parent
913ffbb92d
commit
d938c6411e
2 changed files with 71 additions and 55 deletions
|
|
@ -2055,72 +2055,80 @@ proc semGenericConstraints(c: PContext, x: PType): PType =
|
||||||
result = newTypeWithSons(c, tyGenericParam, @[x])
|
result = newTypeWithSons(c, tyGenericParam, @[x])
|
||||||
|
|
||||||
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
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)
|
result = copyNode(n)
|
||||||
if n.kind != nkGenericParams:
|
if n.kind != nkGenericParams:
|
||||||
illFormedAst(n, c.config)
|
illFormedAst(n, c.config)
|
||||||
return
|
return
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
var a = n[i]
|
var a = n[i]
|
||||||
if a.kind != nkIdentDefs: illFormedAst(n, c.config)
|
case a.kind
|
||||||
var def = a[^1]
|
of nkSym: result.addSym(a.sym)
|
||||||
let constraint = a[^2]
|
of nkIdentDefs:
|
||||||
var typ: PType
|
var def = a[^1]
|
||||||
|
let constraint = a[^2]
|
||||||
|
var typ: PType
|
||||||
|
|
||||||
if constraint.kind != nkEmpty:
|
if constraint.kind != nkEmpty:
|
||||||
typ = semTypeNode(c, constraint, nil)
|
typ = semTypeNode(c, constraint, nil)
|
||||||
if typ.kind != tyStatic or typ.len == 0:
|
if typ.kind != tyStatic or typ.len == 0:
|
||||||
if typ.kind == tyTypeDesc:
|
if typ.kind == tyTypeDesc:
|
||||||
if typ[0].kind == tyNone:
|
if typ[0].kind == tyNone:
|
||||||
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
typ = newTypeWithSons(c, tyTypeDesc, @[newTypeS(tyNone, c)])
|
||||||
incl typ.flags, tfCheckedForDestructor
|
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:
|
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 typ == nil:
|
||||||
if def.typ.kind != tyTypeDesc:
|
typ = newTypeS(tyGenericParam, c)
|
||||||
typ = newTypeWithSons(c, tyStatic, @[def.typ])
|
if father == nil: typ.flags.incl tfWildcard
|
||||||
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)
|
|
||||||
|
|
||||||
if typ == nil:
|
typ.flags.incl tfGenericTypeParam
|
||||||
typ = newTypeS(tyGenericParam, c)
|
|
||||||
if father == nil: typ.flags.incl tfWildcard
|
|
||||||
|
|
||||||
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:
|
if paramName.safeLen == 2:
|
||||||
let finalType = if j == 0: typ
|
if not nimEnableCovariance or paramName[0].ident.s == "in":
|
||||||
else: copyType(typ, typ.owner, false)
|
if father == nil or sfImportc notin father.sym.flags:
|
||||||
# it's important the we create an unique
|
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
|
||||||
# type for each generic param. the index
|
covarianceFlag = if paramName[0].ident.s == "in": tfContravariant
|
||||||
# of the parameter will be stored in the
|
else: tfCovariant
|
||||||
# attached symbol.
|
if father != nil: father.flags.incl tfCovariant
|
||||||
var paramName = a[j]
|
paramName = paramName[1]
|
||||||
var covarianceFlag = tfUnresolved
|
|
||||||
|
|
||||||
if paramName.safeLen == 2:
|
var s = if finalType.kind == tyStatic or tfWildcard in typ.flags:
|
||||||
if not nimEnableCovariance or paramName[0].ident.s == "in":
|
newSymG(skGenericParam, paramName, c).linkTo(finalType)
|
||||||
if father == nil or sfImportc notin father.sym.flags:
|
else:
|
||||||
localError(c.config, paramName.info, errInOutFlagNotExtern % $paramName[0])
|
newSymG(skType, paramName, c).linkTo(finalType)
|
||||||
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:
|
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
|
||||||
newSymG(skGenericParam, paramName, c).linkTo(finalType)
|
if def.kind != nkEmpty: s.ast = def
|
||||||
else:
|
s.position = result.len
|
||||||
newSymG(skType, paramName, c).linkTo(finalType)
|
result.addSym(s)
|
||||||
|
else:
|
||||||
if covarianceFlag != tfUnresolved: s.typ.flags.incl(covarianceFlag)
|
illFormedAst(n, c.config)
|
||||||
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)
|
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,11 @@ const t = mac("HEllo World")
|
||||||
echo s, " ", t
|
echo s, " ", t
|
||||||
|
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# issue #15326
|
||||||
|
macro m(n:typed):auto =
|
||||||
|
result = n
|
||||||
|
|
||||||
|
proc f[T](x:T): T {.m.} = x
|
||||||
|
|
||||||
|
discard f(3)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue