@@ -15,7 +15,7 @@ use ide_db::{
1515} ;
1616use itertools:: { izip, Itertools } ;
1717use syntax:: {
18- ast:: { self , edit:: IndentLevel , edit_in_place:: Indent , HasArgList , PathExpr } ,
18+ ast:: { self , edit:: IndentLevel , edit_in_place:: Indent , HasArgList , Pat , PathExpr } ,
1919 ted, AstNode , NodeOrToken , SyntaxKind ,
2020} ;
2121
@@ -278,7 +278,7 @@ fn get_fn_params(
278278
279279 let mut params = Vec :: new ( ) ;
280280 if let Some ( self_param) = param_list. self_param ( ) {
281- // FIXME this should depend on the receiver as well as the self_param
281+ // Keep `ref` and `mut` and transform them into `&` and `mut` later
282282 params. push ( (
283283 make:: ident_pat (
284284 self_param. amp_token ( ) . is_some ( ) ,
@@ -409,16 +409,56 @@ fn inline(
409409 let mut let_stmts = Vec :: new ( ) ;
410410
411411 // Inline parameter expressions or generate `let` statements depending on whether inlining works or not.
412- for ( ( pat, param_ty, _ ) , usages, expr) in izip ! ( params, param_use_nodes, arguments) {
412+ for ( ( pat, param_ty, param ) , usages, expr) in izip ! ( params, param_use_nodes, arguments) {
413413 // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
414414 let usages: & [ ast:: PathExpr ] = & usages;
415415 let expr: & ast:: Expr = expr;
416416
417417 let mut insert_let_stmt = || {
418418 let ty = sema. type_of_expr ( expr) . filter ( TypeInfo :: has_adjustment) . and ( param_ty. clone ( ) ) ;
419- let_stmts. push (
420- make:: let_stmt ( pat. clone ( ) , ty, Some ( expr. clone ( ) ) ) . clone_for_update ( ) . into ( ) ,
421- ) ;
419+
420+ let is_self = param
421+ . name ( sema. db )
422+ . and_then ( |name| name. as_text ( ) )
423+ . is_some_and ( |name| name == "self" ) ;
424+
425+ if is_self {
426+ let mut this_pat = make:: ident_pat ( false , false , make:: name ( "this" ) ) ;
427+ let mut expr = expr. clone ( ) ;
428+ match pat {
429+ Pat :: IdentPat ( pat) => match ( pat. ref_token ( ) , pat. mut_token ( ) ) {
430+ // self => let this = obj
431+ ( None , None ) => { }
432+ // mut self => let mut this = obj
433+ ( None , Some ( _) ) => {
434+ this_pat = make:: ident_pat ( false , true , make:: name ( "this" ) ) ;
435+ }
436+ // &self => let this = &obj
437+ ( Some ( _) , None ) => {
438+ expr = make:: expr_ref ( expr, false ) ;
439+ }
440+ // let foo = &mut X; &mut self => let this = &mut obj
441+ // let mut foo = X; &mut self => let this = &mut *obj (reborrow)
442+ ( Some ( _) , Some ( _) ) => {
443+ let should_reborrow = sema
444+ . type_of_expr ( & expr)
445+ . map ( |ty| ty. original . is_mutable_reference ( ) ) ;
446+ expr = if let Some ( true ) = should_reborrow {
447+ make:: expr_reborrow ( expr)
448+ } else {
449+ make:: expr_ref ( expr, true )
450+ } ;
451+ }
452+ } ,
453+ _ => { }
454+ } ;
455+ let_stmts
456+ . push ( make:: let_stmt ( this_pat. into ( ) , ty, Some ( expr) ) . clone_for_update ( ) . into ( ) )
457+ } else {
458+ let_stmts. push (
459+ make:: let_stmt ( pat. clone ( ) , ty, Some ( expr. clone ( ) ) ) . clone_for_update ( ) . into ( ) ,
460+ ) ;
461+ }
422462 } ;
423463
424464 // check if there is a local var in the function that conflicts with parameter
@@ -484,12 +524,10 @@ fn inline(
484524 body = make:: block_expr ( let_stmts, Some ( body. into ( ) ) ) . clone_for_update ( ) ;
485525 }
486526 } else if let Some ( stmt_list) = body. stmt_list ( ) {
487- ted:: insert_all (
488- ted:: Position :: after (
489- stmt_list. l_curly_token ( ) . expect ( "L_CURLY for StatementList is missing." ) ,
490- ) ,
491- let_stmts. into_iter ( ) . map ( |stmt| stmt. syntax ( ) . clone ( ) . into ( ) ) . collect ( ) ,
492- ) ;
527+ let position = stmt_list. l_curly_token ( ) . expect ( "L_CURLY for StatementList is missing." ) ;
528+ let_stmts. into_iter ( ) . rev ( ) . for_each ( |let_stmt| {
529+ ted:: insert ( ted:: Position :: after ( position. clone ( ) ) , let_stmt. syntax ( ) . clone ( ) ) ;
530+ } ) ;
493531 }
494532
495533 let original_indentation = match node {
@@ -721,7 +759,7 @@ impl Foo {
721759
722760fn main() {
723761 let x = {
724- let ref this = Foo(3);
762+ let this = & Foo(3);
725763 Foo(this.0 + 2)
726764 };
727765}
@@ -757,7 +795,7 @@ impl Foo {
757795
758796fn main() {
759797 let x = {
760- let ref this = Foo(3);
798+ let this = & Foo(3);
761799 Foo(this.0 + 2)
762800 };
763801}
@@ -795,7 +833,7 @@ impl Foo {
795833fn main() {
796834 let mut foo = Foo(3);
797835 {
798- let ref mut this = foo;
836+ let this = &mut foo;
799837 this.0 = 0;
800838 };
801839}
@@ -882,7 +920,7 @@ impl Foo {
882920 }
883921 fn bar(&self) {
884922 {
885- let ref this = self;
923+ let this = & self;
886924 this;
887925 this;
888926 };
@@ -1557,7 +1595,7 @@ impl Enum {
15571595
15581596fn a() -> bool {
15591597 {
1560- let ref this = Enum::A;
1598+ let this = & Enum::A;
15611599 this == &Enum::A || this == &Enum::B
15621600 }
15631601}
@@ -1619,6 +1657,82 @@ fn main() {
16191657 a as A
16201658 };
16211659}
1660+ "# ,
1661+ )
1662+ }
1663+
1664+ #[ test]
1665+ fn method_by_reborrow ( ) {
1666+ check_assist (
1667+ inline_call,
1668+ r#"
1669+ pub struct Foo(usize);
1670+
1671+ impl Foo {
1672+ fn add1(&mut self) {
1673+ self.0 += 1;
1674+ }
1675+ }
1676+
1677+ pub fn main() {
1678+ let f = &mut Foo(0);
1679+ f.add1$0();
1680+ }
1681+ "# ,
1682+ r#"
1683+ pub struct Foo(usize);
1684+
1685+ impl Foo {
1686+ fn add1(&mut self) {
1687+ self.0 += 1;
1688+ }
1689+ }
1690+
1691+ pub fn main() {
1692+ let f = &mut Foo(0);
1693+ {
1694+ let this = &mut *f;
1695+ this.0 += 1;
1696+ };
1697+ }
1698+ "# ,
1699+ )
1700+ }
1701+
1702+ #[ test]
1703+ fn method_by_mut ( ) {
1704+ check_assist (
1705+ inline_call,
1706+ r#"
1707+ pub struct Foo(usize);
1708+
1709+ impl Foo {
1710+ fn add1(mut self) {
1711+ self.0 += 1;
1712+ }
1713+ }
1714+
1715+ pub fn main() {
1716+ let mut f = Foo(0);
1717+ f.add1$0();
1718+ }
1719+ "# ,
1720+ r#"
1721+ pub struct Foo(usize);
1722+
1723+ impl Foo {
1724+ fn add1(mut self) {
1725+ self.0 += 1;
1726+ }
1727+ }
1728+
1729+ pub fn main() {
1730+ let mut f = Foo(0);
1731+ {
1732+ let mut this = f;
1733+ this.0 += 1;
1734+ };
1735+ }
16221736"# ,
16231737 )
16241738 }
0 commit comments