macro_rules! polonius {
    (
    $(
        <
            $( $(
                $lt:lifetime
            ),+ $(,)? )?
            $( $(
                $T:ident $(:
                    $( $super:lifetime + )?
                    $( ?$Sized:ident )?
                    $( + )?
                    $( $Bound:path )?
                )?
            ),+ $(,)? )?
        >
    )?
    |$var:ident| -> $Ret:ty $body:block
) => { ... };
}
Expand description

Convenient entry-point to this crate’s logic.

Usage

use ::polonius_the_crab::prelude::*;

let mut a_mut_binding: &mut _ = // …

//                                      the lifetime placeholder has to be
//                                          named `'polonius` !!
//                                               vvvvvvvvv
let x = polonius!(|a_mut_binding| -> SomeRetType<'polonius> {
   let some_dependent_type = stuff(a_mut_binding);
   if some_cond() {
       polonius_return!(some_dependent_type);
   }
   if some_other_cond() {
       polonius_break!(42);
       unreachable!();
   }
   42
});
assert_eq!(x, 42);
stuff(a_mut_binding) // macro gave it back
// …

Generic parameters

Sometimes, the return value of that polonius! closure may need to refer to generic parameters. When that’s the case, you’ll need to tell the macro about those, using <generics…> syntax before the |…| -> part of the macro input:

use ::polonius_the_crab::prelude::*;

fn get_or_insert<'map, 'v, K, V : ?Sized> (
   mut map: &'map mut ::std::collections::HashMap<K, &'v V>,
   key: &'_ K,
   fallback_value: &'v V,
) -> &'map &'v V
where
   K : ::core::hash::Hash + Eq + Clone,
   V : ::core::fmt::Debug,
{
   // No need to provide `K`, since not part of the return type;
   // nor to provide the bounds for `V`, except for:
   //   - nested borrows (if ever),
   //   - `?Sized` (every now and then)
   //   - or to be able to name a bound-provided associated type (super rare!)
   polonius!(<'v, V : 'v + ?Sized> |map| -> &'polonius &'v V {
       if let Some(v) = map.get(key) {
           dbg!(v); // Even though `Debug` is not provided to the signature, it is available to the body.
           polonius_return!(v);
       }
   });
   map.insert(key.clone(), fallback_value);
   &map[key]
}