proc redefinition search based on the type system instead of on sloppy AST matching
This will work the same for procs/templates/macros/etc, having arbitrary mix of implicit and explicit generics (as long as the symbols are equivalent for the purposes of overload resolution, they will be detected as redefinitions) fixes tgeneric
This commit is contained in:
parent
fa3bb8d66b
commit
e3f53409f6
3 changed files with 48 additions and 30 deletions
|
|
@ -30,7 +30,7 @@ proc equalGenericParams(procA, procB: PNode): bool =
|
||||||
if not exprStructuralEquivalent(a.ast, b.ast): return
|
if not exprStructuralEquivalent(a.ast, b.ast): return
|
||||||
result = true
|
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
|
# Searchs for a forward declaration or a "twin" symbol of fn
|
||||||
# in the symbol table. If the parameter lists are exactly
|
# in the symbol table. If the parameter lists are exactly
|
||||||
# the same the sym in the symbol table is returned, else nil.
|
# 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
|
nil
|
||||||
result = nextIdentIter(it, scope.symbols)
|
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:
|
when false:
|
||||||
proc paramsFitBorrow(child, parent: PNode): bool =
|
proc paramsFitBorrow(child, parent: PNode): bool =
|
||||||
var length = sonsLen(child)
|
var length = sonsLen(child)
|
||||||
|
|
|
||||||
|
|
@ -827,22 +827,6 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
|
||||||
dec(c.p.nestedBlockCounter)
|
dec(c.p.nestedBlockCounter)
|
||||||
|
|
||||||
proc semGenericParamInInvokation(c: PContext, n: PNode): PType =
|
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)
|
result = semTypeNode(c, n, nil)
|
||||||
|
|
||||||
proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
|
|
|
||||||
|
|
@ -606,8 +606,10 @@ type
|
||||||
|
|
||||||
TTypeCmpFlag* = enum
|
TTypeCmpFlag* = enum
|
||||||
IgnoreTupleFields
|
IgnoreTupleFields
|
||||||
|
IgnoreCC
|
||||||
ExactTypeDescValues
|
ExactTypeDescValues
|
||||||
ExactGenericParams
|
ExactGenericParams
|
||||||
|
ExactConstraints
|
||||||
AllowCommonBase
|
AllowCommonBase
|
||||||
|
|
||||||
TTypeCmpFlags* = set[TTypeCmpFlag]
|
TTypeCmpFlags* = set[TTypeCmpFlag]
|
||||||
|
|
@ -637,15 +639,17 @@ proc sameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool =
|
||||||
if a == nil or b == nil: result = false
|
if a == nil or b == nil: result = false
|
||||||
else: result = sameTypeAux(a, b, c)
|
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 =
|
proc sameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
|
||||||
if a == b:
|
if a == b:
|
||||||
result = true
|
result = true
|
||||||
else:
|
else:
|
||||||
if a == nil or b == nil: result = false
|
if a == nil or b == nil: result = false
|
||||||
else:
|
else: result = sameType(a, b, flags)
|
||||||
var c = initSameTypeClosure()
|
|
||||||
c.flags = flags
|
|
||||||
result = sameTypeAux(a, b, c)
|
|
||||||
|
|
||||||
proc equalParam(a, b: PSym): TParamsEquality =
|
proc equalParam(a, b: PSym): TParamsEquality =
|
||||||
if sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}) and
|
if sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}) and
|
||||||
|
|
@ -662,6 +666,14 @@ proc equalParam(a, b: PSym): TParamsEquality =
|
||||||
else:
|
else:
|
||||||
result = paramsNotEqual
|
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 =
|
proc equalParams(a, b: PNode): TParamsEquality =
|
||||||
result = paramsEqual
|
result = paramsEqual
|
||||||
var length = sonsLen(a)
|
var length = sonsLen(a)
|
||||||
|
|
@ -860,8 +872,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
else:
|
else:
|
||||||
result = sameFlags(a, b)
|
result = sameFlags(a, b)
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
result = if ExactGenericParams in c.flags: a.id == b.id
|
result = sameChildrenAux(a, b, c) and sameFlags(a, b)
|
||||||
else: 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,
|
of tyGenericInvokation, tyGenericBody, tySequence,
|
||||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr,
|
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr,
|
||||||
tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter,
|
tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter,
|
||||||
|
|
@ -869,7 +882,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
cycleCheck()
|
cycleCheck()
|
||||||
result = sameChildrenAux(a, b, c) and sameFlags(a, b)
|
result = sameChildrenAux(a, b, c) and sameFlags(a, b)
|
||||||
if result and a.kind == tyProc:
|
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:
|
of tyRange:
|
||||||
cycleCheck()
|
cycleCheck()
|
||||||
result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
|
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])
|
sameValue(a.n.sons[1], b.n.sons[1])
|
||||||
of tyNone: result = false
|
of tyNone: result = false
|
||||||
|
|
||||||
proc sameType*(x, y: PType): bool =
|
|
||||||
var c = initSameTypeClosure()
|
|
||||||
result = sameTypeAux(x, y, c)
|
|
||||||
|
|
||||||
proc sameBackendType*(x, y: PType): bool =
|
proc sameBackendType*(x, y: PType): bool =
|
||||||
var c = initSameTypeClosure()
|
var c = initSameTypeClosure()
|
||||||
c.flags.incl IgnoreTupleFields
|
c.flags.incl IgnoreTupleFields
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue