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