Skip to content

Commit d5de663

Browse files
committed
c2rust-refactor: Fix remove_unnecessary_refs to ignore pointers
Change the behavior of remove_unnecessary_refs to not remove dereferences of pointers because those are generally required.
1 parent df2af7f commit d5de663

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

c2rust-refactor/src/transform/canonicalize_refs.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
22
use rustc_ast::{Crate, Expr, ExprKind, Mutability, UnOp};
33
use rustc_ast::ptr::P;
4+
use rustc_type_ir::sty;
45

56
use crate::ast_builder::mk;
67
use crate::ast_manip::MutVisitNodes;
@@ -59,21 +60,21 @@ impl Transform for CanonicalizeRefs {
5960
struct RemoveUnnecessaryRefs;
6061

6162
impl Transform for RemoveUnnecessaryRefs {
62-
fn transform(&self, krate: &mut Crate, _st: &CommandState, _cx: &RefactorCtxt) {
63+
fn transform(&self, krate: &mut Crate, _st: &CommandState, cx: &RefactorCtxt) {
6364
MutVisitNodes::visit(krate, |expr: &mut P<Expr>| {
6465
match &mut expr.kind {
6566
ExprKind::MethodCall(_path, args, _span) => {
6667
let (receiver, rest) = args.split_first_mut().unwrap();
67-
remove_reborrow(receiver);
68+
remove_reborrow(receiver, cx);
6869
remove_ref(receiver);
69-
remove_all_derefs(receiver);
70+
remove_all_derefs(receiver, cx);
7071
for arg in rest {
71-
remove_reborrow(arg);
72+
remove_reborrow(arg, cx);
7273
}
7374
}
7475
ExprKind::Call(_callee, args) => {
7576
for arg in args.iter_mut() {
76-
remove_reborrow(arg);
77+
remove_reborrow(arg, cx);
7778
}
7879
}
7980
_ => {}
@@ -93,21 +94,31 @@ fn remove_ref(expr: &mut P<Expr>) {
9394
}
9495
}
9596

96-
fn remove_all_derefs(expr: &mut P<Expr>) {
97+
fn is_pointer(expr: &P<Expr>, cx: &RefactorCtxt) -> bool {
98+
let ty = cx.node_type(expr.id);
99+
matches!(ty.kind(), sty::TyKind::RawPtr(..))
100+
}
101+
102+
fn remove_all_derefs(expr: &mut P<Expr>, cx: &RefactorCtxt) {
97103
match &expr.kind {
98-
ExprKind::Unary(UnOp::Deref, inner) => {
104+
ExprKind::Unary(UnOp::Deref, inner) if !is_pointer(inner, cx) => {
99105
*expr = inner.clone();
100-
remove_all_derefs(expr);
106+
remove_all_derefs(expr, cx);
101107
}
102108
_ => {}
103109
}
104110
}
105111

106-
fn remove_reborrow(expr: &mut P<Expr>) {
112+
fn remove_reborrow(expr: &mut P<Expr>, cx: &RefactorCtxt) {
107113
if let ExprKind::AddrOf(_, _, ref subexpr) = expr.kind {
108114
if let ExprKind::Unary(UnOp::Deref, ref subexpr) = subexpr.kind {
115+
if is_pointer(subexpr, cx) {
116+
// &* on a pointer produces a reference, so it's not a no-op
117+
return;
118+
}
119+
109120
*expr = subexpr.clone();
110-
remove_reborrow(expr);
121+
remove_reborrow(expr, cx);
111122
}
112123
}
113124
}

0 commit comments

Comments
 (0)