From 93f0c01ebbede2664d4e81d235ea55914bab340f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Sun, 26 Mar 2023 16:34:47 +0200 Subject: [PATCH] Fix `Enum#includes?` to require all bits set --- spec/std/enum_spec.cr | 6 ++++++ src/enum.cr | 19 ++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/spec/std/enum_spec.cr b/spec/std/enum_spec.cr index 963e9401ad95..19248788cbb3 100644 --- a/spec/std/enum_spec.cr +++ b/spec/std/enum_spec.cr @@ -144,6 +144,12 @@ describe Enum do it "does includes?" do (SpecEnumFlags::One | SpecEnumFlags::Two).includes?(SpecEnumFlags::One).should be_true (SpecEnumFlags::One | SpecEnumFlags::Two).includes?(SpecEnumFlags::Three).should be_false + SpecEnumFlags::One.includes?(SpecEnumFlags::None).should be_true + SpecEnumFlags::None.includes?(SpecEnumFlags::None).should be_true + SpecEnumFlags::None.includes?(SpecEnumFlags::One).should be_false + SpecEnumFlags::One.includes?(SpecEnumFlags::One | SpecEnumFlags::Two).should be_false + (SpecEnumFlags::One | SpecEnumFlags::Two).includes?(SpecEnumFlags::One | SpecEnumFlags::Two).should be_true + (SpecEnumFlags::One | SpecEnumFlags::Two | SpecEnumFlags::Three).includes?(SpecEnumFlags::One | SpecEnumFlags::Two).should be_true end describe "each" do diff --git a/src/enum.cr b/src/enum.cr index 06c7e3afdfbd..a42f9901f9cf 100644 --- a/src/enum.cr +++ b/src/enum.cr @@ -337,20 +337,9 @@ struct Enum end # Returns `true` if this enum member's value includes *other*. This - # performs a logical "and" between this enum member's value and *other*'s, - # so instead of writing: + # performs a logical "and" between this enum member's value and *other*'s. # - # ``` - # (member & value) != 0 - # ``` - # - # you can write: - # - # ``` - # member.includes?(value) - # ``` - # - # The above is mostly useful with flag enums. + # This is mostly useful for flag enums. # # For example: # @@ -360,7 +349,7 @@ struct Enum # mode.includes?(IOMode::Async) # => false # ``` def includes?(other : self) : Bool - (value & other.value) != 0 + value.bits_set?(other.value) end # Returns `true` if this enum member and *other* have the same underlying value. @@ -390,7 +379,7 @@ struct Enum {% if @type.annotation(Flags) %} return if value == 0 {% for member in @type.constants %} - {% if member.stringify != "All" %} + {% if member.stringify != "All" && member.stringify != "None" %} if includes?(self.class.new({{@type.constant(member)}})) yield self.class.new({{@type.constant(member)}}), {{@type.constant(member)}} end