diff options
author | Araq <rumpf_a@web.de> | 2011-09-20 00:56:48 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-09-20 00:56:48 +0200 |
commit | fd62116f6eb80d1dd3d6cc745d80629ad32dca1a (patch) | |
tree | ac5cbd102ffa580e322eda22deeef9298babae4a /compiler | |
parent | dc3ace4f379931f2af4dd4a3cd2a0984a94865af (diff) | |
download | Nim-fd62116f6eb80d1dd3d6cc745d80629ad32dca1a.tar.gz |
bugfixes for generics; new threads implementation still broken
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 8 | ||||
-rwxr-xr-x | compiler/astalgo.nim | 5 | ||||
-rwxr-xr-x | compiler/nimrod.nim | 14 | ||||
-rwxr-xr-x | compiler/pragmas.nim | 1 | ||||
-rwxr-xr-x | compiler/sem.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 5 | ||||
-rwxr-xr-x | compiler/seminst.nim | 15 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 7 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 75 | ||||
-rwxr-xr-x | compiler/semtypinst.nim | 100 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 13 | ||||
-rwxr-xr-x | compiler/types.nim | 26 |
12 files changed, 187 insertions, 84 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index e9bf532b1..bb9803830 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -279,8 +279,8 @@ type TTypeFlags* = set[TTypeFlag] - TSymKind* = enum # the different symbols (start with the prefix sk); - # order is important for the documentation generator! + TSymKind* = enum # the different symbols (start with the prefix sk); + # order is important for the documentation generator! skUnknown, # unknown symbol: used for parsing assembler blocks # and first phase symbol lookup in generics skConditional, # symbol for the preprocessor (may become obsolete) @@ -848,6 +848,10 @@ proc initNodeTable(x: var TNodeTable) = proc sonsLen(n: PType): int = if isNil(n.sons): result = 0 else: result = len(n.sons) + +proc len*(n: PType): int = + if isNil(n.sons): result = 0 + else: result = len(n.sons) proc newSons(father: PType, length: int) = if isNil(father.sons): father.sons = @[] diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 08b502af7..17875d524 100755 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -46,7 +46,6 @@ proc StrTableContains*(t: TStrTable, n: PSym): bool proc StrTableAdd*(t: var TStrTable, n: PSym) proc StrTableGet*(t: TStrTable, name: PIdent): PSym - # the iterator scheme: type TTabIter*{.final.} = object # consider all fields here private h*: THash # current hash @@ -749,6 +748,10 @@ proc IdTablePut(t: var TIdTable, key: PIdObj, val: PObject) = IdTableRawInsert(t.data, key, val) inc(t.counter) +iterator IdTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = + for i in 0 .. high(t.data): + if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) + proc writeIdNodeTable(t: TIdNodeTable) = nil diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 5c91329cd..3a910cfad 100755 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -49,6 +49,13 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) = if optRun notin gGlobalOptions and arguments != "": rawMessage(errArgsNeedRunOption, []) +proc prependCurDir(f: string): string = + when defined(unix): + if os.isAbsolute(f): result = f + else: result = "./" & f + else: + result = f + proc HandleCmdLine() = var start = epochTime() if paramCount() == 0: @@ -79,11 +86,8 @@ proc HandleCmdLine() = rawMessage(hintSuccessX, [$gLinesCompiled, formatFloat(epochTime() - start, ffDecimal, 3)]) if optRun in gGlobalOptions: - when defined(unix): - var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, "")) - else: - var prog = quoteIfContainsWhite(changeFileExt(filename, "")) - execExternalProgram(prog & ' ' & arguments) + var ex = quoteIfContainsWhite(changeFileExt(filename, "").prependCurDir) + execExternalProgram(ex & ' ' & arguments) #GC_disableMarkAndSweep() cmdLineInfo = newLineInfo("command line", -1, -1) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d5cbae4ab..039474266 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -53,6 +53,7 @@ const wExtern, wImportcpp, wImportobjc} procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect, wThread} + allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) proc pragmaAsm*(c: PContext, n: PNode): char diff --git a/compiler/sem.nim b/compiler/sem.nim index 5d2e1069f..c0ea23d2e 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -146,7 +146,7 @@ proc addCodeForGenerics(c: PContext, n: PNode) = addSon(n, prc.ast) lastGenericIdx = Len(generics) -proc semExprNoFlags(c: PContext, n: PNode): PNode = +proc semExprNoFlags(c: PContext, n: PNode): PNode {.procvar.} = result = semExpr(c, n, {}) proc myOpen(module: PSym, filename: string): PPassContext = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d116ede2e..f86a4f60d 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1178,9 +1178,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) - elif n.sons[0].kind == nkSymChoice: + elif n.sons[0].kind == nkSymChoice or n[0].kind == nkBracketExpr and + n[0][0].kind == nkSymChoice: result = semDirectOp(c, n, flags) - else: + else: result = semIndirectOp(c, n, flags) of nkMacroStmt: result = semMacroStmt(c, n) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 87f988ed9..d53d33898 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -29,6 +29,10 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, break if t.kind == tyGenericParam: InternalError(a.info, "instantiateGenericParamList: " & q.name.s) + elif t.kind == tyGenericInvokation: + #t = instGenericContainer(c, a, t) + t = generateTypeInstance(c, pt, a, t) + #t = ReplaceTypeVarsT(cl, t) s.typ = t addDecl(c, s) entry.concreteTypes[i] = t @@ -94,6 +98,14 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) = closeScope(c.tab) popInfoContext() +proc sideEffectsCheck(c: PContext, s: PSym) = + if {sfNoSideEffect, sfSideEffect} * s.flags == + {sfNoSideEffect, sfSideEffect}: + LocalError(s.info, errXhasSideEffects, s.name.s) + elif sfThread in s.flags and semthreads.needsGlobalAnalysis() and + s.ast.sons[genericParamsPos].kind == nkEmpty: + c.threadEntries.add(s) + proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym = # generates an instantiated proc @@ -133,7 +145,10 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, var oldPrc = GenericCacheGet(c, entry) if oldPrc == nil: generics.add(entry) + if n.sons[pragmasPos].kind != nkEmpty: + pragma(c, result, n.sons[pragmasPos], allRoutinePragmas) instantiateBody(c, n, result) + sideEffectsCheck(c, result) else: result = oldPrc popInfoContext() diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index c37706f3a..ce870a3ad 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -554,13 +554,6 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = n.sons[codePos] = newSymNode(b) else: LocalError(n.info, errNoSymbolToBorrowFromFound) - -proc sideEffectsCheck(c: PContext, s: PSym) = - if {sfNoSideEffect, sfSideEffect} * s.flags == - {sfNoSideEffect, sfSideEffect}: - LocalError(s.info, errXhasSideEffects, s.name.s) - elif sfThread in s.flags and semthreads.needsGlobalAnalysis(): - c.threadEntries.add(s) proc addResult(c: PContext, t: PType, info: TLineInfo) = if t != nil: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 7cdb32c79..9ff7ea27f 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -216,23 +216,6 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = addSon(result.n, newSymNode(field)) addSon(result, typ) -proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = - if s.typ == nil or s.typ.kind != tyGenericBody: - GlobalError(n.info, errCannotInstantiateX, s.name.s) - result = newOrPrevType(tyGenericInvokation, prev, c) - if s.typ.containerID == 0: InternalError(n.info, "semtypes.semGeneric") - if sonsLen(n) != sonsLen(s.typ): - GlobalError(n.info, errWrongNumberOfArguments) - addSon(result, s.typ) - var isConcrete = true # iterate over arguments: - for i in countup(1, sonsLen(n)-1): - var elem = semTypeNode(c, n.sons[i], nil) - if elem.kind in {tyGenericParam, tyGenericInvokation}: isConcrete = false - addSon(result, elem) - if isConcrete: - if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s) - result = instGenericContainer(c, n, result) - proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = # identifier with visibility @@ -489,7 +472,6 @@ proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode, if ContainsOrIncl(cl, t.id): return case t.kind of tyGenericBody: - #debug(t) result = newTypeS(tyGenericInvokation, c) addSon(result, t) for i in countup(0, sonsLen(t) - 2): @@ -505,11 +487,9 @@ proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode, addSon(genericParams, newSymNode(s)) addSon(result, t.sons[i]) of tyGenericInst: - #debug(t) var L = sonsLen(t) - 1 t.sons[L] = addTypeVarsOfGenericBody(c, t.sons[L], genericParams, cl) of tyGenericInvokation: - #debug(t) for i in countup(1, sonsLen(t) - 1): t.sons[i] = addTypeVarsOfGenericBody(c, t.sons[i], genericParams, cl) else: @@ -520,7 +500,6 @@ proc paramType(c: PContext, n, genericParams: PNode, cl: var TIntSet): PType = result = semTypeNode(c, n, nil) if genericParams != nil and sonsLen(genericParams) == 0: result = addTypeVarsOfGenericBody(c, result, genericParams, cl) - #if result.kind == tyGenericInvokation: debug(result) proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType): PType = @@ -546,6 +525,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, var length = sonsLen(a) if a.sons[length-2].kind != nkEmpty: typ = paramType(c, a.sons[length-2], genericParams, cl) + #if matchType(typ, [(tyVar, 0)], tyGenericInvokation): + # debug a.sons[length-2][0][1] + else: typ = nil if a.sons[length-1].kind != nkEmpty: @@ -557,8 +539,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, # and def.typ != nil and def.typ.kind != tyNone: # example code that triggers it: # proc sort[T](cmp: proc(a, b: T): int = cmp) - def = fitNode(c, typ, def) - else: + if not containsGenericType(typ): + def = fitNode(c, typ, def) + else: def = ast.emptyNode if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue for j in countup(0, length-3): @@ -578,6 +561,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if skipTypes(r, {tyGenericInst}).kind != tyEmpty: result.sons[0] = r res.typ = result.sons[0] + #if matchType(result, [(tyProc, 1), (tyVar, 0)], tyGenericInvokation): + # debug result proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = checkMinSonsLen(n, 1) @@ -603,6 +588,50 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType = closeScope(c.tab) Dec(c.p.nestedBlockCounter) +proc semGenericParamInInvokation(c: PContext, n: PNode): PType = + # XXX hack 1022 for generics ... would have been nice if the compiler had + # been designed with them in mind from start ... + when false: + if n.kind == nkSym: + # for generics we need to lookup the type var again: + var s = SymtabGet(c.Tab, n.sym.name) + if s != nil: + if s.kind == skType and s.typ != nil: + var t = n.sym.typ + echo "came here" + return t + else: + echo "s is crap:" + debug(s) + else: + echo "s is nil!!!!" + result = semTypeNode(c, n, nil) + +proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = + if s.typ == nil or s.typ.kind != tyGenericBody: + GlobalError(n.info, errCannotInstantiateX, s.name.s) + result = newOrPrevType(tyGenericInvokation, prev, c) + if s.typ.containerID == 0: InternalError(n.info, "semtypes.semGeneric") + if sonsLen(n) != sonsLen(s.typ): + GlobalError(n.info, errWrongNumberOfArguments) + addSon(result, s.typ) + var isConcrete = true # iterate over arguments: + for i in countup(1, sonsLen(n)-1): + var elem = semGenericParamInInvokation(c, n.sons[i]) + if containsGenericType(elem): isConcrete = false + #if elem.kind in {tyGenericParam, tyGenericInvokation}: isConcrete = false + addSon(result, elem) + if isConcrete: + if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s) + result = instGenericContainer(c, n, result) + +proc FixupRemainingGenericInvokations(c: PContext, n: PNode, + typ: PType): PType = + if typ.kind == tyGenericInvokation: + nil + else: + result = typ + proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = nil if gCmd == cmdIdeTools: suggestExpr(c, n) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 41ec8ddac..88697dc85 100755 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -92,51 +92,90 @@ proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) - if result == nil: + if result == nil: GlobalError(t.sym.info, errCannotInstantiateX, typeToString(t)) elif result.kind == tyGenericParam: InternalError(cl.info, "substitution with generic parameter") proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = + # tyGenericInvokation[A, tyGenericInvokation[A, B]] + # is difficult to handle: var body = t.sons[0] if body.kind != tyGenericBody: InternalError(cl.info, "no generic body") var header: PType = nil - for i in countup(1, sonsLen(t) - 1): - var x = replaceTypeVarsT(cl, t.sons[i]) - if t.sons[i].kind == tyGenericParam: - if header == nil: header = copyType(t, t.owner, false) + when true: + # search for some instantiation here: + result = searchInstTypes(gInstTypes, t) + if result != nil: return + for i in countup(1, sonsLen(t) - 1): + var x = t.sons[i] + if x.kind == tyGenericParam: + x = lookupTypeVar(cl, x) + if header == nil: header = copyType(t, t.owner, false) + header.sons[i] = x + #idTablePut(cl.typeMap, body.sons[i-1], x) + if header != nil: + # search again after first pass: + result = searchInstTypes(gInstTypes, header) + if result != nil: return + else: + header = copyType(t, t.owner, false) + # ugh need another pass for deeply recursive generic types (e.g. PActor) + # we need to add the candidate here, before it's fully instantiated for + # recursive instantions: + result = newType(tyGenericInst, t.sons[0].owner) + idTablePut(gInstTypes, header, result) + + for i in countup(1, sonsLen(t) - 1): + var x = replaceTypeVarsT(cl, t.sons[i]) + assert x.kind != tyGenericInvokation header.sons[i] = x - when false: - var x: PType + idTablePut(cl.typeMap, body.sons[i-1], x) + + for i in countup(0, sonsLen(t) - 1): + # if one of the params is not concrete, we cannot do anything + # but we already raised an error! + addSon(result, header.sons[i]) + + var newbody = ReplaceTypeVarsT(cl, lastSon(body)) + newbody.flags = newbody.flags + t.flags + body.flags + result.flags = result.flags + newbody.flags + newbody.callConv = body.callConv + newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n) + addSon(result, newbody) + checkPartialConstructedType(cl.info, newbody) + else: + for i in countup(1, sonsLen(t) - 1): + if PType(idTableGet(cl.typeMap, t.sons[i])) == nil: debug(t) + var x = replaceTypeVarsT(cl, t.sons[i]) if t.sons[i].kind == tyGenericParam: - x = lookupTypeVar(cl, t.sons[i]) if header == nil: header = copyType(t, t.owner, false) header.sons[i] = x - else: - x = t.sons[i] - idTablePut(cl.typeMap, body.sons[i-1], x) - if header == nil: header = t - result = searchInstTypes(gInstTypes, header) - if result != nil: return - result = newType(tyGenericInst, t.sons[0].owner) - for i in countup(0, sonsLen(t) - 1): - # if one of the params is not concrete, we cannot do anything - # but we already raised an error! - addSon(result, header.sons[i]) - idTablePut(gInstTypes, header, result) - var newbody = ReplaceTypeVarsT(cl, lastSon(body)) - newbody.flags = newbody.flags + t.flags + body.flags - newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n) - addSon(result, newbody) - #writeln(output, ropeToStr(Typetoyaml(newbody))); - checkPartialConstructedType(cl.info, newbody) + assert x.kind != tyGenericInvokation + idTablePut(cl.typeMap, body.sons[i-1], x) + if header == nil: header = t + result = searchInstTypes(gInstTypes, header) + if result != nil: return + result = newType(tyGenericInst, t.sons[0].owner) + for i in countup(0, sonsLen(t) - 1): + # if one of the params is not concrete, we cannot do anything + # but we already raised an error! + addSon(result, header.sons[i]) + idTablePut(gInstTypes, header, result) + var newbody = ReplaceTypeVarsT(cl, lastSon(body)) + newbody.flags = newbody.flags + t.flags + body.flags + newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n) + addSon(result, newbody) + checkPartialConstructedType(cl.info, newbody) proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = result = t if t == nil: return case t.kind - of tyGenericParam: + of tyGenericParam: result = lookupTypeVar(cl, t) + if result.kind == tyGenericInvokation: + result = handleGenericInvokation(cl, result) of tyGenericInvokation: result = handleGenericInvokation(cl, t) of tyGenericBody: @@ -151,9 +190,10 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = result.n = ReplaceTypeVarsN(cl, result.n) if result.Kind in GenericTypes: LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName)) - #writeln(output, ropeToStr(Typetoyaml(result))) - #checkConstructedType(cl.info, result) - + if result.kind == tyProc and result.sons[0] != nil: + if result.sons[0].kind == tyEmpty: + result.sons[0] = nil + proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, t: PType): PType = var cl: TReplTypeVars diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9acf83a46..1e93385d9 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -137,6 +137,8 @@ proc concreteType(mapping: TIdTable, t: PType): PType = # example code that triggers it: # proc sort[T](cmp: proc(a, b: T): int = cmp) if result.kind != tyGenericParam: break + of tyGenericInvokation: + assert false else: result = t # Note: empty is valid here @@ -388,8 +390,10 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = of tyGenericInvokation: assert(f.sons[0].kind == tyGenericBody) if a.kind == tyGenericInvokation: - InternalError("typeRel: tyGenericInvokation -> tyGenericInvokation") - if (a.kind == tyGenericInst): + #InternalError("typeRel: tyGenericInvokation -> tyGenericInvokation") + # simply no match for now: + nil + elif a.kind == tyGenericInst: if (f.sons[0].containerID == a.sons[0].containerID) and (sonsLen(a) - 1 == sonsLen(f)): assert(a.sons[0].kind == tyGenericBody) @@ -404,7 +408,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = # we steal the generic parameters from the tyGenericBody: for i in countup(1, sonsLen(f) - 1): var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1])) - if x == nil or x.kind == tyGenericParam: + if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: InternalError("wrong instantiated type!") idTablePut(mapping, f.sons[i], x) of tyGenericParam: @@ -413,8 +417,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = if sonsLen(f) == 0: # no constraints var concrete = concreteType(mapping, a) - if concrete != nil: - #MessageOut('putting: ' + f.sym.name.s); + if concrete != nil: idTablePut(mapping, f, concrete) result = isGeneric else: diff --git a/compiler/types.nim b/compiler/types.nim index 692b7f61b..d8d0caf35 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -728,7 +728,16 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool = else: for i in countup(0, sonsLen(n) - 1): result = typeAllowedNode(marker, n.sons[i], kind) - if not result: return + if not result: break + +proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], + last: TTypeKind): bool = + var a = a + for k, i in pattern.items: + if a.kind != k: return false + if i >= a.sonslen or a.sons[i] == nil: return false + a = a.sons[i] + result = a.kind == last proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = assert(kind in {skVar, skConst, skParam, skResult}) @@ -751,13 +760,14 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = of tyProc: for i in countup(1, sonsLen(t) - 1): result = typeAllowedAux(marker, t.sons[i], skParam) - if not result: return - if t.sons[0] != nil: result = typeAllowedAux(marker, t.sons[0], skResult) + if not result: break + if result and t.sons[0] != nil: + result = typeAllowedAux(marker, t.sons[0], skResult) of tyExpr, tyStmt, tyTypeDesc: result = true of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation: result = false #InternalError('shit found'); - of tyEmpty, tyNil: + of tyEmpty, tyNil: result = kind == skConst of tyString, tyBool, tyChar, tyEnum, tyInt..tyFloat128, tyCString, tyPointer: result = true @@ -781,13 +791,13 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = of tyArrayConstr, tyTuple, tySet: for i in countup(0, sonsLen(t) - 1): result = typeAllowedAux(marker, t.sons[i], kind) - if not result: return + if not result: break of tyObject: for i in countup(0, sonsLen(t) - 1): result = typeAllowedAux(marker, t.sons[i], skVar) - if not result: return - if t.n != nil: result = typeAllowedNode(marker, t.n, skVar) - + if not result: break + if result and t.n != nil: result = typeAllowedNode(marker, t.n, skVar) + proc typeAllowed(t: PType, kind: TSymKind): bool = var marker = InitIntSet() result = typeAllowedAux(marker, t, kind) |