@@ -231,14 +231,14 @@ LUB coercion has the following properties:
231
231
` LubCoerce(ty1, ty0, ty4, ty3) ` .
232
232
2 . ` LubCoerce(ty0, ty1, ty2, ...) ` equals to
233
233
` LubCoerce(LubCoerce(ty0, ty1), ty2, ...) `
234
- 3 . ` LubCoerce(ty0, ty1) == ty2 ` means both ` ty0 ` and ` ty1 ` can be coerced to
234
+ 3 . ` LubCoerce(ty0, ty1) == Some( ty2) ` means both ` ty0 ` and ` ty1 ` can be coerced to
235
235
` ty2 ` .
236
236
237
237
Notice the feature No.3, it uses the word "means" rather than "if and only if".
238
238
That's because currently if ` ty0 ` and ` ty1 ` can be coerced to ` ty2 ` and
239
239
unfortunately ` ty2 ` equals to neither ` ty0 ` nor ` ty1 ` , there are only one
240
- special situation where we can get ` LubCoerce(ty0, ty1) == ty2 ` :
241
- ` LubCoerce((FnDef | Closure), (FnDef | Closure)) == FnPtr ` (where Closure is
240
+ special situation where we can get ` LubCoerce(ty0, ty1) == Some( ty2) ` :
241
+ ` LubCoerce((FnDef | Closure), (FnDef | Closure)) == Some( FnPtr) ` (where Closure is
242
242
non-capturing).
243
243
244
244
If the comments above confuses you, here is the pseudo code of ` LubCoerce `
@@ -267,3 +267,28 @@ LubCoerce(vars):
267
267
result = Lub(result, var)
268
268
return result
269
269
```
270
+
271
+ It also worth mentioning code below compiles if and only if
272
+ ` LubCoerce(Ty, typeof(a), typeof(b)).is_some() ` :
273
+
274
+ ``` rust
275
+ # #[derive(Clone , Copy )]
276
+ # struct Ty ;
277
+ # let (a , b ) = (Ty , Ty );
278
+ let foo : Ty = if true {
279
+ a
280
+ } else {
281
+ b
282
+ };
283
+
284
+ let bar : Ty = match true {
285
+ true => a ,
286
+ false => b ,
287
+ };
288
+
289
+ let baz : [Ty ; 2 ] = [a , b ];
290
+ ```
291
+
292
+ That's because with expected type, the compiler checks
293
+ ` LubCoerce(expected, ty0, ty1, ty2...).is_some() ` rather than
294
+ ` LubCoerce(ty0, ty1, ty2...) == expected ` .
0 commit comments