mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 19:52:36 +00:00
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:
@@ -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}:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user