summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-01-07 20:03:41 +0100
committerAraq <rumpf_a@web.de>2012-01-07 20:03:41 +0100
commit7405278138f4e76d5e6278b3ed25f953ba9260e1 (patch)
tree7c634a657e72eb4a2aaf1e1a472531daecd6ac99
parent0e22a51095d189080ef8af445376fb7ccc061c85 (diff)
downloadNim-7405278138f4e76d5e6278b3ed25f953ba9260e1.tar.gz
bugfix: type alias to generic; generic type not stripped away from for loop variable
-rwxr-xr-xcompiler/condsyms.nim3
-rwxr-xr-xcompiler/semcall.nim4
-rwxr-xr-xcompiler/semstmts.nim5
-rwxr-xr-xcompiler/sigmatch.nim24
-rwxr-xr-xkoch.nim117
-rw-r--r--tests/compile/tgeneric.nim11
-rw-r--r--tests/compile/tgeneric2.nim11
-rw-r--r--tests/compile/tgenericprop.nim12
8 files changed, 118 insertions, 69 deletions
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index fca494324..5467e3929 100755
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -32,6 +32,9 @@ proc isDefined*(symbol: PIdent): bool =
   var sym = StrTableGet(gSymbols, symbol)
   result = sym != nil and sym.position == 1
 
+proc isDefined*(symbol: string): bool = 
+  result = isDefined(getIdent(symbol))
+
 proc ListSymbols*() = 
   var it: TTabIter
   var s = InitTabIter(it, gSymbols)
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 8d6af4528..c92eff319 100755
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -116,9 +116,9 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
         # type parameters:
         if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
           result.add(explicitGenericSym(c, n, candidate))
-    # get rid of nkSymChoice if not ambigious:
+    # get rid of nkSymChoice if not ambiguous:
     if result.len == 1: result = result[0]
     # candidateCount != 1: return explicitGenericInstError(n)
   else:
-    assert false
+    result = explicitGenericInstError(n)
 
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index fdb2bfe36..52a3853f2 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -417,7 +417,10 @@ proc semFor(c: PContext, n: PNode): PNode =
     if iter.kind != tyTuple or length == 3: 
       if length != 3: GlobalError(n.info, errWrongNumberOfVariables)
       var v = newSymS(skForVar, n.sons[0], c)
-      v.typ = iter
+      # BUGFIX: don't use `iter` here as that would strip away
+      # the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
+      # for an example:
+      v.typ = n.sons[length-2].typ
       n.sons[0] = newSymNode(v)
       addDecl(c, v)
     else: 
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 59501f403..6b6ebb40a 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -12,7 +12,7 @@
 
 import 
   intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, 
-  magicsys
+  magicsys, condsyms, idents
 
 type
   TCandidateState* = enum 
@@ -27,7 +27,7 @@ type
     callee*: PType           # may not be nil!
     calleeSym*: PSym         # may be nil
     call*: PNode             # modified call
-    bindings*: TIdTable      # maps sym-ids to types
+    bindings*: TIdTable      # maps types to types
     baseTypeMatch: bool      # needed for conversions from T to openarray[T]
                              # for example
   
@@ -52,6 +52,12 @@ proc initCandidate*(c: var TCandidate, callee: PType) =
   c.calleeSym = nil
   initIdTable(c.bindings)
 
+proc put(t: var TIdTable, key, val: PType) {.inline.} =
+  IdTablePut(t, key, val)
+  if val.kind == tyObject and isDefined"testme" and 
+      IdentEq(val.sym.name, "TTable"):
+    assert false
+
 proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) = 
   initCandidateAux(c, callee.typ)
   c.calleeSym = callee
@@ -61,7 +67,7 @@ proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) =
     for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1):
       var formalTypeParam = typeParams.sons[i-1].typ
       #debug(formalTypeParam)
-      IdTablePut(c.bindings, formalTypeParam, binding[i].typ)
+      put(c.bindings, formalTypeParam, binding[i].typ)
 
 proc copyCandidate(a: var TCandidate, b: TCandidate) = 
   a.exactMatches = b.exactMatches
@@ -100,7 +106,7 @@ proc getNotFoundError*(c: PContext, n: PNode): string =
   # in case of an error).
   result = msgKindToString(errTypeMismatch)
   for i in countup(1, sonsLen(n) - 1): 
-    #debug(n.sons[i].typ);
+    #debug(n.sons[i].typ)
     if n.sons[i].kind == nkExprEqExpr: 
       add(result, renderTree(n.sons[i].sons[0]))
       add(result, ": ")
@@ -225,7 +231,7 @@ proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
     if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags:
       result = isNone
     elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
-      # noSideEffect implies ``tfThread``!
+      # noSideEffect implies ``tfThread``! XXX really?
       result = isNone
   else: nil
 
@@ -236,7 +242,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
   assert(a != nil)
   if a.kind == tyGenericInst and
       skipTypes(f, {tyVar}).kind notin {
-        tyGenericBody, tyGenericInvokation, tyGenericParam}: 
+        tyGenericBody, tyGenericInvokation, tyGenericParam}:
     return typeRel(mapping, f, lastSon(a))
   if a.kind == tyVar and f.kind != tyVar: 
     return typeRel(mapping, f, a.sons[0])
@@ -413,7 +419,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
           var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1]))
           if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}:
             InternalError("wrong instantiated type!")
-          idTablePut(mapping, f.sons[i], x)
+          put(mapping, f.sons[i], x)
   of tyGenericParam: 
     var x = PType(idTableGet(mapping, f))
     if x == nil: 
@@ -421,7 +427,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
         # no constraints
         var concrete = concreteType(mapping, a)
         if concrete != nil:
-          idTablePut(mapping, f, concrete)
+          put(mapping, f, concrete)
           result = isGeneric
       else: 
         # check constraints:
@@ -429,7 +435,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
           if typeRel(mapping, f.sons[i], a) >= isSubtype: 
             var concrete = concreteType(mapping, a)
             if concrete != nil: 
-              idTablePut(mapping, f, concrete)
+              put(mapping, f, concrete)
               result = isGeneric
             break 
     elif a.kind == tyEmpty: 
diff --git a/koch.nim b/koch.nim
index a19de3f2f..35b7d7f3d 100755
--- a/koch.nim
+++ b/koch.nim
@@ -36,7 +36,7 @@ Possible Commands:
   zip                      builds the installation ZIP package
   inno [options]           builds the Inno Setup installer (for Windows)
   tests                    run the testsuite
-  update                   updates nimrod to the latest version from the repo
+  update                   updates nimrod to the latest version from github
 Boot options:
   -d:release               produce a release version of the compiler
   -d:tinyc                 include the Tiny C backend (not supported on Windows)
@@ -83,62 +83,6 @@ proc web(args: string) =
   exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" %
        NimrodVersion)
 
-proc update(args: string) =
-  when defined(windows):
-    echo("Windows users: Make sure to be running this in Bash. ",
-         "If you aren't, press CTRL+C now.")
-
-  var thisDir = getAppDir()
-  var git = findExe("git")
-  echo("Checking for git repo and git executable...")
-  if existsDir(thisDir & "/.git") and git != "":
-    echo("Git repo found!")
-    # use git to download latest source
-    echo("Checking for updates...")
-    discard startCmd(git & " fetch origin master")
-    var procs = startCmd(git & " diff origin/master master")
-    var errcode = procs.waitForExit()
-    var output = readLine(procs.outputStream)
-    echo(output)
-    if errcode == 0:
-      if output == "":
-        # No changes
-        echo("No update. Exiting..")
-        return
-      else:
-        echo("Fetching updates from repo...")
-        var pullout = execCmdEx(git & " pull origin master")
-        if pullout[1] != 0:
-          quit("An error has occured.")
-        else:
-          if pullout[0].startsWith("Already up-to-date."):
-            quit("No new changes fetched from the repo. " &
-                 "Local branch must be ahead of it. Exiting...")
-    else:
-      quit("An error has occured.")
-    
-  else:
-    echo("No repo or executable found!")
-    when defined(haveZipLib):
-      echo("Falling back.. Downloading source code from repo...")
-      # use dom96's httpclient to download zip
-      downloadFile("https://github.com/Araq/Nimrod/zipball/master",
-                   thisDir / "update.zip")
-      try:
-        echo("Extracting source code from archive...")
-        var zip: TZipArchive
-        discard open(zip, thisDir & "/update.zip", fmRead)
-        extractAll(zip, thisDir & "/")
-      except:
-        quit("Error reading archive.")
-    else:
-      quit("No failback available. Exiting...")
-  
-  echo("Starting update...")
-  boot(args)
-  echo("Update complete!")
-
-
 # -------------- boot ---------------------------------------------------------
 
 const
@@ -237,6 +181,65 @@ proc clean(args: string) =
       echo "removing dir: ", path
       RemoveDir(path)
 
+# -------------- update -------------------------------------------------------
+
+proc update(args: string) =
+  when defined(windows):
+    echo("Windows users: Make sure to be running this in Bash. ",
+         "If you aren't, press CTRL+C now.")
+
+  var thisDir = getAppDir()
+  var git = findExe("git")
+  echo("Checking for git repo and git executable...")
+  if existsDir(thisDir & "/.git") and git != "":
+    echo("Git repo found!")
+    # use git to download latest source
+    echo("Checking for updates...")
+    discard startCmd(git & " fetch origin master")
+    var procs = startCmd(git & " diff origin/master master")
+    var errcode = procs.waitForExit()
+    var output = readLine(procs.outputStream)
+    echo(output)
+    if errcode == 0:
+      if output == "":
+        # No changes
+        echo("No update. Exiting..")
+        return
+      else:
+        echo("Fetching updates from repo...")
+        var pullout = execCmdEx(git & " pull origin master")
+        if pullout[1] != 0:
+          quit("An error has occured.")
+        else:
+          if pullout[0].startsWith("Already up-to-date."):
+            quit("No new changes fetched from the repo. " &
+                 "Local branch must be ahead of it. Exiting...")
+    else:
+      quit("An error has occured.")
+    
+  else:
+    echo("No repo or executable found!")
+    when defined(haveZipLib):
+      echo("Falling back.. Downloading source code from repo...")
+      # use dom96's httpclient to download zip
+      downloadFile("https://github.com/Araq/Nimrod/zipball/master",
+                   thisDir / "update.zip")
+      try:
+        echo("Extracting source code from archive...")
+        var zip: TZipArchive
+        discard open(zip, thisDir & "/update.zip", fmRead)
+        extractAll(zip, thisDir & "/")
+      except:
+        quit("Error reading archive.")
+    else:
+      quit("No failback available. Exiting...")
+  
+  echo("Starting update...")
+  boot(args)
+  echo("Update complete!")
+
+# -------------- tests --------------------------------------------------------
+
 proc tests(args: string) =
   # we compile the tester with taintMode:on to have a basic
   # taint mode test :-)
diff --git a/tests/compile/tgeneric.nim b/tests/compile/tgeneric.nim
new file mode 100644
index 000000000..8bda15c42
--- /dev/null
+++ b/tests/compile/tgeneric.nim
@@ -0,0 +1,11 @@
+import tables
+
+type
+  TX = TTable[string, int]
+
+proc foo(models: seq[TTable[string, float]]): seq[float] =
+  result = @[]
+  for model in models.items:
+    result.add model["foobar"]
+
+
diff --git a/tests/compile/tgeneric2.nim b/tests/compile/tgeneric2.nim
new file mode 100644
index 000000000..b9b8e5a62
--- /dev/null
+++ b/tests/compile/tgeneric2.nim
@@ -0,0 +1,11 @@
+import tables
+
+type
+  TX = TTable[string, int]
+
+proc foo(models: seq[TX]): seq[int] =
+  result = @[]
+  for model in models.items:
+    result.add model["foobar"]
+
+
diff --git a/tests/compile/tgenericprop.nim b/tests/compile/tgenericprop.nim
new file mode 100644
index 000000000..211fddecf
--- /dev/null
+++ b/tests/compile/tgenericprop.nim
@@ -0,0 +1,12 @@
+
+type
+  TProperty[T] = object of TObject
+    getProc: proc(property: TProperty[T]): T
+    setProc: proc(property: TProperty[T], value: T)
+    value: T
+
+proc newProperty[T](value: TObject): TProperty[T] =
+  result.getProc = proc (property: TProperty[T]) =
+    return property.value
+
+