summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-08-23 00:42:43 +0300
committerZahary Karadjov <zahary@gmail.com>2013-08-23 01:10:20 +0300
commit8682ed9bd0bd8230e779e45cc65c2bfd4661a966 (patch)
tree2cd423d08702aaca03e4c5100fd9deb5b875d6dd
parentfee2a7ecfa883d100e1177b1cc7d738c6cfeaa83 (diff)
downloadNim-8682ed9bd0bd8230e779e45cc65c2bfd4661a966.tar.gz
pass-through of static int generic params to arrays when late instantiation is disabled
-rw-r--r--compiler/evals.nim3
-rw-r--r--compiler/options.nim2
-rw-r--r--compiler/semdata.nim10
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semtypes.nim14
-rw-r--r--compiler/semtypinst.nim6
-rw-r--r--compiler/sigmatch.nim3
-rw-r--r--tests/run/tstaticparams.nim9
8 files changed, 31 insertions, 18 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim
index 35954ccec..053068ea4 100644
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -905,8 +905,7 @@ proc evalParseStmt(c: PEvalContext, n: PNode): PNode =
   #result.typ = newType(tyStmt, c.module)
  
 proc evalTypeTrait*(trait, operand: PNode, context: PSym): PNode =
-  InternalAssert operand.kind == nkSym and
-                 operand.sym.typ.kind == tyTypeDesc
+  InternalAssert operand.kind == nkSym
 
   let typ = operand.sym.typ.skipTypes({tyTypeDesc})
   case trait.sym.name.s.normalize
diff --git a/compiler/options.nim b/compiler/options.nim
index cfda15f6a..2b25b2650 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -156,7 +156,7 @@ var
 
 const oKeepVariableNames* = true
 
-const oUseLateInstantiation* = true
+const oUseLateInstantiation* = false
 
 proc mainCommandArg*: string =
   ## This is intended for commands like check or parse
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index b9c32a680..8b04f4af5 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -225,14 +225,14 @@ proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) =
   dest.owner = getCurrOwner()
   dest.size = - 1
 
-proc makeRangeType*(c: PContext, first, last: biggestInt, 
-                    info: TLineInfo): PType = 
+proc makeRangeType*(c: PContext; first, last: biggestInt;
+                    info: TLineInfo; intType = getSysType(tyInt)): PType =
   var n = newNodeI(nkRange, info)
-  addSon(n, newIntNode(nkIntLit, first))
-  addSon(n, newIntNode(nkIntLit, last))
+  addSon(n, newIntTypeNode(nkIntLit, first, intType))
+  addSon(n, newIntTypeNode(nkIntLit, last, intType))
   result = newTypeS(tyRange, c)
   result.n = n
-  rawAddSon(result, getSysType(tyInt)) # basetype of range
+  addSonSkipIntLit(result, intType) # basetype of range
 
 proc markIndirect*(c: PContext, s: PSym) {.inline.} =
   if s.kind in {skProc, skConverter, skMethod, skIterator}:
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index d88cc28b6..ebda31501 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -113,7 +113,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
   of skGenericParam:
     if s.typ.kind == tyExpr:
       result = newSymNode(s, n.info)
-      result.typ = s.typ.lastSon
+      result.typ = s.typ
     elif s.ast != nil:
       result = semExpr(c, s.ast)
     else:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 1f7574bb5..e5d9058b4 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -195,16 +195,18 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
     else:
       let e = semExprWithType(c, n.sons[1], {efDetermineType})
       if e.kind in {nkIntLit..nkUInt64Lit}:
-        indx = newTypeS(tyRange, c)
-        indx.n = newNodeI(nkRange, n.info)
-        addSon(indx.n, newIntTypeNode(e.kind, 0, e.typ))
-        addSon(indx.n, newIntTypeNode(e.kind, e.intVal-1, e.typ))
-        addSonSkipIntLit(indx, e.typ)
+        indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
+      elif e.kind == nkSym and e.typ.kind == tyExpr:
+        if e.sym.ast != nil: return semArray(c, e.sym.ast, nil)
+        InternalAssert c.InGenericContext > 0
+        if not isOrdinalType(e.typ.lastSon):
+          localError(n[1].info, errOrdinalTypeExpected)
+        indx = e.typ
       else:
         indx = e.typ.skipTypes({tyTypeDesc})
     addSonSkipIntLit(result, indx)
     if indx.kind == tyGenericInst: indx = lastSon(indx)
-    if indx.kind != tyGenericParam:
+    if indx.kind notin {tyGenericParam, tyExpr}:
       if not isOrdinalType(indx):
         LocalError(n.sons[1].info, errOrdinalTypeExpected)
       elif enumHasHoles(indx): 
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 5482d5df8..0c15c7248 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -208,6 +208,12 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
   of tyInt:
     result = skipIntLit(t)
   else:
+    if t.kind == tyArray:
+      let idxt = t.sons[0]
+      if idxt.kind == tyExpr and 
+         idxt.sym != nil and idxt.sym.kind == skGenericParam:
+        let value = lookupTypeVar(cl, idxt).n
+        t.sons[0] = makeRangeType(cl.c, 0, value.intVal - 1, value.info)
     if containsGenericType(t):
       result = copyType(t, t.owner, false)
       incl(result.flags, tfFromGeneric)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index fa87f27a7..4483b1f8b 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -622,7 +622,8 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
   of tyGenericParam, tyTypeClass:
     var x = PType(idTableGet(c.bindings, f))
     if x == nil:
-      if c.calleeSym.kind == skType and f.kind == tyGenericParam and not c.typedescMatched:
+      if c.calleeSym != nil and c.calleeSym.kind == skType and
+         f.kind == tyGenericParam and not c.typedescMatched:
         # XXX: The fact that generic types currently use tyGenericParam for 
         # their parameters is really a misnomer. tyGenericParam means "match
         # any value" and what we need is "match any type", which can be encoded
diff --git a/tests/run/tstaticparams.nim b/tests/run/tstaticparams.nim
index 3e501ed8b..232748356 100644
--- a/tests/run/tstaticparams.nim
+++ b/tests/run/tstaticparams.nim
@@ -1,17 +1,22 @@
 discard """
   file: "tstaticparams.nim"
-  output: "abracadabra\ntest"
+  output: "abracadabra\ntest\n3"
 """
 
 type 
   TFoo[T; Val: expr[string]] = object
     data: array[4, T]
 
+  TBar[T; I: expr[int]] = object
+    data: array[I, T]
+
 proc takeFoo(x: TFoo) =
   echo "abracadabra"
   echo TFoo.Val
 
 var x: TFoo[int, "test"]
-
 takeFoo(x)
 
+var y: TBar[float, 4]
+echo high(y.data)
+