a simple way to simulate covariance in generic types

This commit is contained in:
Zahary Karadjov 2017-04-28 17:40:57 +03:00
commit c981284ddc
2 changed files with 17 additions and 1 deletions

View file

@ -956,6 +956,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
case a.kind case a.kind
of tyOr: of tyOr:
# XXX: deal with the current dual meaning of tyGenericParam
c.typedescMatched = true
# seq[int|string] vs seq[number] # seq[int|string] vs seq[number]
# both int and string must match against number # both int and string must match against number
# but ensure that '[T: A|A]' matches as good as '[T: A]' (bug #2219): # but ensure that '[T: A|A]' matches as good as '[T: A]' (bug #2219):
@ -964,15 +966,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
let x = typeRel(c, f, branch, false) let x = typeRel(c, f, branch, false)
if x == isNone: return isNone if x == isNone: return isNone
if x < result: result = x if x < result: result = x
return
of tyAnd: of tyAnd:
# XXX: deal with the current dual meaning of tyGenericParam
c.typedescMatched = true
# seq[Sortable and Iterable] vs seq[Sortable] # seq[Sortable and Iterable] vs seq[Sortable]
# only one match is enough # only one match is enough
for branch in a.sons: for branch in a.sons:
let x = typeRel(c, f, branch, false) let x = typeRel(c, f, branch, false)
if x != isNone: if x != isNone:
return if x >= isGeneric: isGeneric else: x return if x >= isGeneric: isGeneric else: x
result = isNone return isNone
of tyNot: of tyNot:
case f.kind case f.kind

View file

@ -0,0 +1,11 @@
type
BaseObj = object of RootObj
DerivedObj = object of BaseObj
Container[T] = object
proc doSomething(c: Container[BaseObj or DerivedObj]) = discard
var t: Container[DerivedObj]
doSomething t