RFC 2722 by @Nokel81 proposed the following design for overriding the short circuiting operators:
enum ShortCircuit<S, L> {
    Short(S),
    Long(L),
}
trait LogicalOr<Rhs = Self>: Sized {
    type Output;
    type Intermediate;
    fn short_circuit_or(self) -> ShortCircuit<Self::Output, Intermediate>;
    fn logical_or(lhs: Intermediate, rhs: Rhs) -> Self::Output;
}
trait LogicalAnd<Rhs = Self>: Sized {
    type Output;
    type Intermediate;
    fn short_circuit_and(self) -> ShortCircuit<Self::Output, Intermediate>;
    fn logical_and(lhs: Intermediate, rhs: Rhs) -> Self::Output;
}
I believe this design can be made simpler like this:
trait LogicalOr<Rhs = Self>: Sized {
    type Output;
    fn logical_or<F>(self, rhs: F) -> Self::Output 
    where
        F: FnOnce() -> Rhs;
}
trait LogicalAnd<Rhs = Self>: Sized {
    type Output;
    fn logical_and<F>(self, rhs: F) -> Self::Output 
    where
        F: FnOnce() -> Rhs;
}
These traits take in two arguments, self and an FnOnce closure that calculates the right-hand side. The trait implementation decides if it needs to call the closure or not.
For example, this is the implementation for bool:
impl LogicalOr for bool {
    type Output = bool;
    fn logical_or<F>(self, rhs: F) -> bool
    where
        F: FnOnce() -> bool
    {
        if self {
            true
        }else{
            rhs()
        }
    }
}
impl LogicalAnd for bool {
    type Output = bool;
    fn logical_and<F>(self, rhs: F) -> bool
    where
        F: FnOnce() -> bool
    {
        if self {
            rhs()
        }else{
            false
        }
    }
}
These traits desugar like this:
<expr a> || <expr b>
=>
(<expr a>).logical_or(||<expr b>)
<expr a> && <expr b>
=>
(<expr a>).logical_and(||<expr b>)