Covariance describes how lifetimes behave in type substitution. A type is covariant over a lifetime if it can accept shorter lifetimes than originally specified.
📌 Example:
let short: &'short i32 = &5;
let long: &'long i32 = short; // allowed if &'long is covariant over 'short
#### In `ouroboros`:
When you annotate a field with:
#[covariant]
You're telling the macro:
> “This field’s type behaves covariantly over 'this (the synthetic lifetime tied to the struct). It's safe to allow borrowing access.”
For instance:
#[covariant]
fields: Vec<&'this str>,
This is safe because Vec<&'this str> is covariant—each element is a reference that can have a shorter lifetime than 'this.
Contrast with:
callback: Box<dyn Fn(&'this str)>
This is not covariant, since function traits are *invariant*. If the macro isn’t sure, it’ll ask you to annotate the field with either:
* #[covariant], or
* #[not_covariant]
The macro will then generate or skip the .borrow_*() method accordingly.
---