summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorcooldome <ariabushenko@gmail.com>2020-09-16 20:37:23 +0100
committerGitHub <noreply@github.com>2020-09-16 21:37:23 +0200
commitd938c6411e399ee1c936fa7b9ee3a1b53ab65791 (patch)
treec5e710365ab74eb5540e369510edf71a52b503c7 /compiler
parent913ffbb92d0f0b9c5e7cf3fcbb446c38e890680e (diff)
downloadNim-d938c6411e399ee1c936fa7b9ee3a1b53ab65791.tar.gz
fix #15326 (#15341)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semtypes.nim126
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)