diff options
-rw-r--r-- | compiler/procfind.nim | 26 | ||||
-rw-r--r-- | compiler/semtypes.nim | 16 | ||||
-rw-r--r-- | compiler/types.nim | 36 |
3 files changed, 48 insertions, 30 deletions
diff --git a/compiler/procfind.nim b/compiler/procfind.nim index f02e7aed4..eb0cbca3f 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -30,7 +30,7 @@ proc equalGenericParams(procA, procB: PNode): bool = if not exprStructuralEquivalent(a.ast, b.ast): return result = true -proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = +proc searchForProcOld*(c: PContext, scope: PScope, fn: PSym): PSym = # Searchs for a forward declaration or a "twin" symbol of fn # in the symbol table. If the parameter lists are exactly # the same the sym in the symbol table is returned, else nil. @@ -63,6 +63,30 @@ proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = nil result = nextIdentIter(it, scope.symbols) +proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym = + const flags = {ExactGenericParams, ExactTypeDescValues, + ExactConstraints, IgnoreCC} + + var it: TIdentIter + result = initIdentIter(it, scope.symbols, fn.name) + while result != nil: + if result.kind in skProcKinds and + sameType(result.typ, fn.typ, flags): return + + result = nextIdentIter(it, scope.symbols) + + return nil + +proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = + result = searchForProcNew(c, scope, fn) + when false: + let old = searchForProcOld(c, scope, fn) + if old != result: + echo "Mismatch in searchForProc: ", fn.info + debug fn.typ + debug if result != nil: result.typ else: nil + debug if old != nil: old.typ else: nil + when false: proc paramsFitBorrow(child, parent: PNode): bool = var length = sonsLen(child) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 03d8b7095..175901057 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -827,22 +827,6 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType = 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 = searchInScopes(c, 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 = diff --git a/compiler/types.nim b/compiler/types.nim index 024cf4549..7403e29f9 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -606,8 +606,10 @@ type TTypeCmpFlag* = enum IgnoreTupleFields + IgnoreCC ExactTypeDescValues ExactGenericParams + ExactConstraints AllowCommonBase TTypeCmpFlags* = set[TTypeCmpFlag] @@ -637,15 +639,17 @@ proc sameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool = if a == nil or b == nil: result = false else: result = sameTypeAux(a, b, c) +proc sameType*(a, b: PType, flags: TTypeCmpFlags = {}): bool = + var c = initSameTypeClosure() + c.flags = flags + result = sameTypeAux(a, b, c) + proc sameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool = if a == b: result = true - else: + else: if a == nil or b == nil: result = false - else: - var c = initSameTypeClosure() - c.flags = flags - result = sameTypeAux(a, b, c) + else: result = sameType(a, b, flags) proc equalParam(a, b: PSym): TParamsEquality = if sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}) and @@ -661,7 +665,15 @@ proc equalParam(a, b: PSym): TParamsEquality = result = paramsIncompatible else: result = paramsNotEqual - + +proc sameConstraints(a, b: PNode): bool = + internalAssert a.len == b.len + for i in 1 .. <a.len: + if not exprStructuralEquivalent(a[i].sym.constraint, + b[i].sym.constraint): + return false + return true + proc equalParams(a, b: PNode): TParamsEquality = result = paramsEqual var length = sonsLen(a) @@ -860,8 +872,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = else: result = sameFlags(a, b) of tyGenericParam: - result = if ExactGenericParams in c.flags: a.id == b.id - else: sameChildrenAux(a, b, c) and sameFlags(a, b) + result = sameChildrenAux(a, b, c) and sameFlags(a, b) + if result and ExactGenericParams in c.flags: + result = a.sym.position == b.sym.position of tyGenericInvokation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, @@ -869,7 +882,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = cycleCheck() result = sameChildrenAux(a, b, c) and sameFlags(a, b) if result and a.kind == tyProc: - result = a.callConv == b.callConv + result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and + ((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n)) of tyRange: cycleCheck() result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and @@ -877,10 +891,6 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = sameValue(a.n.sons[1], b.n.sons[1]) of tyNone: result = false -proc sameType*(x, y: PType): bool = - var c = initSameTypeClosure() - result = sameTypeAux(x, y, c) - proc sameBackendType*(x, y: PType): bool = var c = initSameTypeClosure() c.flags.incl IgnoreTupleFields |