Skip to content

Commit

Permalink
Add description for LUB Coercion
Browse files Browse the repository at this point in the history
  • Loading branch information
ldm0 committed May 12, 2020
1 parent 30af091 commit c3fe177
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/type-coercions.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,47 @@ unsized coercion to `Foo<U>`.
[`Unsize`]: ../std/marker/trait.Unsize.html
[`CoerceUnsized`]: ../std/ops/trait.CoerceUnsized.html

## LUB Coercion

This is not in the RFC 401, but it's the behavior of current compiler. In LUB
Coercion, we tried to find the least upper bound of given types. It can be
observed in array collection, if-else/match arms.

For example:

```rust
let emm = if true {
A
} else if false {
B
} else {
C
};

let foo = match 42 {
0 => A,
1 => B,
_ => C,
};

let bar = [A, B, C];
```
In this example, both `emm` and `foo` has type
`LubCoerce(typeof(A), typeof(B), typeof(C))` and `bar` has type
`[LubCoerce(typeof(A), typeof(B), typeof(C)); 3]`.

LUB Coercion has some features:
1. Order independent: e.g. `LubCoerce(ty0, ty1, ty2, ty3)` equals to
`LubCoerce(ty1, ty0, ty4, ty3)`.
2. `LubCoerce(ty0, ty1, ty2, ...)` equals to
`LubCoerce(LubCoerce(ty0, ty1), ty2, ...)`
4. `LubCoerce(ty0, ty1) == ty2` means both `ty0` and `ty1` can be coerced to
`ty2`.

Notice the feature No.3, it uses the word "means" rather than "if and only if".
That's because currently if `ty0` and `ty1` can be coerced to `ty2` and `ty2`
equals to neither `ty0` nor `ty1`, there are only two special cases we can get
`LubCoerce(ty0, ty1) == ty2`:
1. `LubCoerce(FnDef, FnDef) == FnPtr`,
2. `LubCoerce(Closure, Closure) == FnPtr`(where Closure is non-capturing).

0 comments on commit c3fe177

Please sign in to comment.