11use rustc_middle:: ty:: adjustment:: { Adjust , AutoBorrow , AutoBorrowMutability } ;
22use rustc_ast:: { Crate , Expr , ExprKind , Mutability , UnOp } ;
33use rustc_ast:: ptr:: P ;
4+ use rustc_type_ir:: sty;
45
56use crate :: ast_builder:: mk;
67use crate :: ast_manip:: MutVisitNodes ;
@@ -59,21 +60,21 @@ impl Transform for CanonicalizeRefs {
5960struct RemoveUnnecessaryRefs ;
6061
6162impl 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