mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +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.
(cherry picked from commit 96043bdbb7)
This commit is contained in:
@@ -1749,9 +1749,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
let target = f[0]
|
||||
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