fix crash with tyBuiltInTypeClass matching itself (#24462)

fixes #24449

The standalone `seq` type is a `tyBuiltInTypeClass` with a single child
of kind `tySequence`, which itself has no children. This is also the
case for most other `tyBuiltInTypeClass` kinds. However this can cause a
crash in sigmatch when calling `isEmptyContainer` on this child type,
which expects the sequence type to have children. This check was added
in #5557 to prevent empty collections like `@[]` from matching their
respective typeclass, but it's not useful when matching against another
typeclass (which is done here to resolve an ambiguity). So to avoid the
crash, this empty container check is disabled when matching against
another typeclass.
This commit is contained in:
metagn
2024-11-23 16:20:15 +03:00
committed by GitHub
parent af3181e75b
commit 96043bdbb7
2 changed files with 19 additions and 11 deletions

View File

@@ -1878,9 +1878,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let target = f.genericHead
let targetKind = target.kind
var effectiveArgType = reduceToBase(a)
# the skipped child of tyBuiltInTypeClass can be structured differently,
# newConstraint constructs them with no children
let typeClassArg = effectiveArgType.kind == tyBuiltInTypeClass
effectiveArgType = effectiveArgType.skipTypes({tyBuiltInTypeClass})
if targetKind == effectiveArgType.kind:
if effectiveArgType.isEmptyContainer:
if not typeClassArg and effectiveArgType.isEmptyContainer:
return isNone
if targetKind == tyProc:
if target.flags * {tfIterator} != effectiveArgType.flags * {tfIterator}:

View File

@@ -1,11 +1,16 @@
# issue #13302
block: # issue #13302
proc foo(x: object): int = x.i*2
proc foo(x: var object) = x.i*=2
type Foo = object
i: int
let x = Foo(i: 3)
var y = Foo(i: 4)
doAssert foo(x) == 6
foo(y)
doAssert y.i == 8
proc foo(x: object): int = x.i*2
proc foo(x: var object) = x.i*=2
type Foo = object
i: int
let x = Foo(i: 3)
var y = Foo(i: 4)
doAssert foo(x) == 6
foo(y)
doAssert y.i == 8
block: # issue #24449
proc p(x: var seq)= discard
proc p(x: seq)= discard
var s : seq[int]
p(s)