Skip to main content

bitflags/
lib.rs

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