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>)
```