From d53ab9e5c857d47b8ea9643a2cf0235f3486afa0 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Tue, 26 Feb 2019 16:43:34 +0200 Subject: [PATCH] Prevent options from calling custom ref == operators (#10745) --- lib/pure/options.nim | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/pure/options.nim b/lib/pure/options.nim index 7a474e7721..82ecedeb6d 100644 --- a/lib/pure/options.nim +++ b/lib/pure/options.nim @@ -111,7 +111,7 @@ proc some*[T](val: T): Option[T] = assert $b == "Some(42)" when T is SomePointer: - assert val != nil + assert(not val.isNil) result.val = val else: result.has = true @@ -146,7 +146,7 @@ proc isSome*[T](self: Option[T]): bool {.inline.} = assert not b.isSome when T is SomePointer: - self.val != nil + not self.val.isNil else: self.has @@ -159,7 +159,7 @@ proc isNone*[T](self: Option[T]): bool {.inline.} = assert not a.isNone assert b.isNone when T is SomePointer: - self.val == nil + self.val.isNil else: not self.has @@ -371,6 +371,16 @@ proc unsafeGet*[T](self: Option[T]): T = when isMainModule: import unittest, sequtils + # RefPerson is used to test that overloaded `==` operator is not called by + # options. It is defined here in the global scope, because otherwise the test + # will not even consider the `==` operator. Different bug? + type RefPerson = ref object + name: string + + proc `==`(a, b: RefPerson): bool = + assert(not a.isNil and not b.isNil) + a.name == b.name + suite "options": # work around a bug in unittest let intNone = none(int) @@ -489,3 +499,8 @@ when isMainModule: let noperson = none(Person) check($noperson == "None[Person]") + + test "Ref type with overloaded `==`": + let p = some(RefPerson.new()) + check p.isSome +