pub fn polonius<'i, Input: ?Sized, OwnedOutput, BorrowingOutput>(
input_borrow: &'i mut Input,
branch: impl for<'any> FnOnce(&'any mut Input) -> PoloniusResult<BorrowingOutput::Of<'any>, OwnedOutput>,
) -> PoloniusResult<BorrowingOutput::Of<'i>, OwnedOutput, &'i mut Input>
Expand description
The key stone of the API of this crate. See the top-level docs for more info.
Signature formatted for readability:
fn polonius<'i, Input : ?Sized, OwnedOutput, BorrowingOutput : ?Sized> (
input_borrow: &'i mut Input,
branch:
impl for<'any>
FnOnce(&'any mut Input)
-> PoloniusResult<
BorrowingOutput::Of<'any>,
OwnedOutput, // -----------+
> // |
, // | `polonius()`
) -> PoloniusResult< // | magic
BorrowingOutput::Of<'i>, // | adds "back"
OwnedOutput, &'i mut Input, // <-------+ the `input_borrow`
>
where
BorrowingOutput : ForLt,
§Turbofishing a ForLt!()
parameter.
As described in the top-level docs, the key aspect that allows this
function to be both sound, and generic, is that it involves a
for<'any>
-quantified lifetime in its branching closure,
and a lifetime-generic generic type parameter.
There was no stutter: this is indeed a generic generic type parameter: the API is said to be “higher-kinded”, related to HKTs (higher-kinded types).
Hence the BorrowingOutput : ForLt
(lifetime-generic) generic
type parameter.
Such “For
types” involved in these HKT APIs, however, cannot be
elided, since they do not play well with type inference.
This means that turbofishing this third type parameter is:
- mandatory;
- to be done using the
ForLt!
macro.
polonius::<_, _, ForLt!(…)>(…)
If this sounds too complex or abstract, know that there also are:
§Easier APIs for the most pervasive use cases
These are provided as the macros that accompany this crate:
-
polonius!
for most cases; -
polonius_loop!
as extra sugar for a specific shape ofloop { polonius!(…) }
- ⚠️ not every
loop { polonius!(…); … }
case can be translated to apolonius_loop!
. When in doubt, fall back to a lower-levelpolonius!
invocation, or even to a manualpolonius()
call.
- ⚠️ not every