diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-05-25 20:46:50 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-05-26 11:14:23 +0300 |
commit | aea27a7ce4a263122e0a053afa864ee76baaf8d5 (patch) | |
tree | f639c5ac55585eef78e2b6f0ca4116e6938c0a14 /compiler | |
parent | 420789c2782be7b969ad02448841d90bd0d17a1f (diff) | |
download | Nim-aea27a7ce4a263122e0a053afa864ee76baaf8d5.tar.gz |
allow `void` as a field type
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgtypes.nim | 3 | ||||
-rw-r--r-- | compiler/types.nim | 65 |
2 files changed, 42 insertions, 26 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 427b0ec86..3e2ebd736 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -437,8 +437,9 @@ proc genRecordFieldsAux(m: BModule, n: PNode, app(result, genRecordFieldsAux(m, k, ae, rectype, check)) else: internalError("genRecordFieldsAux(record case branch)") appf(result, "} $1;$n", [uname]) - of nkSym: + of nkSym: field = n.sym + if field.typ.kind == tyEmpty: return #assert(field.ast == nil) sname = mangleRecFieldName(field, rectype) if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname]) diff --git a/compiler/types.nim b/compiler/types.nim index 731c1f12a..2ca735b0d 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -926,11 +926,21 @@ proc commonSuperclass*(a, b: PType): PType = if ancestors.contains(y.id): return y y = y.sons[0] -proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool -proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool = +type + TTypeAllowedFlag = enum + taField, + taHeap + + TTypeAllowedFlags = set[TTypeAllowedFlag] + +proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, + flags: TTypeAllowedFlags = {}): bool + +proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind, + flags: TTypeAllowedFlags = {}): bool = result = true if n != nil: - result = typeAllowedAux(marker, n.typ, kind) + result = typeAllowedAux(marker, n.typ, kind, flags) #if not result: debug(n.typ) if result: case n.kind @@ -938,7 +948,7 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool = nil else: for i in countup(0, sonsLen(n) - 1): - result = typeAllowedNode(marker, n.sons[i], kind) + result = typeAllowedNode(marker, n.sons[i], kind, flags) if not result: break proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], @@ -990,7 +1000,8 @@ proc matchTypeClass*(typeClass, typ: PType): bool = initIdTable(bindings) result = matchTypeClass(bindings, typeClass, typ) -proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = +proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, + flags: TTypeAllowedFlags = {}): bool = assert(kind in {skVar, skLet, skConst, skParam, skResult}) # if we have already checked the type, return true, because we stop the # evaluation if something is wrong: @@ -1004,66 +1015,70 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc}) case t2.kind of tyVar: - result = false # ``var var`` is always an invalid type: + result = taHeap in flags # ``var var`` is illegal on the heap: of tyOpenArray: - result = kind == skParam and typeAllowedAux(marker, t2, kind) + result = kind == skParam and typeAllowedAux(marker, t2, kind, flags) else: - result = kind in {skParam, skResult} and typeAllowedAux(marker, t2, kind) + result = kind in {skParam, skResult} and + typeAllowedAux(marker, t2, kind, flags) of tyProc: for i in countup(1, sonsLen(t) - 1): - result = typeAllowedAux(marker, t.sons[i], skParam) + result = typeAllowedAux(marker, t.sons[i], skParam, flags) if not result: break if result and t.sons[0] != nil: - result = typeAllowedAux(marker, t.sons[0], skResult) + result = typeAllowedAux(marker, t.sons[0], skResult, flags) of tyExpr, tyStmt, tyTypeDesc: result = true # XXX er ... no? these should not be allowed! + of tyEmpty: + result = taField in flags of tyTypeClass: result = true of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation: result = false - of tyEmpty, tyNil: + of tyNil: result = kind == skConst of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer: result = true of tyOrdinal: result = kind == skParam of tyGenericInst, tyDistinct: - result = typeAllowedAux(marker, lastSon(t), kind) + result = typeAllowedAux(marker, lastSon(t), kind, flags) of tyRange: result = skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind in {tyChar, tyEnum, tyInt..tyFloat128} of tyOpenArray, tyVarargs: - result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar) + result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar, flags) of tySequence: result = t.sons[0].kind == tyEmpty or - typeAllowedAux(marker, t.sons[0], skVar) + typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap}) of tyArray: result = t.sons[1].kind == tyEmpty or - typeAllowedAux(marker, t.sons[1], skVar) + typeAllowedAux(marker, t.sons[1], skVar, flags) of tyRef: if kind == skConst: return false - result = typeAllowedAux(marker, t.sons[0], skVar) + result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap}) of tyPtr: - result = typeAllowedAux(marker, t.sons[0], skVar) - of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter: + result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap}) + of tyArrayConstr, tySet, tyConst, tyMutable, tyIter: for i in countup(0, sonsLen(t) - 1): - result = typeAllowedAux(marker, t.sons[i], kind) + result = typeAllowedAux(marker, t.sons[i], kind, flags) if not result: break - of tyObject: - if kind == skConst: return false + of tyObject, tyTuple: + if kind == skConst and t.kind == tyObject: return false + let flags = flags+{taField} for i in countup(0, sonsLen(t) - 1): - result = typeAllowedAux(marker, t.sons[i], kind) + result = typeAllowedAux(marker, t.sons[i], kind, flags) if not result: break - if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind) + if result and t.n != nil: result = typeAllowedNode(marker, t.n, kind, flags) of tyProxy: # for now same as error node; we say it's a valid type as it should # prevent cascading errors: result = true - + proc typeAllowed(t: PType, kind: TSymKind): bool = var marker = InitIntSet() - result = typeAllowedAux(marker, t, kind) + result = typeAllowedAux(marker, t, kind, {}) proc align(address, alignment: biggestInt): biggestInt = result = (address + (alignment - 1)) and not (alignment - 1) |