Here are examples written in the formality dialect. We'll reference these when discussion the options.

Default trait and impl

Here the model is having the Default trait that is usable in different contexts, e.g., const Default and async Default. There is also an impl of Wrapper<T> and then a function that calls it

#![allow(unused)]
fn main() {
trait Default {
    do DefaultEffect;

    fn default() -> Self
    do
        Self::DefaultEffect;
}

struct Wrapper<T> {
    value: T
}

impl<T> Default for Wrapper<T>
where
    T: Default,
{
    do DefaultEffect = T::DefaultEffect;

    fn default() -> Self
    do
        Self::DefaultEffect
    {
        Wrapper {
            value: T::default()
        }
    }
}

fn get_me<T>(x: Option<Wrapper<T>>) -> Wrapper<T>
where
    T: Default,
do
    T::DefaultEffect,
{
    match x {
        None => <Wrapper<T>>::default(),
        Some(v) => v,
    }
}
}

All the things

This ATT trait exercises all the variations.

#![allow(unused)]
fn main() {
trait ATT {
    do Effect;

    fn always_const(&self) -> u32
    do
        const;

    fn maybe_const(&self) -> u32
    do
        (const, <Self as ATT>::Effect);

    fn maybe_maybe_const<T: ATT>(&self) -> u32
    do
        (const, <Self as ATT>::Effect, <T as ATT>::Effect);

    fn always_maybe_const<T: ATT>(&self) -> u32
    do
        (const, <T as ATT>::Effect);
}
}

ATT Impl A

ATT Impl B