overloading resolution finally takes inheritance depth into account

This commit is contained in:
Araq 2012-07-11 00:10:24 +02:00
commit e2f8d91290
3 changed files with 78 additions and 66 deletions

View file

@ -32,6 +32,7 @@ type
bindings*: TIdTable # maps types to types bindings*: TIdTable # maps types to types
baseTypeMatch: bool # needed for conversions from T to openarray[T] baseTypeMatch: bool # needed for conversions from T to openarray[T]
# for example # for example
inheritancePenalty: int # to prefer closest father object type
TTypeRelation* = enum # order is important! TTypeRelation* = enum # order is important!
isNone, isConvertible, isNone, isConvertible,
@ -53,6 +54,7 @@ proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} =
c.callee = callee c.callee = callee
c.call = nil c.call = nil
c.baseTypeMatch = false c.baseTypeMatch = false
c.inheritancePenalty = 0
proc initCandidate*(c: var TCandidate, callee: PType) = proc initCandidate*(c: var TCandidate, callee: PType) =
initCandidateAux(c, callee) initCandidateAux(c, callee)
@ -100,6 +102,9 @@ proc cmpCandidates*(a, b: TCandidate): int =
if result != 0: return if result != 0: return
if (a.calleeScope != -1) and (b.calleeScope != -1): if (a.calleeScope != -1) and (b.calleeScope != -1):
result = a.calleeScope - b.calleeScope result = a.calleeScope - b.calleeScope
if result != 0: return
# the other way round because of other semantics:
result = b.inheritancePenalty - a.inheritancePenalty
proc writeMatches*(c: TCandidate) = proc writeMatches*(c: TCandidate) =
Writeln(stdout, "exact matches: " & $c.exactMatches) Writeln(stdout, "exact matches: " & $c.exactMatches)
@ -133,8 +138,8 @@ proc getNotFoundError*(c: PContext, n: PNode): string =
if candidates != "": if candidates != "":
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation
proc concreteType(mapping: TIdTable, t: PType): PType = proc concreteType(c: TCandidate, t: PType): PType =
case t.kind case t.kind
of tyArrayConstr: of tyArrayConstr:
# make it an array # make it an array
@ -146,7 +151,7 @@ proc concreteType(mapping: TIdTable, t: PType): PType =
of tyGenericParam: of tyGenericParam:
result = t result = t
while true: while true:
result = PType(idTableGet(mapping, t)) result = PType(idTableGet(c.bindings, t))
if result == nil: if result == nil:
break # it's ok, no match break # it's ok, no match
# example code that triggers it: # example code that triggers it:
@ -204,28 +209,31 @@ proc handleFloatRange(f, a: PType): TTypeRelation =
elif k >= tyFloat and k <= tyFloat128: result = isConvertible elif k >= tyFloat and k <= tyFloat128: result = isConvertible
else: result = isNone else: result = isNone
proc isObjectSubtype(a, f: PType): bool = proc isObjectSubtype(a, f: PType): int =
var t = a var t = a
assert t.kind == tyObject assert t.kind == tyObject
var depth = 0
while t != nil and not sameObjectTypes(f, t): while t != nil and not sameObjectTypes(f, t):
assert t.kind == tyObject assert t.kind == tyObject
t = t.sons[0] t = t.sons[0]
if t == nil: break if t == nil: break
t = skipTypes(t, {tyGenericInst}) t = skipTypes(t, {tyGenericInst})
result = t != nil inc depth
if t != nil:
result = depth
proc minRel(a, b: TTypeRelation): TTypeRelation = proc minRel(a, b: TTypeRelation): TTypeRelation =
if a <= b: result = a if a <= b: result = a
else: result = b else: result = b
proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation = proc tupleRel(c: var TCandidate, f, a: PType): TTypeRelation =
result = isNone result = isNone
if sameType(f, a): if sameType(f, a):
result = isEqual result = isEqual
elif sonsLen(a) == sonsLen(f): elif sonsLen(a) == sonsLen(f):
result = isEqual result = isEqual
for i in countup(0, sonsLen(f) - 1): for i in countup(0, sonsLen(f) - 1):
var m = typeRel(mapping, f.sons[i], a.sons[i]) var m = typeRel(c, f.sons[i], a.sons[i])
if m < isSubtype: return isNone if m < isSubtype: return isNone
result = minRel(result, m) result = minRel(result, m)
if f.n != nil and a.n != nil: if f.n != nil and a.n != nil:
@ -237,7 +245,7 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
var y = a.n.sons[i].sym var y = a.n.sons[i].sym
if x.name.id != y.name.id: return isNone if x.name.id != y.name.id: return isNone
proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation = proc matchTypeClass(c: var TCandidate, f, a: PType): TTypeRelation =
for i in countup(0, f.sonsLen - 1): for i in countup(0, f.sonsLen - 1):
let son = f.sons[i] let son = f.sons[i]
var match = son.kind == skipTypes(a, {tyRange}).kind var match = son.kind == skipTypes(a, {tyRange}).kind
@ -247,9 +255,9 @@ proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation =
of tyGenericBody: of tyGenericBody:
if a.kind == tyGenericInst and a.sons[0] == son: if a.kind == tyGenericInst and a.sons[0] == son:
match = true match = true
put(mapping, f, a) put(c.bindings, f, a)
of tyTypeClass: of tyTypeClass:
match = matchTypeClass(mapping, son, a) == isGeneric match = matchTypeClass(c, son, a) == isGeneric
else: nil else: nil
if tfAny in f.flags: if tfAny in f.flags:
@ -263,7 +271,7 @@ proc matchTypeClass(mapping: var TIdTable, f, a: PType): TTypeRelation =
# or none of them matched. # or none of them matched.
result = if tfAny in f.flags: isNone else: isGeneric result = if tfAny in f.flags: isNone else: isGeneric
proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
proc inconsistentVarTypes(f, a: PType): bool {.inline.} = proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
result = f.kind != a.kind and (f.kind == tyVar or a.kind == tyVar) result = f.kind != a.kind and (f.kind == tyVar or a.kind == tyVar)
@ -276,13 +284,13 @@ proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
result = isEqual # start with maximum; also correct for no result = isEqual # start with maximum; also correct for no
# params at all # params at all
for i in countup(1, sonsLen(f)-1): for i in countup(1, sonsLen(f)-1):
var m = typeRel(mapping, f.sons[i], a.sons[i]) var m = typeRel(c, f.sons[i], a.sons[i])
if m <= isSubtype or inconsistentVarTypes(f.sons[i], a.sons[i]): if m <= isSubtype or inconsistentVarTypes(f.sons[i], a.sons[i]):
return isNone return isNone
else: result = minRel(m, result) else: result = minRel(m, result)
if f.sons[0] != nil: if f.sons[0] != nil:
if a.sons[0] != nil: if a.sons[0] != nil:
var m = typeRel(mapping, f.sons[0], a.sons[0]) var m = typeRel(c, f.sons[0], a.sons[0])
# Subtype is sufficient for return types! # Subtype is sufficient for return types!
if m < isSubtype or inconsistentVarTypes(f.sons[0], a.sons[0]): if m < isSubtype or inconsistentVarTypes(f.sons[0], a.sons[0]):
result = isNone result = isNone
@ -305,7 +313,7 @@ proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
result = isNone result = isNone
else: nil else: nil
proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
# is a subtype of f? # is a subtype of f?
result = isNone result = isNone
assert(f != nil) assert(f != nil)
@ -314,9 +322,9 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
skipTypes(f, {tyVar}).kind notin { skipTypes(f, {tyVar}).kind notin {
tyGenericBody, tyGenericInvokation, tyGenericBody, tyGenericInvokation,
tyGenericParam, tyTypeClass}: tyGenericParam, tyTypeClass}:
return typeRel(mapping, f, lastSon(a)) return typeRel(c, f, lastSon(a))
if a.kind == tyVar and f.kind != tyVar: if a.kind == tyVar and f.kind != tyVar:
return typeRel(mapping, f, a.sons[0]) return typeRel(c, f, a.sons[0])
case f.kind case f.kind
of tyEnum: of tyEnum:
if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual
@ -326,7 +334,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
elif skipTypes(a, {tyRange}).kind == f.kind: result = isSubtype elif skipTypes(a, {tyRange}).kind == f.kind: result = isSubtype
of tyRange: of tyRange:
if a.kind == f.kind: if a.kind == f.kind:
result = typeRel(mapping, base(f), base(a)) result = typeRel(c, base(f), base(a))
# bugfix: accept integer conversions here # bugfix: accept integer conversions here
#if result < isGeneric: result = isNone #if result < isGeneric: result = isNone
elif skipTypes(f, {tyRange}).kind == a.kind: elif skipTypes(f, {tyRange}).kind == a.kind:
@ -348,45 +356,45 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
of tyFloat64: result = handleFloatRange(f, a) of tyFloat64: result = handleFloatRange(f, a)
of tyFloat128: result = handleFloatRange(f, a) of tyFloat128: result = handleFloatRange(f, a)
of tyVar: of tyVar:
if a.kind == f.kind: result = typeRel(mapping, base(f), base(a)) if a.kind == f.kind: result = typeRel(c, base(f), base(a))
else: result = typeRel(mapping, base(f), a) else: result = typeRel(c, base(f), a)
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
# tyArrayConstr cannot happen really, but # tyArrayConstr cannot happen really, but
# we wanna be safe here # we wanna be safe here
case a.kind case a.kind
of tyArray: of tyArray:
result = minRel(typeRel(mapping, f.sons[0], a.sons[0]), result = minRel(typeRel(c, f.sons[0], a.sons[0]),
typeRel(mapping, f.sons[1], a.sons[1])) typeRel(c, f.sons[1], a.sons[1]))
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
of tyArrayConstr: of tyArrayConstr:
result = typeRel(mapping, f.sons[1], a.sons[1]) result = typeRel(c, f.sons[1], a.sons[1])
if result < isGeneric: if result < isGeneric:
result = isNone result = isNone
else: else:
if (result != isGeneric) and (lengthOrd(f) != lengthOrd(a)): if (result != isGeneric) and (lengthOrd(f) != lengthOrd(a)):
result = isNone result = isNone
elif f.sons[0].kind in GenericTypes: elif f.sons[0].kind in GenericTypes:
result = minRel(result, typeRel(mapping, f.sons[0], a.sons[0])) result = minRel(result, typeRel(c, f.sons[0], a.sons[0]))
else: nil else: nil
of tyOpenArray: of tyOpenArray:
case a.Kind case a.Kind
of tyOpenArray: of tyOpenArray:
result = typeRel(mapping, base(f), base(a)) result = typeRel(c, base(f), base(a))
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
of tyArrayConstr: of tyArrayConstr:
if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty):
result = isSubtype # [] is allowed here result = isSubtype # [] is allowed here
elif typeRel(mapping, base(f), a.sons[1]) >= isGeneric: elif typeRel(c, base(f), a.sons[1]) >= isGeneric:
result = isSubtype result = isSubtype
of tyArray: of tyArray:
if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty):
result = isSubtype result = isSubtype
elif typeRel(mapping, base(f), a.sons[1]) >= isGeneric: elif typeRel(c, base(f), a.sons[1]) >= isGeneric:
result = isConvertible result = isConvertible
of tySequence: of tySequence:
if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
result = isConvertible result = isConvertible
elif typeRel(mapping, base(f), a.sons[0]) >= isGeneric: elif typeRel(c, base(f), a.sons[0]) >= isGeneric:
result = isConvertible result = isConvertible
else: nil else: nil
of tySequence: of tySequence:
@ -397,23 +405,27 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
result = isSubtype result = isSubtype
else: else:
result = typeRel(mapping, f.sons[0], a.sons[0]) result = typeRel(c, f.sons[0], a.sons[0])
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
else: nil else: nil
of tyOrdinal: of tyOrdinal:
if isOrdinalType(a): if isOrdinalType(a):
var x = if a.kind == tyOrdinal: a.sons[0] else: a var x = if a.kind == tyOrdinal: a.sons[0] else: a
result = typeRel(mapping, f.sons[0], x) result = typeRel(c, f.sons[0], x)
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
of tyForward: InternalError("forward type in typeRel()") of tyForward: InternalError("forward type in typeRel()")
of tyNil: of tyNil:
if a.kind == f.kind: result = isEqual if a.kind == f.kind: result = isEqual
of tyTuple: of tyTuple:
if a.kind == tyTuple: result = tupleRel(mapping, f, a) if a.kind == tyTuple: result = tupleRel(c, f, a)
of tyObject: of tyObject:
if a.kind == tyObject: if a.kind == tyObject:
if sameObjectTypes(f, a): result = isEqual if sameObjectTypes(f, a): result = isEqual
elif isObjectSubtype(a, f): result = isSubtype else:
var depth = isObjectSubtype(a, f)
if depth > 0:
inc(c.inheritancePenalty, depth)
result = isSubtype
of tyDistinct: of tyDistinct:
if (a.kind == tyDistinct) and sameDistinctTypes(f, a): result = isEqual if (a.kind == tyDistinct) and sameDistinctTypes(f, a): result = isEqual
of tySet: of tySet:
@ -421,25 +433,25 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty): if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
result = isSubtype result = isSubtype
else: else:
result = typeRel(mapping, f.sons[0], a.sons[0]) result = typeRel(c, f.sons[0], a.sons[0])
if result <= isConvertible: if result <= isConvertible:
result = isNone # BUGFIX! result = isNone # BUGFIX!
of tyPtr: of tyPtr:
case a.kind case a.kind
of tyPtr: of tyPtr:
result = typeRel(mapping, base(f), base(a)) result = typeRel(c, base(f), base(a))
if result <= isConvertible: result = isNone if result <= isConvertible: result = isNone
of tyNil: result = isSubtype of tyNil: result = isSubtype
else: nil else: nil
of tyRef: of tyRef:
case a.kind case a.kind
of tyRef: of tyRef:
result = typeRel(mapping, base(f), base(a)) result = typeRel(c, base(f), base(a))
if result <= isConvertible: result = isNone if result <= isConvertible: result = isNone
of tyNil: result = isSubtype of tyNil: result = isSubtype
else: nil else: nil
of tyProc: of tyProc:
result = procTypeRel(mapping, f, a) result = procTypeRel(c, f, a)
of tyPointer: of tyPointer:
case a.kind case a.kind
of tyPointer: result = isEqual of tyPointer: result = isEqual
@ -468,10 +480,10 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
of tyEmpty: of tyEmpty:
if a.kind == tyEmpty: result = isEqual if a.kind == tyEmpty: result = isEqual
of tyGenericInst: of tyGenericInst:
result = typeRel(mapping, lastSon(f), a) result = typeRel(c, lastSon(f), a)
of tyGenericBody: of tyGenericBody:
let ff = lastSon(f) let ff = lastSon(f)
if ff != nil: result = typeRel(mapping, ff, a) if ff != nil: result = typeRel(c, ff, a)
of tyGenericInvokation: of tyGenericInvokation:
assert(f.sons[0].kind == tyGenericBody) assert(f.sons[0].kind == tyGenericBody)
if a.kind == tyGenericInvokation: if a.kind == tyGenericInvokation:
@ -485,40 +497,40 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
for i in countup(1, sonsLen(f) - 1): for i in countup(1, sonsLen(f) - 1):
if a.sons[i].kind == tyGenericParam: if a.sons[i].kind == tyGenericParam:
InternalError("wrong instantiated type!") InternalError("wrong instantiated type!")
if typeRel(mapping, f.sons[i], a.sons[i]) <= isSubtype: return if typeRel(c, f.sons[i], a.sons[i]) <= isSubtype: return
result = isGeneric result = isGeneric
else: else:
result = typeRel(mapping, f.sons[0], a) result = typeRel(c, f.sons[0], a)
if result != isNone: if result != isNone:
# we steal the generic parameters from the tyGenericBody: # we steal the generic parameters from the tyGenericBody:
for i in countup(1, sonsLen(f) - 1): for i in countup(1, sonsLen(f) - 1):
var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1])) var x = PType(idTableGet(c.bindings, f.sons[0].sons[i - 1]))
if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}:
InternalError("wrong instantiated type!") InternalError("wrong instantiated type!")
put(mapping, f.sons[i], x) put(c.bindings, f.sons[i], x)
of tyGenericParam, tyTypeClass: of tyGenericParam, tyTypeClass:
var x = PType(idTableGet(mapping, f)) var x = PType(idTableGet(c.bindings, f))
if x == nil: if x == nil:
result = matchTypeClass(mapping, f, a) result = matchTypeClass(c, f, a)
if result == isGeneric: if result == isGeneric:
var concrete = concreteType(mapping, a) var concrete = concreteType(c, a)
if concrete == nil: if concrete == nil:
result = isNone result = isNone
else: else:
put(mapping, f, concrete) put(c.bindings, f, concrete)
elif a.kind == tyEmpty: elif a.kind == tyEmpty:
result = isGeneric result = isGeneric
elif x.kind == tyGenericParam: elif x.kind == tyGenericParam:
result = isGeneric result = isGeneric
else: else:
result = typeRel(mapping, x, a) # check if it fits result = typeRel(c, x, a) # check if it fits
of tyTypeDesc: of tyTypeDesc:
if a.kind == tyTypeDesc: if a.kind == tyTypeDesc:
if f.sonsLen == 0: if f.sonsLen == 0:
result = isGeneric result = isGeneric
else: else:
result = matchTypeClass(mapping, f, a.sons[0]) result = matchTypeClass(c, f, a.sons[0])
if result == isGeneric: put(mapping, f, a) if result == isGeneric: put(c.bindings, f, a)
else: else:
result = isNone result = isNone
of tyExpr, tyStmt: of tyExpr, tyStmt:
@ -526,9 +538,9 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
else: internalError("typeRel(" & $f.kind & ')') else: internalError("typeRel(" & $f.kind & ')')
proc cmpTypes*(f, a: PType): TTypeRelation = proc cmpTypes*(f, a: PType): TTypeRelation =
var mapping: TIdTable var c: TCandidate
InitIdTable(mapping) InitCandidate(c, f)
result = typeRel(mapping, f, a) result = typeRel(c, f, a)
proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
f: PType): PType = f: PType): PType =
@ -552,8 +564,8 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
for i in countup(0, len(c.converters) - 1): for i in countup(0, len(c.converters) - 1):
var src = c.converters[i].typ.sons[1] var src = c.converters[i].typ.sons[1]
var dest = c.converters[i].typ.sons[0] var dest = c.converters[i].typ.sons[0]
if (typeRel(m.bindings, f, dest) == isEqual) and if (typeRel(m, f, dest) == isEqual) and
(typeRel(m.bindings, src, a) == isEqual): (typeRel(m, src, a) == isEqual):
markUsed(arg, c.converters[i]) markUsed(arg, c.converters[i])
var s = newSymNode(c.converters[i]) var s = newSymNode(c.converters[i])
s.typ = c.converters[i].typ s.typ = c.converters[i].typ
@ -572,7 +584,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
if f.sonsLen == 0: if f.sonsLen == 0:
r = isGeneric r = isGeneric
else: else:
let match = matchTypeClass(m.bindings, f, a) let match = matchTypeClass(m, f, a)
if match != isGeneric: r = isNone if match != isGeneric: r = isNone
else: else:
# XXX: Ideally, this should happen much earlier somewhere near # XXX: Ideally, this should happen much earlier somewhere near
@ -590,7 +602,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
if r == isGeneric: if r == isGeneric:
put(m.bindings, f, arg.typ) put(m.bindings, f, arg.typ)
else: else:
r = typeRel(m.bindings, f, a) r = typeRel(m, f, a)
case r case r
of isConvertible: of isConvertible:
@ -633,7 +645,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
# check for a base type match, which supports openarray[T] without [] # check for a base type match, which supports openarray[T] without []
# constructor in a call: # constructor in a call:
if result == nil and f.kind == tyOpenArray: if result == nil and f.kind == tyOpenArray:
r = typeRel(m.bindings, base(f), a) r = typeRel(m, base(f), a)
if r >= isGeneric: if r >= isGeneric:
inc(m.convMatches) inc(m.convMatches)
result = copyTree(arg) result = copyTree(arg)
@ -663,7 +675,7 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
# iterators are not first class yet, so ignore them # iterators are not first class yet, so ignore them
if arg.sons[i].sym.kind in {skProc, skMethod, skConverter}: if arg.sons[i].sym.kind in {skProc, skMethod, skConverter}:
copyCandidate(z, m) copyCandidate(z, m)
var r = typeRel(z.bindings, f, arg.sons[i].typ) var r = typeRel(z, f, arg.sons[i].typ)
if r != isNone: if r != isNone:
case x.state case x.state
of csEmpty, csNoMatch: of csEmpty, csNoMatch:
@ -687,7 +699,8 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
else: else:
# only one valid interpretation found: # only one valid interpretation found:
markUsed(arg, arg.sons[best].sym) markUsed(arg, arg.sons[best].sym)
result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best], argOrig) result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best],
argOrig)
proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode = proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode =
var m: TCandidate var m: TCandidate

View file

@ -1,5 +1,5 @@
discard """ discard """
disabled: true output: "b"
""" """
type type
@ -12,8 +12,8 @@ type
TC = object of TB TC = object of TB
whatever: string whatever: string
proc p(a: var TA) = nil proc p(a: var TA) = echo "a"
proc p(b: var TB) = nil proc p(b: var TB) = echo "b"
var c: TC var c: TC

View file

@ -1,7 +1,6 @@
version 0.9.0 version 0.9.0
============= =============
- change overloading resolution: toop.nim test
- implicit ref/ptr->var conversion - implicit ref/ptr->var conversion
- deprecate ``var x, y = 0`` as it's confusing for tuple consistency - deprecate ``var x, y = 0`` as it's confusing for tuple consistency
- finish support for unsigned ints: - finish support for unsigned ints: