diff options
author | Araq <rumpf_a@web.de> | 2011-06-17 01:04:33 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-06-17 01:04:33 +0200 |
commit | 849208d779e860230bb8682b3b356ba2942dd889 (patch) | |
tree | bc6428bf782f9d47e121177c0e5f300062b3f1aa /compiler | |
parent | dc6a80bd1d36b158a090ed0fb622140856be3dfe (diff) | |
download | Nim-849208d779e860230bb8682b3b356ba2942dd889.tar.gz |
got rid of unsound co/contravariance in procvars
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/sigmatch.nim | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index c9ab27123..ac1429e4e 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -189,6 +189,39 @@ proc constraintRel(mapping: var TIdTable, f, a: PType): TTypeRelation = result = isNone if f.kind == a.kind: result = 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) + + case a.kind + of tyNil: result = isSubtype + of tyProc: + if sonsLen(f) != sonsLen(a) or f.callconv != a.callconv: 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): + var m = typeRel(mapping, f.sons[i], a.sons[i]) + if m <= isSubtype or inconsistentVarTypes(f.sons[i], a.sons[i]): + return isNone + else: result = minRel(m, result) + if f.sons[0] != nil: + if a.sons[0] != nil: + var m = typeRel(mapping, f.sons[0], a.sons[0]) + # Subtype is sufficient for return types! + if m < isSubtype or inconsistentVarTypes(f.sons[0], a.sons[0]): + result = isNone + elif m == isSubtype: result = isConvertible + else: result = minRel(m, result) + else: + result = isNone + elif a.sons[0] != nil: + result = isNone + if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: + result = isNone + else: nil + proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = # is a subtype of f? result = isNone @@ -316,39 +349,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = of tyNil: result = isSubtype else: nil of tyProc: - case a.kind - of tyNil: result = isSubtype - of tyProc: - if (sonsLen(f) == sonsLen(a)) and (f.callconv == a.callconv): - # 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 - var m: TTypeRelation - for i in countup(1, sonsLen(f) - 1): - m = typeRel(mapping, f.sons[i], a.sons[i]) - if (m == isNone) and - (typeRel(mapping, a.sons[i], f.sons[i]) == isSubtype): - # allow ``f.son`` as subtype of ``a.son``! - result = isConvertible - elif m < isSubtype: - return isNone - else: - result = minRel(m, result) - if f.sons[0] != nil: - if a.sons[0] != nil: - m = typeRel(mapping, f.sons[0], a.sons[0]) - # Subtype is sufficient for return types! - if m < isSubtype: result = isNone - elif m == isSubtype: result = isConvertible - else: result = minRel(m, result) - else: - result = isNone - elif a.sons[0] != nil: - result = isNone - if (tfNoSideEffect in f.flags) and not (tfNoSideEffect in a.flags): - result = isNone - else: nil + result = procTypeRel(mapping, f, a) of tyPointer: case a.kind of tyPointer: result = isEqual |