1+ use hir:: TypeInfo ;
12use stdx:: format_to;
23use syntax:: {
34 ast:: { self , AstNode } ,
@@ -46,21 +47,24 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
4647 . take_while ( |it| ctx. selection_trimmed ( ) . contains_range ( it. text_range ( ) ) )
4748 . find_map ( valid_target_expr) ?;
4849
49- if let Some ( ty_info) = ctx. sema . type_of_expr ( & to_extract) {
50- if ty_info. adjusted ( ) . is_unit ( ) {
51- return None ;
52- }
50+ let ty = ctx. sema . type_of_expr ( & to_extract) . map ( TypeInfo :: adjusted) ;
51+ if matches ! ( & ty, Some ( ty_info) if ty_info. is_unit( ) ) {
52+ return None ;
5353 }
5454
55- let reference_modifier = match get_receiver_type ( ctx, & to_extract) {
55+ let parent = to_extract. syntax ( ) . parent ( ) . and_then ( ast:: Expr :: cast) ;
56+ let needs_adjust = parent
57+ . as_ref ( )
58+ . map_or ( false , |it| matches ! ( it, ast:: Expr :: FieldExpr ( _) | ast:: Expr :: MethodCallExpr ( _) ) ) ;
59+
60+ let reference_modifier = match ty. filter ( |_| needs_adjust) {
5661 Some ( receiver_type) if receiver_type. is_mutable_reference ( ) => "&mut " ,
5762 Some ( receiver_type) if receiver_type. is_reference ( ) => "&" ,
5863 _ => "" ,
5964 } ;
6065
61- let parent_ref_expr = to_extract. syntax ( ) . parent ( ) . and_then ( ast:: RefExpr :: cast) ;
62- let var_modifier = match parent_ref_expr {
63- Some ( expr) if expr. mut_token ( ) . is_some ( ) => "mut " ,
66+ let var_modifier = match parent {
67+ Some ( ast:: Expr :: RefExpr ( expr) ) if expr. mut_token ( ) . is_some ( ) => "mut " ,
6468 _ => "" ,
6569 } ;
6670
@@ -164,22 +168,6 @@ fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
164168 }
165169}
166170
167- fn get_receiver_type ( ctx : & AssistContext < ' _ > , expression : & ast:: Expr ) -> Option < hir:: Type > {
168- let receiver = get_receiver ( expression. clone ( ) ) ?;
169- Some ( ctx. sema . type_of_expr ( & receiver) ?. original ( ) )
170- }
171-
172- /// In the expression `a.b.c.x()`, find `a`
173- fn get_receiver ( expression : ast:: Expr ) -> Option < ast:: Expr > {
174- match expression {
175- ast:: Expr :: FieldExpr ( field) if field. expr ( ) . is_some ( ) => {
176- let nested_expression = & field. expr ( ) ?;
177- get_receiver ( nested_expression. to_owned ( ) )
178- }
179- _ => Some ( expression) ,
180- }
181- }
182-
183171#[ derive( Debug ) ]
184172enum Anchor {
185173 Before ( SyntaxNode ) ,
@@ -944,6 +932,11 @@ struct S {
944932 vec: Vec<u8>
945933}
946934
935+ struct Vec<T>;
936+ impl<T> Vec<T> {
937+ fn push(&mut self, _:usize) {}
938+ }
939+
947940fn foo(s: &mut S) {
948941 $0s.vec$0.push(0);
949942}"# ,
@@ -952,6 +945,11 @@ struct S {
952945 vec: Vec<u8>
953946}
954947
948+ struct Vec<T>;
949+ impl<T> Vec<T> {
950+ fn push(&mut self, _:usize) {}
951+ }
952+
955953fn foo(s: &mut S) {
956954 let $0vec = &mut s.vec;
957955 vec.push(0);
@@ -973,6 +971,10 @@ struct X {
973971struct S {
974972 vec: Vec<u8>
975973}
974+ struct Vec<T>;
975+ impl<T> Vec<T> {
976+ fn push(&mut self, _:usize) {}
977+ }
976978
977979fn foo(f: &mut Y) {
978980 $0f.field.field.vec$0.push(0);
@@ -987,6 +989,10 @@ struct X {
987989struct S {
988990 vec: Vec<u8>
989991}
992+ struct Vec<T>;
993+ impl<T> Vec<T> {
994+ fn push(&mut self, _:usize) {}
995+ }
990996
991997fn foo(f: &mut Y) {
992998 let $0vec = &mut f.field.field.vec;
@@ -1123,7 +1129,7 @@ struct S {
11231129}
11241130
11251131fn foo(s: S) {
1126- let $0x = s.sub;
1132+ let $0x = & s.sub;
11271133 x.do_thing();
11281134}"# ,
11291135 ) ;
@@ -1189,7 +1195,7 @@ impl X {
11891195
11901196fn foo() {
11911197 let local = &mut S::new();
1192- let $0x = &mut local.sub;
1198+ let $0x = &local.sub;
11931199 x.do_thing();
11941200}"# ,
11951201 ) ;
0 commit comments