@@ -1365,6 +1365,7 @@ pub fn can_coerce<'tcx>(
13651365/// - WARNING: I don't believe this final type is guaranteed to be
13661366/// related to your initial `expected_ty` in any particular way,
13671367/// although it will typically be a subtype, so you should check it.
1368+ /// Check the note below for more details.
13681369/// - Invoking `complete()` may cause us to go and adjust the "adjustments" on
13691370/// previously coerced expressions.
13701371///
@@ -1379,6 +1380,30 @@ pub fn can_coerce<'tcx>(
13791380/// let final_ty = coerce.complete(fcx);
13801381/// ```
13811382pub ( crate ) struct CoerceMany < ' tcx > {
1383+ ///
1384+ /// NOTE: Why does the `expected_ty` participate in the LUB?
1385+ /// When coercing, each branch should use the following expectations for type inference:
1386+ /// - The branch can be coerced to the expected type of the match/if/whatever.
1387+ /// - The branch can be coercion lub'd with the types of the previous branches.
1388+ /// Ideally we'd have some sort of `Expectation::ParticipatesInCoerceLub(ongoing_lub_ty, final_ty)`,
1389+ /// but adding and using this feels very challenging.
1390+ /// What we instead do is to use the expected type of the match/if/whatever as
1391+ /// the initial coercion lub. This allows us to use the lub of "expected type of match" with
1392+ /// "types from previous branches" as the coercion target, which can contains both expectations.
1393+ ///
1394+ /// Two concerns with this approach:
1395+ /// - We may have incompatible `final_ty` if that lub is different from the expected
1396+ /// type of the match. However, in this case coercing the final type of the
1397+ /// `CoerceMany` to its expected type would have error'd anyways, so we don't care.
1398+ /// - We may constrain the `expected_ty` too early. For some branches with
1399+ /// type `a` and `b`, we end up with `(a lub expected_ty) lub b` instead of
1400+ /// `(a lub b) lub expected_ty`. They should be the same type. However,
1401+ /// `a lub expected_ty` may constrain inference variables in `expected_ty`.
1402+ /// In this case the difference does matter and we get actually incorrect results.
1403+ /// FIXME: Ideally we'd compute the final type without unnecessarily constraining
1404+ /// the expected type of the match when computing the types of its branches.
1405+ pub ( crate ) struct CoerceMany <' tcx, ' exprs, E : AsCoercionSite > {
1406+ >>>>>>> d04050504b7 ( doc : explain why `expected_ty` participates in the LUB of `CoerceMany `)
13821407 expected_ty: Ty < ' tcx > ,
13831408 final_ty : Option < Ty < ' tcx > > ,
13841409 expressions : Vec < & ' tcx hir:: Expr < ' tcx > > ,
0 commit comments