mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
@@ -1014,7 +1014,7 @@ proc skipGenericInvocation(t: PType): PType {.inline.} =
|
||||
proc tryAddInheritedFields(c: PContext, check: var IntSet, pos: var int,
|
||||
obj: PType, n: PNode, isPartial = false, innerObj: PType = nil): bool =
|
||||
if ((not isPartial) and (obj.kind notin {tyObject, tyGenericParam} or tfFinal in obj.flags)) or
|
||||
(innerObj != nil and obj.sym.id == innerObj.sym.id):
|
||||
(innerObj != nil and obj.id == innerObj.id):
|
||||
localError(c.config, n.info, "Cannot inherit from: '" & $obj & "'")
|
||||
result = false
|
||||
elif obj.kind == tyObject:
|
||||
|
||||
@@ -1678,7 +1678,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
elif a.kind == tyGenericInst:
|
||||
if roota.base == rootf.base:
|
||||
let nextFlags = flags + {trNoCovariance}
|
||||
var hasCovariance = false
|
||||
# YYYY
|
||||
result = isEqual
|
||||
|
||||
@@ -1690,7 +1689,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
if res notin {isEqual, isGeneric}:
|
||||
if trNoCovariance notin flags and ff.kind == aa.kind:
|
||||
let paramFlags = rootf.base[i-1].flags
|
||||
hasCovariance =
|
||||
let hasCovariance =
|
||||
if tfCovariant in paramFlags:
|
||||
if tfWeakCovariant in paramFlags:
|
||||
isCovariantPtr(c, ff, aa)
|
||||
@@ -1701,35 +1700,36 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
typeRel(c, aa, ff, flags) == isSubtype
|
||||
if hasCovariance:
|
||||
continue
|
||||
result = isNone
|
||||
break
|
||||
|
||||
return isNone
|
||||
if prev == nil: put(c, f, a)
|
||||
else:
|
||||
let fKind = rootf.last.kind
|
||||
if fKind in {tyAnd, tyOr}:
|
||||
result = typeRel(c, last(f), a, flags)
|
||||
if result != isNone: put(c, f, a)
|
||||
if result != isNone:
|
||||
if prev == nil: put(c, f, a)
|
||||
return
|
||||
|
||||
var aAsObject = roota.last
|
||||
let fKind = rootf.last.kind
|
||||
if fKind in {tyAnd, tyOr}:
|
||||
result = typeRel(c, last(f), a, flags)
|
||||
if result != isNone: put(c, f, a)
|
||||
return
|
||||
|
||||
if fKind in {tyRef, tyPtr}:
|
||||
if aAsObject.kind == tyObject:
|
||||
# bug #7600, tyObject cannot be passed
|
||||
# as argument to tyRef/tyPtr
|
||||
return isNone
|
||||
elif aAsObject.kind == fKind:
|
||||
aAsObject = aAsObject.base
|
||||
var aAsObject = roota.last
|
||||
|
||||
if aAsObject.kind == tyObject and trIsOutParam notin flags:
|
||||
let baseType = aAsObject.base
|
||||
if baseType != nil:
|
||||
if tfFinal notin aAsObject.flags:
|
||||
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
|
||||
let ret = typeRel(c, f, baseType, flags)
|
||||
return if ret in {isEqual,isGeneric}: isSubtype else: ret
|
||||
if fKind in {tyRef, tyPtr}:
|
||||
if aAsObject.kind == tyObject:
|
||||
# bug #7600, tyObject cannot be passed
|
||||
# as argument to tyRef/tyPtr
|
||||
return isNone
|
||||
elif aAsObject.kind == fKind:
|
||||
aAsObject = aAsObject.base
|
||||
|
||||
result = isNone
|
||||
if aAsObject.kind == tyObject and trIsOutParam notin flags:
|
||||
let baseType = aAsObject.base
|
||||
if baseType != nil:
|
||||
if tfFinal notin aAsObject.flags:
|
||||
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
|
||||
let ret = typeRel(c, f, baseType, flags)
|
||||
return if ret in {isEqual,isGeneric}: isSubtype else: ret
|
||||
else:
|
||||
assert last(origF) != nil
|
||||
result = typeRel(c, last(origF), a, flags)
|
||||
|
||||
16
tests/typerel/t25340.nim
Normal file
16
tests/typerel/t25340.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
type
|
||||
Foo[T] = object of T
|
||||
|
||||
template inheritanceCheck(a, b: untyped) =
|
||||
doAssert a is b
|
||||
doAssert b isnot a
|
||||
|
||||
inheritanceCheck Foo[RootObj], RootObj
|
||||
|
||||
inheritanceCheck Foo[Foo[RootObj]], RootObj
|
||||
inheritanceCheck Foo[Foo[RootObj]], Foo[RootObj]
|
||||
|
||||
inheritanceCheck Foo[Foo[Foo[RootObj]]], RootObj
|
||||
inheritanceCheck Foo[Foo[Foo[RootObj]]], Foo[RootObj]
|
||||
inheritanceCheck Foo[Foo[Foo[RootObj]]], Foo[Foo[RootObj]]
|
||||
Reference in New Issue
Block a user