summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-31 16:08:07 +0100
committerAraq <rumpf_a@web.de>2014-12-31 16:08:07 +0100
commite751a0af573a5a65eaaabf15fecb1f1c010b6bf6 (patch)
tree1654faf325452b5a379c3198c680b4e4a36295bc
parent2ee24013360649d9ec3749e5dcdce37716900854 (diff)
parent13e07f5d667c569355470a56e8a730ca8a1862e5 (diff)
downloadNim-e751a0af573a5a65eaaabf15fecb1f1c010b6bf6.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nim into devel
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semgnrc.nim3
-rw-r--r--compiler/sigmatch.nim3
-rw-r--r--compiler/types.nim20
-rw-r--r--tests/generics/t1056.nim26
-rw-r--r--tests/types/tisopr.nim17
6 files changed, 65 insertions, 8 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f71847946..89110a479 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -926,7 +926,8 @@ const
 proc readTypeParameter(c: PContext, typ: PType,
                        paramName: PIdent, info: TLineInfo): PNode =
   let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias
-           else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1])
+           else: (internalAssert(typ.kind == tyCompositeTypeClass);
+                  typ.sons[1].skipGenericAlias)
   #debug ty
   let tbody = ty.sons[0]
   for s in countup(0, tbody.len-2):
@@ -965,6 +966,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
   var ty = n.sons[0].typ
   var f: PSym = nil
   result = nil
+
   if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone):
     if ty.kind == tyTypeDesc: ty = ty.base
     ty = ty.skipTypes(tyDotOpTransparent)
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index 06959b8d1..1ab4f5989 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -72,7 +72,8 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
     result = n
     styleCheckUse(n.info, s)
   of skType: 
-    if (s.typ != nil) and (s.typ.kind != tyGenericParam): 
+    if (s.typ != nil) and
+       (s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}):
       result = newSymNodeTypeDesc(s, n.info)
     else: 
       result = n
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index d7bf4fee9..b58818a29 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -979,6 +979,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   of tyStatic:
     if aOrig.kind == tyStatic:
       result = typeRel(c, f.lastSon, a)
+      if result != isNone and f.n != nil:
+        if not exprStructuralEquivalent(f.n, a.n):
+          result = isNone
       if result != isNone: put(c.bindings, f, aOrig)
     else:
       result = isNone
diff --git a/compiler/types.nim b/compiler/types.nim
index f67cd239e..4a77773e6 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -17,7 +17,7 @@ proc lastOrd*(t: PType): BiggestInt
 proc lengthOrd*(t: PType): BiggestInt
 type 
   TPreferedDesc* = enum
-    preferName, preferDesc, preferExported, preferModuleInfo
+    preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
 
 proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string
 proc base*(t: PType): PType
@@ -411,11 +411,13 @@ const
     "UserTypeClassInst", "CompositeTypeClass",
     "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor"]
 
+const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
+
 proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
   var t = typ
   result = ""
   if t == nil: return 
-  if prefer in {preferName, preferModuleInfo} and t.sym != nil and
+  if prefer in preferToResolveSymbols and t.sym != nil and
        sfAnon notin t.sym.flags:
     if t.kind == tyInt and isIntLit(t):
       return t.sym.name.s & " literal(" & $t.n.intVal & ")"
@@ -428,20 +430,26 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
     if not isIntLit(t) or prefer == preferExported:
       result = typeToStr[t.kind]
     else:
-      result = "int literal(" & $t.n.intVal & ")"
+      if prefer == preferGenericArg:
+        result = $t.n.intVal
+      else:
+        result = "int literal(" & $t.n.intVal & ")"
   of tyGenericBody, tyGenericInst, tyGenericInvokation:
     result = typeToString(t.sons[0]) & '['
     for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)):
       if i > 1: add(result, ", ")
-      add(result, typeToString(t.sons[i]))
+      add(result, typeToString(t.sons[i], preferGenericArg))
     add(result, ']')
   of tyTypeDesc:
     if t.base.kind == tyNone: result = "typedesc"
     else: result = "typedesc[" & typeToString(t.base) & "]"
   of tyStatic:
     internalAssert t.len > 0
-    result = "static[" & typeToString(t.sons[0]) & "]"
-    if t.n != nil: result.add "(" & renderTree(t.n) & ")"
+    if prefer == preferGenericArg and t.n != nil:
+      result = t.n.renderTree
+    else:
+      result = "static[" & typeToString(t.sons[0]) & "]"
+      if t.n != nil: result.add "(" & renderTree(t.n) & ")"
   of tyUserTypeClass:
     internalAssert t.sym != nil and t.sym.owner != nil
     return t.sym.owner.name.s
diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim
new file mode 100644
index 000000000..73a24a76a
--- /dev/null
+++ b/tests/generics/t1056.nim
@@ -0,0 +1,26 @@
+discard """
+  output: '''TMatrix[3, 3, system.int]
+3
+3'''
+"""
+
+import typetraits
+
+type
+  TMatrix*[N,M: static[int], T] = object
+    data*: array[0..N*M-1, T]
+
+  TMat2[T] = TMatrix[2,2,T]
+
+proc echoMatrix(a: TMatrix) =
+  echo a.type.name
+  echo TMatrix.N
+
+proc echoMat2(a: TMat2) =
+  echo TMat2.M
+  
+var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
+
+echoMatrix m
+echoMat2 m
+
diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim
index 3c2b9ee5e..8b7fe4e46 100644
--- a/tests/types/tisopr.nim
+++ b/tests/types/tisopr.nim
@@ -34,3 +34,20 @@ type
 yes s.items is Iter[TNumber]
 no  s.items is Iter[float]
 
+type
+  Foo[N: static[int], T] = object
+    field: array[1..N, T]
+
+  Bar[T] = Foo[4, T]
+  Baz[N: static[int]] = Foo[N, float]
+
+no Foo[2, float] is Foo[3, float]
+no Foo[2, float] is Foo[2, int]
+
+yes Foo[4, string] is Foo[4, string]
+yes Bar[int] is Foo[4, int]
+yes Foo[4, int] is Bar[int]
+
+no Foo[4, int] is Baz[4]
+yes Foo[4, float] is Baz[4]
+