From 8549ef5465504fecc63553f54401c300a820fb83 Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Mon, 20 May 2024 16:56:43 -0700 Subject: [PATCH] analyze: rewrite::convert: apply LoadFromTempForAdjustment before adjust, not after --- c2rust-analyze/src/rewrite/expr/convert.rs | 42 ++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/c2rust-analyze/src/rewrite/expr/convert.rs b/c2rust-analyze/src/rewrite/expr/convert.rs index 1c981fb372..dcb818acaf 100644 --- a/c2rust-analyze/src/rewrite/expr/convert.rs +++ b/c2rust-analyze/src/rewrite/expr/convert.rs @@ -440,15 +440,21 @@ impl<'tcx> Visitor<'tcx> for ConvertVisitor<'tcx> { .any(|x| matches!(x.desc, MirOriginDesc::Adjustment(_))); if self.materialize_adjustments || has_adjustment_rewrites { let adjusts = self.typeck_results.expr_adjustments(ex); - hir_rw = materialize_adjustments(self.tcx, adjusts, hir_rw, |i, mut hir_rw| { - let load_rws = take_prefix_while(&mut mir_rws, |x| { - x.desc == MirOriginDesc::LoadFromTempForAdjustment(i) + hir_rw = + materialize_adjustments(self.tcx, adjusts, hir_rw, |step, hir_rw| match step { + AdjustmentStep::Before(i) => { + let load_rws = take_prefix_while(&mut mir_rws, |x| { + x.desc == MirOriginDesc::LoadFromTempForAdjustment(i) + }); + self.rewrite_from_mir_rws(Some(ex), load_rws, hir_rw) + } + AdjustmentStep::After(i) => { + let adj_rws = take_prefix_while(&mut mir_rws, |x| { + x.desc == MirOriginDesc::Adjustment(i) + }); + self.rewrite_from_mir_rws(Some(ex), adj_rws, hir_rw) + } }); - hir_rw = self.rewrite_from_mir_rws(Some(ex), load_rws, hir_rw); - let adj_rws = - take_prefix_while(&mut mir_rws, |x| x.desc == MirOriginDesc::Adjustment(i)); - self.rewrite_from_mir_rws(Some(ex), adj_rws, hir_rw) - }); } // Apply late rewrites. @@ -517,11 +523,16 @@ fn apply_adjustment<'tcx>( } } +enum AdjustmentStep { + Before(usize), + After(usize), +} + fn materialize_adjustments<'tcx>( tcx: TyCtxt<'tcx>, adjustments: &[Adjustment<'tcx>], hir_rw: Rewrite, - mut callback: impl FnMut(usize, Rewrite) -> Rewrite, + mut callback: impl FnMut(AdjustmentStep, Rewrite) -> Rewrite, ) -> Rewrite { let adj_kinds: Vec<&_> = adjustments.iter().map(|a| &a.kind).collect(); match (hir_rw, &adj_kinds[..]) { @@ -529,19 +540,20 @@ fn materialize_adjustments<'tcx>( // reference type appropriate for the pointer's uses. However, we still want to give // `callback` a chance to remove the cast itself so that if there's a `RemoveCast` rewrite // on this adjustment, we don't get an error about it failing to apply. - (rw, &[Adjust::Pointer(PointerCast::MutToConstPointer)]) => { - let mut hir_rw = Rewrite::RemovedCast(Box::new(rw)); - hir_rw = callback(0, hir_rw); + (mut hir_rw, &[Adjust::Pointer(PointerCast::MutToConstPointer)]) => { + hir_rw = callback(AdjustmentStep::Before(0), hir_rw); + hir_rw = Rewrite::RemovedCast(Box::new(hir_rw)); + hir_rw = callback(AdjustmentStep::After(0), hir_rw); match hir_rw { Rewrite::RemovedCast(rw) => *rw, rw => rw, } } - (rw, _) => { - let mut hir_rw = rw; + (mut hir_rw, _) => { for (i, adj) in adjustments.iter().enumerate() { + hir_rw = callback(AdjustmentStep::Before(i), hir_rw); hir_rw = apply_adjustment(tcx, adj, hir_rw); - hir_rw = callback(i, hir_rw); + hir_rw = callback(AdjustmentStep::After(i), hir_rw); } hir_rw }