fixes #4478
This commit is contained in:
parent
55db59a897
commit
d779a9b722
2 changed files with 49 additions and 9 deletions
|
|
@ -364,22 +364,43 @@ proc isObjectSubtype(a, f: PType): int =
|
||||||
if t != nil:
|
if t != nil:
|
||||||
result = depth
|
result = depth
|
||||||
|
|
||||||
proc skipToGenericBody(t: PType): PType =
|
type
|
||||||
|
SkippedPtr = enum skippedNone, skippedRef, skippedPtr
|
||||||
|
|
||||||
|
proc skipToGenericBody(t: PType; skipped: var SkippedPtr): PType =
|
||||||
var r = t
|
var r = t
|
||||||
|
# we're allowed to skip one level of ptr/ref:
|
||||||
|
var ptrs = 0
|
||||||
while r != nil:
|
while r != nil:
|
||||||
if r.kind in {tyGenericInst, tyGenericInvocation}:
|
case r.kind
|
||||||
return r.sons[0]
|
of tyGenericInst, tyGenericInvocation:
|
||||||
r = if r.len > 0: r.lastSon else: nil
|
result = r.sons[0]
|
||||||
|
break
|
||||||
|
of tyRef:
|
||||||
|
inc ptrs
|
||||||
|
skipped = skippedRef
|
||||||
|
r = r.lastSon
|
||||||
|
of tyPtr:
|
||||||
|
inc ptrs
|
||||||
|
skipped = skippedPtr
|
||||||
|
r = r.lastSon
|
||||||
|
of tyGenericBody:
|
||||||
|
r = r.lastSon
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
if ptrs > 1: result = nil
|
||||||
|
|
||||||
proc isGenericSubtype(a, f: PType, d: var int): bool =
|
proc isGenericSubtype(a, f: PType, d: var int): bool =
|
||||||
assert f.kind in {tyGenericInst, tyGenericInvocation, tyGenericBody}
|
assert f.kind in {tyGenericInst, tyGenericInvocation, tyGenericBody}
|
||||||
var t = if a.kind == tyGenericBody: a else: a.skipToGenericBody
|
var askip = skippedNone
|
||||||
var r = if f.kind == tyGenericBody: f else: f.skipToGenericBody
|
var fskip = skippedNone
|
||||||
|
var t = if a.kind == tyGenericBody: a else: a.skipToGenericBody(askip)
|
||||||
|
var r = if f.kind == tyGenericBody: f else: f.skipToGenericBody(fskip)
|
||||||
var depth = 0
|
var depth = 0
|
||||||
while t != nil and not sameObjectTypes(r, t):
|
while t != nil and not sameObjectTypes(r, t) and askip == fskip:
|
||||||
t = t.skipToGenericBody
|
t = t.skipToGenericBody(askip)
|
||||||
inc depth
|
inc depth
|
||||||
if t != nil:
|
if t != nil and askip == fskip:
|
||||||
d = depth
|
d = depth
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
|
|
||||||
19
tests/typerel/tgeneric_subtype_regression.nim
Normal file
19
tests/typerel/tgeneric_subtype_regression.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "type mismatch: got (FooRef[system.string])"
|
||||||
|
line: 15
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #4478
|
||||||
|
|
||||||
|
type
|
||||||
|
Foo[T] = object
|
||||||
|
FooRef[T] = ref Foo[T]
|
||||||
|
|
||||||
|
proc takeFoo[T](foo: Foo[T]): int = discard
|
||||||
|
|
||||||
|
proc g(x: FooRef[string]) =
|
||||||
|
echo x.takeFoo() != 8
|
||||||
|
|
||||||
|
var x: FooRef[string]
|
||||||
|
|
||||||
|
g(x)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue