diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-03-29 16:03:51 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-03-31 18:50:48 +0300 |
commit | 22dc76a361c70af93403dfbf2610c8d49111637c (patch) | |
tree | e04bfd670534fa2bbd8924746cba656da00fde66 /compiler | |
parent | 6216046bc6b2794d15705f5d2621f602bda636c4 (diff) | |
download | Nim-22dc76a361c70af93403dfbf2610c8d49111637c.tar.gz |
typedesc and expr params
types are now valid proc/template/macro params and you can overload over them: proc foo(T: typedesc) # accept any type proc foo(T: typedesc{int}) # overload specifically for int proc foo(T: typedesc{int or float or Callable}) # overload for any type matching the constraints expr{type} is a param expecting compile time value of the designated type (or type class). when typedesc or expr params are used with a proc, the proc will be instantiated once for each unique type/value used as parameter.
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 9 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 1 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 8 | ||||
-rwxr-xr-x | compiler/cgen.nim | 1 | ||||
-rwxr-xr-x | compiler/msgs.nim | 2 | ||||
-rwxr-xr-x | compiler/sem.nim | 2 | ||||
-rwxr-xr-x | compiler/semdata.nim | 10 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 42 | ||||
-rwxr-xr-x | compiler/seminst.nim | 2 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 34 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 79 | ||||
-rwxr-xr-x | compiler/types.nim | 21 |
12 files changed, 166 insertions, 45 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index edaf7d88a..a9407c91e 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -711,6 +711,15 @@ proc `[]`*(n: PNode, i: int): PNode {.inline.} = var emptyNode* = newNode(nkEmpty) # There is a single empty node that is shared! Do not overwrite it! +proc linkTo*(t: PType, s: PSym): PType {.discardable.} = + t.sym = s + s.typ = t + result = t + +proc linkTo*(s: PSym, t: PType): PSym {.discardable.} = + t.sym = s + s.typ = t + result = s const # for all kind of hash tables: GrowthFactor* = 2 # must be power of 2, > 0 diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 072b2f9fb..cb6014626 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -130,6 +130,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) = var length = sonsLen(ri) for i in countup(1, length - 1): assert(sonsLen(typ) == sonsLen(typ.n)) + if ri.sons[i].typ.isCompileTimeOnly: continue if i < sonsLen(typ): assert(typ.n.sons[i].kind == nkSym) app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym)) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 4207e4dba..78b02c691 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -7,6 +7,8 @@ # distribution, for details about the copyright. # +# included from cgen.nim + # ------------------------- Name Mangling -------------------------------- proc mangle(name: string): string = @@ -48,6 +50,9 @@ proc mangleName(s: PSym): PRope = app(result, toRope(s.id)) s.loc.r = result +proc isCompileTimeOnly(t: PType): bool = + result = t.kind in {tyTypedesc, tyExpr} + proc getTypeName(typ: PType): PRope = if (typ.sym != nil) and ({sfImportc, sfExportc} * typ.sym.flags != {}) and (gCmd != cmdCompileToLLVM): @@ -187,6 +192,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, for i in countup(1, sonsLen(t.n) - 1): if t.n.sons[i].kind != nkSym: InternalError(t.n.info, "genProcParams") var param = t.n.sons[i].sym + if isCompileTimeOnly(param.typ): continue fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack) app(params, getParamTypeDesc(m, param.typ, check)) if ccgIntroducedPtr(param): @@ -206,8 +212,8 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, arr = arr.sons[0] if i < sonsLen(t.n) - 1: app(params, ", ") if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]): - if params != nil: app(params, ", ") var arr = t.sons[0] + if params != nil: app(params, ", ") app(params, getTypeDescAux(m, arr, check)) if (mapReturnType(t.sons[0]) != ctArray) or (gCmd == cmdCompileToLLVM): app(params, "*") diff --git a/compiler/cgen.nim b/compiler/cgen.nim index e9d7673bb..0c1d721c0 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -606,6 +606,7 @@ proc genProcAux(m: BModule, prc: PSym) = res.loc.s = OnUnknown for i in countup(1, sonsLen(prc.typ.n) - 1): var param = prc.typ.n.sons[i].sym + if param.typ.isCompileTimeOnly: continue assignParam(p, param) closureSetup(p, prc) genStmts(p, prc.getBody) # modifies p.locals, p.init, etc. diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 84978ecf9..df9064ab2 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -663,7 +663,7 @@ proc InternalError*(errMsg: string) = writeContext(UnknownLineInfo()) rawMessage(errInternal, errMsg) -template AssertNotNull*(e: expr): expr = +template AssertNotNil*(e: expr): expr = if(e == nil): InternalError($InstantiationInfo()) e diff --git a/compiler/sem.nim b/compiler/sem.nim index 7d296dbfc..e27f20503 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -91,7 +91,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode = proc semAndEvalConstExpr(c: PContext, n: PNode): PNode = result = semConstExpr(c, n) - + include seminst, semcall proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 49ab20290..80aed2fd4 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -180,14 +180,16 @@ proc addToLib(lib: PLib, sym: PSym) = sym.annex = lib proc makePtrType(c: PContext, baseType: PType): PType = - if (baseType == nil): InternalError("makePtrType") result = newTypeS(tyPtr, c) - addSon(result, baseType) + addSon(result, baseType.AssertNotNil) proc makeVarType(c: PContext, baseType: PType): PType = - if (baseType == nil): InternalError("makeVarType") result = newTypeS(tyVar, c) - addSon(result, baseType) + addSon(result, baseType.AssertNotNil) + +proc makeTypeDesc*(c: PContext, typ: PType): PType = + result = newTypeS(tyTypeDesc, c) + result.addSon(typ.AssertNotNil) proc newTypeS(kind: TTypeKind, c: PContext): PType = result = newType(kind, getCurrOwner()) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index f5ceee7c0..0282c6c53 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -10,6 +10,8 @@ # this module does the semantic checking for expressions # included from sem.nim +proc semExprOrTypedesc(c: PContext, n: PNode): PNode + proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode = markUsed(n, s) pushInfoContext(n.info) @@ -93,6 +95,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # if a proc accesses a global variable, it is not side effect free: if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect) + elif s.kind == skParam and s.typ.kind == tyExpr: + return s.typ.n elif s.owner != c.p.owner and s.owner.kind != skModule and c.p.owner.typ != nil and not IsGenericRoutine(s.owner): c.p.owner.typ.callConv = ccClosure @@ -111,7 +115,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = else: markUsed(n, s) result = newSymNode(s, n.info) - + proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) = var diff = inheritanceDiff(castDest, src) if diff == high(int): @@ -247,16 +251,31 @@ proc semIs(c: PContext, n: PNode): PNode = else: GlobalError(n.info, errXExpectsTwoArguments, "is") +proc semExprOrTypedesc(c: PContext, n: PNode): PNode = + # XXX: Currently, semExprWithType will return the same type + # for nodes such as (100) or (int). + # This is inappropriate. The type of the first expression + # should be "int", while the type of the second one should + # be typeDesc(int). + # Ideally, this should be fixed in semExpr, but right now + # there are probably users that depend on the present behavior. + # XXX: Investigate current uses of efAllowType and fix them to + # work with tyTypeDesc. + result = semExprWithType(c, n, {efAllowType}) + if result.kind == nkSym and result.sym.kind == skType and + result.typ.kind != tyTypeDesc: + result.typ = makeTypeDesc(c, result.typ) + proc semOpAux(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkExprEqExpr and sonsLen(a) == 2: var info = a.sons[0].info a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info) - a.sons[1] = semExprWithType(c, a.sons[1], {efAllowType}) + a.sons[1] = semExprOrTypedesc(c, a.sons[1]) a.typ = a.sons[1].typ else: - n.sons[i] = semExprWithType(c, a, {efAllowType}) + n.sons[i] = semExprOrTypedesc(c, a) proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: @@ -822,7 +841,7 @@ proc semDeref(c: PContext, n: PNode): PNode = of tyRef, tyPtr: n.typ = t.sons[0] else: result = nil #GlobalError(n.sons[0].info, errCircumNeedsPointer) - + proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if not a built-in subscript operator; also called for the ## checking of assignments @@ -833,7 +852,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result.add(x[0]) return checkMinSonsLen(n, 2) - n.sons[0] = semExprWithType(c, n.sons[0], flags - {efAllowType}) + n.sons[0] = semExprOrTypedesc(c, n.sons[0]) var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) case arr.kind of tyArray, tyOpenArray, tyArrayConstr, tySequence, tyString, tyCString: @@ -848,6 +867,11 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result = n result.typ = elemType(arr) #GlobalError(n.info, errIndexTypesDoNotMatch) + of tyTypeDesc: + result = n.sons[0] # The result so far is a tyTypeDesc bound to + # a tyGenericBody. The line below will substitute + # it with the instantiated type. + result.typ.sons[0] = semTypeNode(c, n, nil).linkTo(result.sym) of tyTuple: checkSonsLen(n, 2) n.sons[0] = makeDeref(n.sons[0]) @@ -1024,7 +1048,7 @@ proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, markUsed(n, expandedSym) for i in countup(1, macroCall.len-1): - macroCall.sons[i] = semExprWithType(c, macroCall[i], {efAllowType}) + macroCall.sons[i] = semExprWithType(c, macroCall[i], {}) # Preserve the magic symbol in order to be handled in evals.nim n.sons[0] = newSymNode(magicSym, n.info) @@ -1287,6 +1311,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkBind: Message(n.info, warnDeprecated, "bind") result = semExpr(c, n.sons[0], flags) + of nkTypeOfExpr: + var typ = semTypeNode(c, n, nil) + if typ.sym == nil: + typ = copyType(typ, typ.owner, true) + typ.linkTo(newSym(skType, getIdent"typedesc", typ.owner)) + result = newSymNode(typ.sym, n.info) of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: # check if it is an expression macro: checkMinSonsLen(n, 1) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index bc8c1d964..85c68923c 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -20,7 +20,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, if a.kind != nkSym: InternalError(a.info, "instantiateGenericParamList; no symbol") var q = a.sym - if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyTypeClass}: continue + if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyTypeClass, tyExpr}: continue var s = newSym(skType, q.name, getCurrOwner()) s.info = q.info s.flags = s.flags + {sfUsed, sfFromGeneric} diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4c6bc36a3..40176ad50 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -180,6 +180,8 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = result = qualifiedLookup(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: markUsed(n, result) + if result.kind == skParam and result.typ.kind == tyTypeDesc: + return result.typ.sons[0].sym if result.kind != skType: GlobalError(n.info, errTypeExpected) if result.typ.kind != tyGenericParam: # XXX get rid of this hack! @@ -490,9 +492,20 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind): # if id is not nil, the generic param will bind just once (see below) case paramType.kind: of tyExpr: - # proc(a, b: expr) if procKind notin {skTemplate, skMacro}: - result.typ = newTypeS(tyGenericParam, c) + if paramType.sonsLen == 0: + # proc(a, b: expr) + # no constraints, treat like generic param + result.typ = newTypeS(tyGenericParam, c) + else: + # proc(a: expr{string}, b: expr{nkLambda}) + # overload on compile time values and AST trees + result.typ = newTypeS(tyExpr, c) + result.typ.sons = paramType.sons + of tyTypeDesc: + if procKind notin {skTemplate, skMacro}: + result.typ = newTypeS(tyTypeDesc, c) + result.typ.sons = paramType.sons of tyDistinct: # type T1 = distinct expr # type S1 = distinct Sortable @@ -565,7 +578,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if genericParams == nil: # genericParams is nil when the proc is being instantiated # the resolved type will be in scope then - endingType = SymtabGet(c.tab, paramTypId).AssertNotNull.typ + endingType = SymtabGet(c.tab, paramTypId).AssertNotNil.typ else: block addImplicitGeneric: # is this a bindOnce type class already present in the param list? @@ -664,9 +677,10 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if s.ast == nil: GlobalError(n.info, errCannotInstantiateX, s.name.s) result = instGenericContainer(c, n, result) -proc semExpandToType(c: PContext, n: PNode, sym: PSym): PType = +proc semTypeFromMacro(c: PContext, n: PNode): PType = # Expands a macro or template until a type is returned # results in GlobalError if the macro expands to something different + var sym = expectMacroOrTemplateCall(c, n) markUsed(n, sym) case sym.kind of skMacro: @@ -676,7 +690,7 @@ proc semExpandToType(c: PContext, n: PNode, sym: PSym): PType = else: GlobalError(n.info, errXisNoMacroOrTemplate, n.renderTree) -proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = +proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = nil if gCmd == cmdIdeTools: suggestExpr(c, n) case n.kind @@ -703,9 +717,13 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result.addSon(t2) result.flags.incl(if op == ord(wAnd): tfAll else: tfAny) else: - # expand macros and templates - var expandedSym = expectMacroOrTemplateCall(c, n) - result = semExpandToType(c, n, expandedSym) + result = semTypeFromMacro(c, n) + of nkCurlyExpr: + result = semTypeNode(c, n.sons[0], nil) + if result != nil: + result = copyType(result, getCurrOwner(), false) + for i in countup(1, n.len - 1): + result.addSon(semTypeNode(c, n.sons[i], nil)) of nkWhenStmt: var whenResult = semWhen(c, n, false) if whenResult.kind == nkStmtList: whenResult.kind = nkStmtListType diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 767bf3cb8..da804c2cb 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -35,7 +35,7 @@ type TTypeRelation* = enum # order is important! isNone, isConvertible, isIntConv, isSubtype, - isGeneric, + isGeneric isEqual proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = @@ -208,16 +208,32 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation = var y = a.n.sons[i].sym if x.name.id != y.name.id: return isNone -proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation = - result = isNone - let son = f.sons[0] - if son.kind == a.kind: - result = isGeneric - elif son.kind == tyGenericBody: - if a.kind == tyGenericInst and a.sons[0] == son: - result = isGeneric - put(mapping, f, a) +proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation = + for i in countup(0, f.sonsLen - 1): + let son = f.sons[i] + var match = son.kind == a.kind + + if not match: + case son.kind + of tyGenericBody: + if a.kind == tyGenericInst and a.sons[0] == son: + match = true + put(mapping, f, a) + of tyTypeClass: + match = matchTypeClass(mapping, son, a) == isGeneric + else: nil + + if tfAny in f.flags: + if match == true: + return isGeneric + else: + if match == false: + return isNone + # if the loop finished without returning, either all constraints matched + # or none of them matched. + result = if tfAny in f.flags: isNone else: isGeneric + proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = proc inconsistentVarTypes(f, a: PType): bool {.inline.} = result = f.kind != a.kind and (f.kind == tyVar or a.kind == tyVar) @@ -347,8 +363,6 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = result = typeRel(mapping, f.sons[0], a.sons[0]) if result < isGeneric: result = isNone else: nil - of tyTypeClass: - result = matchTypeClass(mapping, f, a) of tyOrdinal: if isOrdinalType(a): var x = if a.kind == tyOrdinal: a.sons[0] else: a @@ -469,7 +483,19 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = result = isGeneric else: result = typeRel(mapping, x, a) # check if it fits - of tyExpr, tyStmt, tyTypeDesc: + of tyTypeClass: + result = matchTypeClass(mapping, f, a) + if result == isGeneric: put(mapping, f, a) + of tyTypeDesc: + if a.kind == tyTypeDesc: + if f.sonsLen == 0: + result = isGeneric + else: + result = matchTypeClass(mapping, f, a.sons[0]) + if result == isGeneric: put(mapping, f, a) + else: + result = isNone + of tyExpr, tyStmt: result = isGeneric else: internalError("typeRel(" & $f.kind & ')') @@ -512,9 +538,34 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType, inc(m.convMatches) return + proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, arg, argOrig: PNode): PNode = - var r = typeRel(m.bindings, f, a) + var r: TTypeRelation + if f.kind == tyExpr: + if f.sonsLen == 0: + r = isGeneric + else: + let match = matchTypeClass(m.bindings, f, a) + if match != isGeneric: r = isNone + else: + # XXX: Ideally, this should happen much earlier somewhere near + # semOpAux, but to do that, we need to be able to query the + # overload set to determine whether compile-time value is expected + # for the param before entering the full-blown sigmatch algorithm. + # This is related to the immediate pragma since querying the + # overload set could help there too. + var evaluated = c.semConstExpr(c, arg) + if evaluated != nil: + r = isGeneric + arg.typ = newTypeS(tyExpr, c) + arg.typ.n = evaluated + + if r == isGeneric: + put(m.bindings, f, arg.typ) + else: + r = typeRel(m.bindings, f, a) + case r of isConvertible: inc(m.convMatches) diff --git a/compiler/types.nim b/compiler/types.nim index 5b3a1e289..6b25a388f 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -48,15 +48,15 @@ proc equalParams*(a, b: PNode): TParamsEquality proc isOrdinalType*(t: PType): bool proc enumHasHoles*(t: PType): bool const - abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, + abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable} - abstractVar* = {tyVar, tyGenericInst, tyDistinct, + abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable} - abstractRange* = {tyGenericInst, tyRange, tyDistinct, + abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable} - abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, + abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal, tyConst, tyMutable} - abstractInst* = {tyGenericInst, tyDistinct, tyConst, tyMutable} + abstractInst* = {tyGenericInst, tyDistinct, tyConst, tyMutable, tyOrdinal} skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable} @@ -142,7 +142,7 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType = proc isOrdinalType(t: PType): bool = assert(t != nil) result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or - (t.Kind in {tyRange, tyConst, tyMutable, tyGenericInst}) and + (t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and isOrdinalType(t.sons[0]) proc enumHasHoles(t: PType): bool = @@ -730,8 +730,10 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = if a.kind != b.kind: return false case a.Kind of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, - tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc, tyOrdinal: + tyInt..tyBigNum, tyStmt: result = true + of tyExpr: + result = ExprStructuralEquivalent(a.n, b.n) of tyObject: IfFastObjectTypeCheckFailed(a, b): CycleCheck() @@ -740,7 +742,7 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = CycleCheck() if c.cmp == dcEq: result = sameDistinctTypes(a, b) else: result = sameTypeAux(a.sons[0], b.sons[0], c) - of tyEnum, tyForward, tyProxy, tyTypeClass: + of tyEnum, tyForward, tyProxy: # XXX generic enums do not make much sense, but require structural checking result = a.id == b.id of tyTuple: @@ -749,7 +751,8 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = of tyGenericInst: result = sameTypeAux(lastSon(a), lastSon(b), c) of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, - tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter: + tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, + tyOrdinal, tyTypeDesc, tyTypeClass: if sonsLen(a) == sonsLen(b): CycleCheck() result = true |