@@ -1168,7 +1168,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11681168 fn try_find_coercion_lub (
11691169 & self ,
11701170 cause : & ObligationCause < ' tcx > ,
1171- exprs : & [ & ' tcx hir:: Expr < ' tcx > ] ,
1171+ exprs : & [ ( & ' tcx hir:: Expr < ' tcx > , Ty < ' tcx > ) ] ,
11721172 prev_ty : Ty < ' tcx > ,
11731173 new : & hir:: Expr < ' _ > ,
11741174 new_ty : Ty < ' tcx > ,
@@ -1266,7 +1266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12661266 ty:: FnDef ( ..) => Adjust :: Pointer ( PointerCoercion :: ReifyFnPointer ( sig. safety ( ) ) ) ,
12671267 _ => span_bug ! ( new. span, "should not try to coerce a {new_ty} to a fn pointer" ) ,
12681268 } ;
1269- for expr in exprs. iter ( ) {
1269+ for ( expr, _expr_ty ) in exprs. iter ( ) {
12701270 self . apply_adjustments (
12711271 expr,
12721272 vec ! [ Adjustment { kind: prev_adjustment. clone( ) , target: fn_ptr } ] ,
@@ -1306,14 +1306,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13061306 }
13071307 }
13081308
1309+ // This is maybe not the *most correct* thing to do. Taking match arm checking as an example:
1310+ // This means that at each match arm, either the new arm ty must coerce into the current LUB (above),
1311+ // or the current LUB can be coerced into the new arm ty. What we *probably* actually want is that each arm
1312+ // can be coerced to the final LUB. Importantly, I can imagine a case where some arm can only be coered to some
1313+ // final LUB, but not some intermediate LUB - and that would fail here.
13091314 let ok = self
13101315 . commit_if_ok ( |_| coerce. coerce ( prev_ty, new_ty) )
13111316 // Avoid giving strange errors on failed attempts.
13121317 . map_err ( |e| first_error. unwrap_or ( e) ) ?;
1313-
1314- let ( adjustments, target) = self . register_infer_ok_obligations ( ok) ;
1315- for expr in exprs {
1316- self . apply_adjustments ( expr, adjustments. clone ( ) ) ;
1318+ let ( _, target) = self . register_infer_ok_obligations ( ok) ;
1319+
1320+ for ( expr, expr_ty) in exprs {
1321+ let ok = self
1322+ . commit_if_ok ( |_| coerce. coerce ( * expr_ty, new_ty) )
1323+ // Avoid giving strange errors on failed attempts.
1324+ . map_err ( |e| first_error. unwrap_or ( e) ) ?;
1325+ let ( adj, _) = self . register_infer_ok_obligations ( ok) ;
1326+ debug ! ( ?expr_ty, ?new_ty) ;
1327+ self . set_adjustments ( * expr, adj) ;
13171328 }
13181329 debug ! (
13191330 "coercion::try_find_coercion_lub: was able to coerce previous type {:?} to new type {:?} ({:?})" ,
@@ -1381,7 +1392,7 @@ pub fn can_coerce<'tcx>(
13811392pub ( crate ) struct CoerceMany < ' tcx > {
13821393 expected_ty : Ty < ' tcx > ,
13831394 final_ty : Option < Ty < ' tcx > > ,
1384- expressions : Vec < & ' tcx hir:: Expr < ' tcx > > ,
1395+ expressions : Vec < ( & ' tcx hir:: Expr < ' tcx > , Ty < ' tcx > ) > ,
13851396}
13861397
13871398impl < ' tcx > CoerceMany < ' tcx > {
@@ -1560,7 +1571,7 @@ impl<'tcx> CoerceMany<'tcx> {
15601571 Ok ( v) => {
15611572 self . final_ty = Some ( v) ;
15621573 if let Some ( e) = expression {
1563- self . expressions . push ( e ) ;
1574+ self . expressions . push ( ( e , expression_ty ) ) ;
15641575 }
15651576 }
15661577 Err ( coercion_error) => {
0 commit comments