bugfix: type alias to generic; generic type not stripped away from for loop variable

This commit is contained in:
Araq
2012-01-07 20:03:41 +01:00
parent 0e22a51095
commit 7405278138
8 changed files with 118 additions and 69 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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:

117
koch.nim
View File

@@ -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 :-)

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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