Skip to main content

bitflags/
lib.rs

1#![no_std]
2#![allow(non_snake_case)]
3//! A verified version of the [`bitflags`](https://docs.rs/bitflags/latest/bitflags/) crate.
4//!
5//! The macro [`bitflags!`] generates a single `struct` whose layout matches
6//! the one produced by the upstream `bitflags` crate
7//! (see [`bitflags::example_generated::Flags`]):
8//!
9//! ```text
10//! pub struct Flags { bits: T } // bits is private
11//! impl Flags {
12//!     pub const fn A() -> Self;   // one factory per declared flag
13//!     ...
14//!     pub const fn empty() -> Self;
15//!     pub const fn all() -> Self;
16//!     pub const fn bits(&self) -> T;
17//!     pub const fn from_bits(bits: T) -> Option<Self>;
18//!     pub const fn from_bits_truncate(bits: T) -> Self;
19//!     pub const fn is_empty(&self) -> bool;
20//!     pub const fn is_all(&self) -> bool;
21//!     pub const fn contains(&self, other: Self) -> bool;
22//!     pub const fn intersects(&self, other: Self) -> bool;
23//!     pub fn insert(&mut self, other: Self);
24//!     pub fn remove(&mut self, other: Self);
25//!     pub fn toggle(&mut self, other: Self);
26//!     pub fn set(&mut self, other: Self, value: bool);
27//! }
28//! ```
29//!
30//! NOTE: unlike upstream `bitflags`, the per-flag accessors are `pub const fn`
31//! factories (`Flags::A()`) instead of associated constants (`Flags::A`). This
32//! is required because the `bits` field is private:
33//! Verus refuses to publish a constructor for an opaque datatype through a `pub const`.
34//!
35//! Upstream's `Flags` trait metadata (`FLAGS`, iterators, lookup helpers, etc.)
36//! is represented here by Verus-only specs and lemmas around the inherent APIs.
37//!
38//! Only **literal** values are supported for each flag.
39use vstd::arithmetic::power::*;
40use vstd::arithmetic::power2::*;
41use vstd::bits::*;
42use vstd::prelude::*;
43
44pub use paste;
45
46#[doc(hidden)]
47#[macro_export]
48macro_rules! __bitflags_cfg_expr {
49    (() $base:expr) => {
50        $base
51    };
52    ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $base:expr) => {
53        (cfg!($($cfg)*) && $crate::__bitflags_cfg_expr!(($($rest)*) $base))
54    };
55    ((#[$_other:meta] $($rest:tt)*) $base:expr) => {
56        $crate::__bitflags_cfg_expr!(($($rest)*) $base)
57    };
58}
59
60#[doc(hidden)]
61#[macro_export]
62macro_rules! __bitflags_cfg_guarded_expr {
63    (() $e:expr) => {
64        $e
65    };
66    ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $e:expr) => {{
67        #[cfg($($cfg)*)]
68        {
69            $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
70        }
71        #[cfg(not($($cfg)*))]
72        {
73            true
74        }
75    }};
76    ((#[$_other:meta] $($rest:tt)*) $e:expr) => {
77        $crate::__bitflags_cfg_guarded_expr!(($($rest)*) $e)
78    };
79}
80
81#[doc(hidden)]
82#[macro_export]
83macro_rules! __bitflags_cfg_guarded_stmt {
84    (() $stmt:stmt) => {
85        $stmt
86    };
87    ((#[cfg($($cfg:tt)*)] $($rest:tt)*) $stmt:stmt) => {
88        #[cfg($($cfg)*)]
89        {
90            $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
91        }
92    };
93    ((#[$_other:meta] $($rest:tt)*) $stmt:stmt) => {
94        $crate::__bitflags_cfg_guarded_stmt!(($($rest)*) $stmt)
95    };
96}
97
98#[doc(hidden)]
99#[macro_export]
100macro_rules! __bitflags_flag {
101    (
102        {
103            name: _,
104            named: { $($named:tt)* },
105            unnamed: { $($unnamed:tt)* },
106        }
107    ) => {
108        $($unnamed)*
109    };
110    (
111        {
112            name: $Flag:ident,
113            named: { $($named:tt)* },
114            unnamed: { $($unnamed:tt)* },
115        }
116    ) => {
117        $($named)*
118    };
119}
120
121/// A macro wrapper for quickly defining bitflags with verified
122/// properties in Verus. It only supports literal values for the bits.
123///
124/// # Example
125///
126/// ```rust,norun
127/// bitflags! {
128///     pub struct Flags: u32 {
129///         const A = 0b00000001;
130///         const B = 0b00000010;
131///         const C = 0b00000100;
132///         const ABC = 0b00000111;
133///     }
134/// }
135///
136/// let f = Flags::A() | Flags::B();
137/// assert!(f.contains(Flags::A()));
138/// ```
139// Upstream expands ordinary Rust; this macro embeds `verus!` and keeps its layout stable.
140#[verusfmt::skip]
141#[rustfmt::skip]
142#[macro_export]
143macro_rules! bitflags {
144    (
145        $(#[$outer:meta])*
146        $vis:vis struct $name:ident: $T:ty {
147            $(
148                $(#[$inner:ident $($args:tt)*])*
149                const $Flag:ident = $value:expr;
150            )*
151        }
152    ) => {
153        $crate::paste::paste! {
154        verus! {
155            $(#[$outer])*
156            #[repr(transparent)]
157            $vis struct $name {
158                /// The raw bits backing this flags value.
159                bits: $T,
160            }
161
162            impl ::core::clone::Clone for $name {
163                #[inline]
164                fn clone(&self) -> (r: Self)
165                    returns self
166                {
167                    Self {
168                        bits: self.bits,
169                    }
170                }
171            }
172
173            impl ::core::marker::Copy for $name {}
174
175            impl ::core::default::Default for $name {
176                #[inline]
177                fn default() -> (r: Self)
178                    ensures
179                        r.bits() == 0,
180                        r.flags_spec() == Self::flags_from_bits(0),
181                    returns
182                        Self::empty(),
183                {
184                    Self::empty()
185                }
186            }
187
188            impl ::vstd::view::View for $name {
189                type V = ::vstd::set::Set<[< __ghost $name >]>;
190
191                open spec fn view(&self) -> Self::V {
192                    Self::flags_from_bits(self.bits())
193                }
194            }
195
196            // Upstream uses `Flags::FLAGS`; specs use this ghost finite set.
197            #[allow(non_camel_case_types)]
198            $vis ghost enum [< __ghost $name >] {
199                $(
200                    [< __ghost $Flag >],
201                )*
202            }
203
204            impl [< __ghost $name >] {
205                $vis open spec fn enabled(self) -> bool {
206                    match self {
207                        $(
208                            [< __ghost $name >]::[< __ghost $Flag >] => $crate::__bitflags_cfg_expr! {
209                                ($(#[$inner $($args)*])*) true
210                            },
211                        )*
212                    }
213                }
214
215                $vis open spec fn bit(self) -> $T {
216                    match self {
217                        $(
218                            [< __ghost $name >]::[< __ghost $Flag >] => (($value) as $T),
219                        )*
220                    }
221                }
222            }
223
224            impl ::vstd::set_lib::FiniteFull for [< __ghost $name >] {
225                proof fn full_properties() {
226                    let s = ::vstd::iset::ISet::empty()
227                        $(.insert([< __ghost $name >]::[< __ghost $Flag >]))*;
228                    assert(::vstd::iset::ISet::new(|a: [< __ghost $name >]| true) =~= s);
229                }
230            }
231
232            impl $name {
233                $vis open spec fn flags_spec(&self) -> ::vstd::set::Set<[< __ghost $name >]> {
234                    Self::flags_from_bits(self.bits())
235                }
236
237                $vis open spec fn flags_from_bits(bits: $T) -> ::vstd::set::Set<[< __ghost $name >]> {
238                    ::vstd::set::Set::< [< __ghost $name >] >::from_finite_type(|flag: [< __ghost $name >]| {
239                        flag.enabled() && (bits & flag.bit()) == flag.bit()
240                    })
241                }
242
243                closed spec fn from_bits_unchecked_spec(bits: $T) -> Self {
244                    Self { bits }
245                }
246
247                #[verifier::when_used_as_spec(from_bits_unchecked_spec)]
248                const fn from_bits_unchecked(bits: $T) -> (r: Self)
249                    ensures
250                        r.bits() == bits,
251                        r.flags_spec() == Self::flags_from_bits(bits),
252                    returns
253                        Self::from_bits_unchecked(bits),
254                {
255                    Self { bits }
256                }
257
258                $(
259                    $vis closed spec fn [< $Flag _spec >]() -> Self {
260                        Self::from_bits_unchecked_spec($value as $T)
261                    }
262
263                    $(#[$inner $($args)*])*
264                    #[verifier::when_used_as_spec([< $Flag _spec >])]
265                    $vis const fn $Flag() -> (r: Self)
266                        ensures
267                            r.bits() == ($value),
268                            r.flags_spec() == Self::flags_from_bits(($value) as $T),
269                        returns Self::[< $Flag _spec >](),
270                    {
271                        Self::from_bits_unchecked($value)
272                    }
273                )*
274
275                // Upstream computes `all()` from `Self::FLAGS`; specs use this mask.
276                closed spec fn declared_bits_spec() -> $T {
277                    (0 as $T) $(| (
278                        if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
279                            (($value) as $T)
280                        } else {
281                            0 as $T
282                        }
283                    ))*
284                }
285
286                // Upstream has no `all_bits()`; proof facts attach to `all().bits()`.
287                $vis proof fn lemma_all_constant()
288                    ensures
289                        Self::all().bits() == Self::all_spec().bits_spec(),
290                        Self::all_spec().bits_spec() == (0 as $T) $(| (
291                            if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
292                                (($value) as $T)
293                            } else {
294                                0 as $T
295                            }
296                        ))*,
297                        Self::all().bits() == (0 as $T) $(| (
298                            if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
299                                (($value) as $T)
300                            } else {
301                                0 as $T
302                        }
303                    ))*,
304                {
305                }
306
307                $vis broadcast proof fn lemma_consts()
308                    ensures
309                        #![trigger Self::all().bits()]
310                        Self::all().bits() == (0 as $T) $(| (
311                            if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
312                                (($value) as $T)
313                            } else {
314                                0 as $T
315                            }
316                        ))*,
317                        $(
318                            #![trigger $crate::__bitflags_cfg_guarded_expr!(
319                                ($(#[$inner $($args)*])*)
320                                Self::$Flag().bits()
321                            )]
322                            $crate::__bitflags_cfg_guarded_expr!(
323                                ($(#[$inner $($args)*])*)
324                                Self::$Flag().bits() == (($value) as $T)
325                            ),
326                        )*
327                {
328                    Self::lemma_all_constant();
329                }
330
331                $vis proof fn lemma_from_bits_bits(bits: $T)
332                    requires
333                        bits & Self::all().bits() == bits,
334                    ensures
335                        Self::from_bits(bits)->0.bits() == bits,
336                {
337                }
338
339                $vis proof fn lemma_eq_from_bits(left: Self, right: Self)
340                    requires
341                        left.bits() == right.bits(),
342                    ensures
343                        left == right,
344                {
345                }
346
347                /// The raw bits stored inside this flags value.
348                $vis closed spec fn bits_spec(&self) -> $T { self.bits }
349
350                #[verifier::when_used_as_spec(bits_spec)]
351                $vis const fn bits(&self) -> $T
352                    returns self.bits(),
353                {
354                    self.bits
355                }
356
357                $vis closed spec fn empty_spec() -> Self {
358                    Self::from_bits_unchecked_spec(0)
359                }
360
361                #[verifier::when_used_as_spec(empty_spec)]
362                $vis const fn empty() -> (r: Self)
363                    ensures
364                        r.bits() == 0,
365                        r.flags_spec() == Self::flags_from_bits(0),
366                    returns Self::empty(),
367                {
368                    Self::from_bits_unchecked(0)
369                }
370
371                $vis closed spec fn all_spec() -> Self {
372                    Self::from_bits_unchecked_spec(Self::declared_bits_spec())
373                }
374
375                #[verifier::when_used_as_spec(all_spec)]
376                $vis const fn all() -> (r: Self)
377                    ensures
378                        r == Self::all_spec(),
379                        r.bits() == Self::all().bits(),
380                        r.flags_spec() == Self::flags_from_bits(Self::all().bits()),
381                {
382                    Self::from_bits_unchecked(
383                        (0 as $T) $(| (
384                            if $crate::__bitflags_cfg_expr! { ($(#[$inner $($args)*])*) true } {
385                                (($value) as $T)
386                            } else {
387                                0 as $T
388                            }
389                        ))*
390                    )
391                }
392
393                /// The bits in `self` that correspond to declared flags.
394                $vis closed spec fn known_bits_spec(&self) -> $T {
395                    self.bits() & Self::all().bits()
396                }
397
398                #[verifier::when_used_as_spec(known_bits_spec)]
399                $vis const fn known_bits(&self) -> (r: $T)
400                    returns self.known_bits(),
401                {
402                    self.bits & Self::all().bits()
403                }
404
405                /// The bits in `self` that do not correspond to declared flags.
406                $vis closed spec fn unknown_bits_spec(&self) -> $T {
407                    self.bits() & !Self::all().bits()
408                }
409
410                #[verifier::when_used_as_spec(unknown_bits_spec)]
411                $vis const fn unknown_bits(&self) -> (r: $T)
412                    returns self.unknown_bits(),
413                {
414                    self.bits & !Self::all().bits()
415                }
416
417                /// This method returns `true` if any unknown bits are set.
418                $vis open spec fn contains_unknown_bits_spec(&self) -> bool {
419                    self.unknown_bits() != 0
420                }
421
422                #[verifier::when_used_as_spec(contains_unknown_bits_spec)]
423                $vis const fn contains_unknown_bits(&self) -> (r: bool)
424                    returns self.contains_unknown_bits(),
425                {
426                    self.unknown_bits() != 0
427                }
428
429                /// Whether all bits in `self` are unset.
430                $vis open spec fn is_empty_spec(&self) -> bool {
431                    self.bits() == 0
432                }
433
434                #[verifier::when_used_as_spec(is_empty_spec)]
435                $vis const fn is_empty(&self) -> (r: bool)
436                    returns self.is_empty(),
437                {
438                    self.bits == 0
439                }
440
441                /// Whether all known bits are set.
442                $vis open spec fn is_all_spec(&self) -> bool {
443                    Self::all().bits() | self.bits() == self.bits()
444                }
445
446                #[verifier::when_used_as_spec(is_all_spec)]
447                $vis const fn is_all(&self) -> (r: bool)
448                    returns self.is_all(),
449                {
450                    Self::all().bits() | self.bits == self.bits
451                }
452
453                /// Whether all set bits in `other` are also set in `self`.
454                $vis open spec fn contains_spec(&self, other: Self) -> bool {
455                    (self.bits() & other.bits()) == other.bits()
456                }
457
458                $vis open spec fn contains_flags_spec(&self, other: Self) -> bool {
459                    self.contains(other)
460                }
461
462                #[verifier::when_used_as_spec(contains_spec)]
463                $vis const fn contains(&self, other: Self) -> (r: bool)
464                    returns self.contains(other),
465                {
466                    (self.bits & other.bits) == other.bits
467                }
468
469                /// Whether any set bits in `other` are also set in `self`.
470                $vis open spec fn intersects_spec(&self, other: Self) -> bool {
471                    (self.bits() & other.bits()) != 0
472                }
473
474                #[verifier::when_used_as_spec(intersects_spec)]
475                $vis const fn intersects(&self, other: Self) -> (r: bool)
476                    returns self.intersects(other),
477                {
478                    (self.bits & other.bits) != 0
479                }
480
481                $vis closed spec fn from_bits_truncate_spec(bits: $T) -> Self {
482                    Self::from_bits_unchecked_spec(bits & Self::all().bits())
483                }
484
485                $vis closed spec fn from_bits_retain_spec(bits: $T) -> Self {
486                    Self::from_bits_unchecked_spec(bits)
487                }
488
489                #[verifier::when_used_as_spec(from_bits_retain_spec)]
490                $vis const fn from_bits_retain(bits: $T) -> (r: Self)
491                    ensures
492                        r.bits() == bits,
493                        r.flags_spec() == Self::flags_from_bits(bits),
494                    returns Self::from_bits_retain(bits),
495                {
496                    Self::from_bits_unchecked(bits)
497                }
498
499                /// Get a flags value with the bits of a flag with the given name set.
500                ///
501                /// This method will return `None` if `name` is empty or doesn't
502                /// correspond to any named flag.
503                $vis fn from_name(name: &str) -> (r: Option<Self>)
504                    ensures
505                        r matches Some(flags_value) ==> {
506                            &&& flags_value.flags_spec()
507                                == Self::flags_from_bits(flags_value.bits())
508                        },
509                {
510                    if name.is_empty() {
511                        return ::core::option::Option::None;
512                    }
513                    $(
514                        $crate::__bitflags_flag!({
515                            name: $Flag,
516                            named: {
517                                $crate::__bitflags_cfg_guarded_stmt!(
518                                    ($(#[$inner $($args)*])*)
519                                    {
520                                        if name == ::core::stringify!($Flag) {
521                                            return ::core::option::Option::Some(
522                                                Self::$Flag()
523                                            );
524                                        }
525                                    }
526                                );
527                            },
528                            unnamed: {},
529                        });
530                    )*
531                    ::core::option::Option::None
532                }
533
534                #[verifier::when_used_as_spec(from_bits_truncate_spec)]
535                $vis const fn from_bits_truncate(bits: $T) -> (r: Self)
536                    ensures
537                        r.bits() == (bits & Self::all().bits()),
538                        r.flags_spec() == Self::flags_from_bits(bits & Self::all().bits()),
539                    returns Self::from_bits_truncate(bits),
540                {
541                    Self::from_bits_unchecked(bits & Self::all().bits())
542                }
543
544                $vis closed spec fn from_bits_spec(bits: $T) -> Option<Self> {
545                    if (bits & Self::all().bits()) == bits {
546                        Some(Self::from_bits_unchecked_spec(bits))
547                    } else {
548                        None
549                    }
550                }
551
552                #[verifier::when_used_as_spec(from_bits_spec)]
553                $vis const fn from_bits(bits: $T) -> (r: Option<Self>)
554                    ensures
555                        r is Some == ((bits & Self::all().bits()) == bits),
556                        r matches Some(flags_value) ==> {
557                            &&& flags_value.bits() == bits
558                            &&& flags_value.flags_spec() == Self::flags_from_bits(bits)
559                        },
560                    returns
561                        Self::from_bits(bits),
562                {
563                    let truncated = Self::from_bits_truncate(bits).bits();
564                    if truncated == bits {
565                        Some(Self::from_bits_retain(bits))
566                    } else {
567                        None
568                    }
569                }
570
571                $vis closed spec fn remove_spec(self, other: Self) -> Self {
572                    Self::from_bits_unchecked_spec(self.bits() & !other.bits())
573                }
574
575                $vis fn insert(&mut self, other: Self)
576                    ensures
577                        final(self).bits() == (old(self).bits() | other.bits()),
578                        final(self).flags_spec() == Self::flags_from_bits(
579                            old(self).bits() | other.bits(),
580                        ),
581                {
582                    *self = Self::from_bits_retain(self.bits()).union(other);
583                }
584
585                $vis fn remove(&mut self, other: Self)
586                    ensures
587                        *final(self) == old(self).remove_spec(other),
588                        final(self).bits() == (old(self).bits() & !other.bits()),
589                        final(self).flags_spec() == Self::flags_from_bits(
590                            old(self).bits() & !other.bits(),
591                        ),
592                {
593                    *self = Self::from_bits_retain(self.bits()).difference(other);
594                }
595
596                /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
597                $vis fn toggle(&mut self, other: Self)
598                    ensures
599                        final(self).bits() == (old(self).bits() ^ other.bits()),
600                        final(self).flags_spec() == Self::flags_from_bits(
601                            old(self).bits() ^ other.bits(),
602                        ),
603                {
604                    *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
605                }
606
607                /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
608                $vis fn set(&mut self, other: Self, value: bool)
609                    ensures
610                        value ==> final(self).bits() == (old(self).bits() | other.bits()),
611                        !value ==> final(self).bits() == (old(self).bits() & !other.bits()),
612                {
613                    if value {
614                        self.insert(other);
615                    } else {
616                        self.remove(other);
617                    }
618                }
619
620                /// Remove any unknown bits from the flags.
621                $vis fn truncate(&mut self)
622                    ensures
623                        final(self).bits() == (old(self).bits() & Self::all().bits()),
624                        final(self).flags_spec() == Self::flags_from_bits(
625                            old(self).bits() & Self::all().bits(),
626                        ),
627                {
628                    *self = Self::from_bits_truncate(self.bits());
629                }
630
631                /// Unsets all bits in the flags.
632                $vis fn clear(&mut self)
633                    ensures
634                        final(self).bits() == 0,
635                        final(self).flags_spec() == Self::flags_from_bits(0),
636                {
637                    *self = Self::empty();
638                }
639
640                $vis closed spec fn union_spec(self, other: Self) -> Self {
641                    Self::from_bits_unchecked_spec(self.bits() | other.bits())
642                }
643
644                #[verifier::when_used_as_spec(union_spec)]
645                $vis const fn union(self, other: Self) -> (r: Self)
646                    ensures
647                        r.bits() == (self.bits() | other.bits()),
648                    returns self.union(other),
649                {
650                    Self::from_bits_unchecked(self.bits | other.bits)
651                }
652
653                $vis closed spec fn intersection_spec(self, other: Self) -> Self {
654                    Self::from_bits_unchecked_spec(self.bits() & other.bits())
655                }
656
657                #[verifier::when_used_as_spec(intersection_spec)]
658                $vis const fn intersection(self, other: Self) -> (r: Self)
659                    ensures
660                        r.bits() == (self.bits() & other.bits()),
661                    returns self.intersection(other),
662                {
663                    Self::from_bits_unchecked(self.bits & other.bits)
664                }
665
666                $vis closed spec fn difference_spec(self, other: Self) -> Self {
667                    Self::from_bits_unchecked_spec(self.bits() & !other.bits())
668                }
669
670                #[verifier::when_used_as_spec(difference_spec)]
671                $vis const fn difference(self, other: Self) -> (r: Self)
672                    ensures
673                        r.bits() == (self.bits() & !other.bits()),
674                    returns self.difference(other),
675                {
676                    Self::from_bits_unchecked(self.bits & !other.bits)
677                }
678
679                $vis closed spec fn symmetric_difference_spec(self, other: Self) -> Self {
680                    Self::from_bits_unchecked_spec(self.bits() ^ other.bits())
681                }
682
683                #[verifier::when_used_as_spec(symmetric_difference_spec)]
684                $vis const fn symmetric_difference(self, other: Self) -> (r: Self)
685                    ensures
686                        r.bits() == (self.bits() ^ other.bits()),
687                    returns self.symmetric_difference(other),
688                {
689                    Self::from_bits_unchecked(self.bits ^ other.bits)
690                }
691
692                $vis closed spec fn complement_spec(self) -> Self {
693                    Self::from_bits_truncate_spec(!self.bits())
694                }
695
696                #[verifier::when_used_as_spec(complement_spec)]
697                $vis const fn complement(self) -> (r: Self)
698                    ensures
699                        r.bits() == (!self.bits() & Self::all().bits()),
700                        r.flags_spec() == Self::flags_from_bits(!self.bits() & Self::all().bits()),
701                    returns self.complement(),
702                {
703                    Self::from_bits_truncate(!self.bits)
704                }
705            }
706
707            impl core::cmp::PartialEq for $name {
708                fn eq(&self, other: &Self) -> (r: bool)
709                    ensures r == (self.bits() == other.bits()),
710                {
711                    self.bits == other.bits
712                }
713            }
714
715            impl ::vstd::std_specs::cmp::PartialEqSpecImpl for $name {
716                closed spec fn obeys_eq_spec() -> bool { true }
717
718                closed spec fn eq_spec(&self, other: &Self) -> bool {
719                    self.bits() == other.bits()
720                }
721            }
722
723            impl core::cmp::Eq for $name {}
724
725            impl ::vstd::std_specs::ops::BitOrSpecImpl for $name {
726                open spec fn obeys_bitor_spec() -> bool { true }
727
728                open spec fn bitor_req(self, rhs: Self) -> bool { true }
729
730                open spec fn bitor_spec(self, rhs: Self) -> Self::Output {
731                    self.union(rhs)
732                }
733            }
734
735            impl core::ops::BitOr for $name {
736                type Output = Self;
737                fn bitor(self, other: Self) -> (r: Self)
738                    ensures
739                        r.bits() == (self.bits() | other.bits()),
740                {
741                    self.union(other)
742                }
743            }
744
745            impl vstd::std_specs::ops::BitAndSpecImpl for $name {
746                open spec fn obeys_bitand_spec() -> bool { true }
747
748                open spec fn bitand_req(self, rhs: Self) -> bool { true }
749
750                open spec fn bitand_spec(self, rhs: Self) -> Self::Output {
751                    self.intersection(rhs)
752                }
753            }
754
755            impl core::ops::BitAnd for $name {
756                type Output = Self;
757                fn bitand(self, other: Self) -> (r: Self)
758                    ensures
759                        r.bits() == (self.bits() & other.bits()),
760                {
761                    self.intersection(other)
762                }
763            }
764
765            impl vstd::std_specs::ops::BitXorSpecImpl for $name {
766                open spec fn obeys_bitxor_spec() -> bool { true }
767
768                open spec fn bitxor_req(self, rhs: Self) -> bool { true }
769
770                open spec fn bitxor_spec(self, rhs: Self) -> Self::Output {
771                    self.symmetric_difference(rhs)
772                }
773            }
774
775            impl core::ops::BitXor for $name {
776                type Output = Self;
777                fn bitxor(self, other: Self) -> (r: Self)
778                    ensures
779                        r.bits() == (self.bits() ^ other.bits()),
780                {
781                    self.symmetric_difference(other)
782                }
783            }
784
785            impl vstd::std_specs::ops::SubSpecImpl for $name {
786                open spec fn obeys_sub_spec() -> bool { true }
787
788                open spec fn sub_req(self, rhs: Self) -> bool { true }
789
790                open spec fn sub_spec(self, rhs: Self) -> Self::Output {
791                    self.difference(rhs)
792                }
793            }
794
795            impl core::ops::Sub for $name {
796                type Output = Self;
797                fn sub(self, other: Self) -> (r: Self)
798                    ensures
799                        r.bits() == (self.bits() & !other.bits()),
800                {
801                    self.difference(other)
802                }
803            }
804
805            impl vstd::std_specs::ops::NotSpecImpl for $name {
806                open spec fn obeys_not_spec() -> bool { true }
807
808                open spec fn not_req(self) -> bool { true }
809
810                closed spec fn not_spec(self) -> Self::Output {
811                    self.complement()
812                }
813            }
814
815            impl core::ops::Not for $name {
816                type Output = Self;
817
818                fn not(self) -> (r: Self)
819                    ensures
820                        r.bits() == (!self.bits() & $name::all().bits()),
821                {
822                    self.complement()
823                }
824            }
825
826        } // verus!
827        impl ::core::fmt::Debug for $name {
828            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
829                f.debug_tuple(stringify!($name)).field(&self.bits).finish()
830            }
831        }
832
833        impl ::core::ops::BitOrAssign for $name {
834            #[inline]
835            fn bitor_assign(&mut self, other: Self) {
836                self.insert(other);
837            }
838        }
839
840        impl ::core::ops::BitAndAssign for $name {
841            #[inline]
842            fn bitand_assign(&mut self, other: Self) {
843                *self = Self::from_bits_retain(self.bits()).intersection(other);
844            }
845        }
846
847        impl ::core::ops::BitXorAssign for $name {
848            #[inline]
849            fn bitxor_assign(&mut self, other: Self) {
850                self.toggle(other);
851            }
852        }
853
854        impl ::core::ops::SubAssign for $name {
855            #[inline]
856            fn sub_assign(&mut self, other: Self) {
857                self.remove(other);
858            }
859        }
860
861        } // paste!
862    };
863}
864
865// ---------------------------------------------------------------------------
866// Smoke test: instantiate the `bitflags!` macro to make sure it expands and
867// verifies. Mirrors `bitflags::example_generated::Flags`.
868// ---------------------------------------------------------------------------
869
870bitflags! {
871    pub struct Flags: u32 {
872        const A = 0b00000001;
873        const B = 0b00000010;
874        const C = 0b00000100;
875        const ABC = 0b00000111;
876    }
877}
878
879verus! {
880
881#[allow(dead_code)]
882fn _bitflags_smoke_test() {
883    let a = Flags::A();
884    let b = Flags::B();
885    let c = Flags::C();
886    let mut flags = Flags::ABC();
887
888    flags.remove(a);
889    flags.insert(a);
890    flags.toggle(b);
891    flags.set(c, false);
892    flags.set(b, true);
893    flags.insert(c);
894    flags = flags.intersection(Flags::from_bits_retain(0b101u32));
895    flags.toggle(a);
896
897    let unknown = Flags::from_bits_retain(0b1000u32);
898    unknown.known_bits();
899    unknown.unknown_bits();
900    unknown.contains_unknown_bits();
901    Flags::from_bits(0b1000u32);
902    let truncated_unknown = Flags::from_bits_truncate(0b1001u32);
903    truncated_unknown.bits();
904
905}
906
907} // verus!