@@ -1381,6 +1381,7 @@ pub fn can_coerce<'tcx>(
13811381/// - WARNING: I don't believe this final type is guaranteed to be
13821382/// related to your initial `expected_ty` in any particular way,
13831383/// although it will typically be a subtype, so you should check it.
1384+ /// Check the note below for more details.
13841385/// - Invoking `complete()` may cause us to go and adjust the "adjustments" on
13851386/// previously coerced expressions.
13861387///
@@ -1394,6 +1395,28 @@ pub fn can_coerce<'tcx>(
13941395/// }
13951396/// let final_ty = coerce.complete(fcx);
13961397/// ```
1398+ ///
1399+ /// NOTE: Why does the `expected_ty` participate in the LUB?
1400+ /// When coercing, each branch should use the following expectations for type inference:
1401+ /// - The branch can be coerced to the expected type of the match/if/whatever.
1402+ /// - The branch can be coercion lub'd with the types of the previous branches.
1403+ /// Ideally we'd have some sort of `Expectation::ParticipatsInCoerceLub(ongoing_lub_ty, final_ty)`,
1404+ /// but adding and using this feels very challenging.
1405+ /// What we instead do is to use the expected type of the match/if/whatever as
1406+ /// the initial coercion lub. This allows us to use the lub of "expected type of match" with
1407+ /// "types from previous branches" as the coercion target, which can contains both expectations.
1408+ ///
1409+ /// Two concerns with this approach:
1410+ /// - We may have incompatible `final_ty` if that lub is different from the expected
1411+ /// type of the match. However, in this case coercing the final type of the
1412+ /// `CoerceMany` to its expected type would have error'd anyways, so we don't care.
1413+ /// - We may constrain the `expected_ty` too early. For some branches with
1414+ /// type `a` and `b`, we end up with `(a lub expected_ty) lub b` instead of
1415+ /// `(a lub b) lub expected_ty`. They should be the same type. However,
1416+ /// `a lub expected_ty` may constrain inference variables in `expected_ty`.
1417+ /// In this case the difference does matter and we get actually incorrect results.
1418+ /// FIXME: Ideally we'd compute the final type without unnecessarily constraining
1419+ /// the expected type of the match when computing the types of its branches.
13971420pub ( crate ) struct CoerceMany < ' tcx , ' exprs , E : AsCoercionSite > {
13981421 expected_ty : Ty < ' tcx > ,
13991422 final_ty : Option < Ty < ' tcx > > ,
0 commit comments