Skip to content

Commit

Permalink
analyze: rewrite::convert: apply LoadFromTempForAdjustment before adj…
Browse files Browse the repository at this point in the history
…ust, not after
  • Loading branch information
spernsteiner committed Jun 25, 2024
1 parent 0bb0480 commit 8549ef5
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions c2rust-analyze/src/rewrite/expr/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -517,31 +523,37 @@ 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[..]) {
// The mut-to-const cast should be unneeded once the inner rewrite switches to a safe
// 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
}
Expand Down

0 comments on commit 8549ef5

Please sign in to comment.