fix argument_parser

This commit is contained in:
Zahary Karadjov
2014-02-16 02:23:06 +02:00
parent f701ee086a
commit 74f4901430

View File

@@ -343,53 +343,57 @@ proc allowsNil(f: PType): TTypeRelation {.inline.} =
proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
result = f.kind != a.kind and (f.kind == tyVar or a.kind == tyVar)
proc procParamTypeRel(c: var TCandidate, f, a: PType,
result: var TTypeRelation) =
var
m: TTypeRelation
f = f
proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
var f = f
if a.isMetaType:
if f.isMetaType:
# we are matching a generic proc (as proc param)
# We are matching a generic proc (as proc param)
# to another generic type appearing in the proc
# sigunature. there is a change that the target
# signature. There is a change that the target
# type is already fully-determined, so we are
# going to try resolve it
f = generateTypeInstance(c.c, c.bindings, c.call.info, f)
if f == nil or f.isMetaType:
# no luck resolving the type, so the inference fails
result = isNone
return
return isNone
let reverseRel = typeRel(c, a, f)
if reverseRel == isGeneric:
m = isInferred
result = isInferred
inc c.genericMatches
else:
m = typeRel(c, f, a)
result = typeRel(c, f, a)
if m <= isSubtype or inconsistentVarTypes(f, a):
if result <= isSubtype or inconsistentVarTypes(f, a):
result = isNone
return
else:
result = minRel(m, result)
if result == isEqual:
inc c.exactMatches
proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
case a.kind
of tyProc:
if sonsLen(f) != sonsLen(a): return
# Note: We have to do unification for the parameters before the
# return type!
result = isEqual # start with maximum; also correct for no
# params at all
for i in countup(1, sonsLen(f)-1):
procParamTypeRel(c, f.sons[i], a.sons[i], result)
template checkParam(f, a) =
result = minRel(result, procParamTypeRel(c, f, a))
if result == isNone: return
# Note: We have to do unification for the parameters before the
# return type!
for i in 1 .. <f.sonsLen:
checkParam(f.sons[i], a.sons[i])
if f.sons[0] != nil:
if a.sons[0] != nil:
procParamTypeRel(c, f.sons[0], a.sons[0], result)
checkParam(f.sons[0], a.sons[0])
else:
return isNone
elif a.sons[0] != nil:
return isNone
if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags:
return isNone
elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
@@ -1101,6 +1105,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
# incorrect to simply use the first fitting match. However, to implement
# this correctly is inefficient. We have to copy `m` here to be able to
# roll back the side effects of the unification algorithm.
let c = m.c
var x, y, z: TCandidate
initCandidate(c, x, m.callee)
@@ -1122,10 +1127,10 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
x.state = csMatch
of csMatch:
var cmp = cmpCandidates(x, z)
if cmp < 0:
if cmp < 0:
best = i
x = z
elif cmp == 0:
elif cmp == 0:
y = z # z is as good as x
if x.state == csEmpty:
result = nil