diff options
author | cooldome <ariabushenko@gmail.com> | 2020-09-16 20:37:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-16 21:37:23 +0200 |
commit | d938c6411e399ee1c936fa7b9ee3a1b53ab65791 (patch) | |
tree | c5e710365ab74eb5540e369510edf71a52b503c7 /compiler | |
parent | 913ffbb92d0f0b9c5e7cf3fcbb446c38e890680e (diff) | |
download | Nim-d938c6411e399ee1c936fa7b9ee3a1b53ab65791.tar.gz |
fix #15326 (#15341)
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semtypes.nim | 126 |
1 files changed, 67 insertions, 59 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d85008342..4d912a46f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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 + else: + typ = semGenericConstraints(c, typ) - 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 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) - - if typ == nil: - typ = newTypeS(tyGenericParam, c) - if father == nil: typ.flags.incl tfWildcard - - 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 + + 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) - 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] - - 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) |