1
- use syntax:: ast:: { edit:: AstNodeEdit , AstNode , HasName , LetStmt , Pat } ;
1
+ use hir:: Semantics ;
2
+ use ide_db:: RootDatabase ;
3
+ use syntax:: ast:: { edit:: AstNodeEdit , AstNode , HasName , LetStmt , Name , Pat } ;
2
4
use syntax:: T ;
3
5
4
6
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
5
7
6
8
/// Gets a list of binders in a pattern, and whether they are mut.
7
- fn binders_in_pat ( pat : & Pat ) -> Option < Vec < ( String , bool ) > > {
9
+ fn binders_in_pat (
10
+ acc : & mut Vec < ( Name , bool ) > ,
11
+ pat : & Pat ,
12
+ sem : & Semantics < RootDatabase > ,
13
+ ) -> Option < ( ) > {
8
14
use Pat :: * ;
9
15
match pat {
10
16
IdentPat ( p) => {
11
- let ident = p. name ( ) ?. text ( ) . to_string ( ) ;
17
+ let ident = p. name ( ) ?;
12
18
let ismut = p. ref_token ( ) . is_none ( ) && p. mut_token ( ) . is_some ( ) ;
13
- let mut res = vec ! [ ( ident, ismut) ] ;
19
+ acc . push ( ( ident, ismut) ) ;
14
20
if let Some ( inner) = p. pat ( ) {
15
- res . extend ( binders_in_pat ( & inner) ? ) ;
21
+ binders_in_pat ( acc , & inner, sem ) ? ;
16
22
}
17
- Some ( res )
23
+ Some ( ( ) )
18
24
}
19
- BoxPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( & p ) ) ,
20
- RestPat ( _) | LiteralPat ( _) | PathPat ( _) | WildcardPat ( _) | ConstBlockPat ( _) => Some ( vec ! [ ] ) ,
25
+ BoxPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( acc , & p , sem ) ) ,
26
+ RestPat ( _) | LiteralPat ( _) | PathPat ( _) | WildcardPat ( _) | ConstBlockPat ( _) => Some ( ( ) ) ,
21
27
OrPat ( p) => {
22
- let mut v = vec ! [ ] ;
23
28
for p in p. pats ( ) {
24
- v . extend ( binders_in_pat ( & p ) ? ) ;
29
+ binders_in_pat ( acc , & p , sem ) ? ;
25
30
}
26
- Some ( v )
31
+ Some ( ( ) )
27
32
}
28
- ParenPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( & p ) ) ,
33
+ ParenPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( acc , & p , sem ) ) ,
29
34
RangePat ( p) => {
30
- let mut start = if let Some ( st) = p. start ( ) { binders_in_pat ( & st) ? } else { vec ! [ ] } ;
31
- let end = if let Some ( st) = p. end ( ) { binders_in_pat ( & st) ? } else { vec ! [ ] } ;
32
- start. extend ( end) ;
33
- Some ( start)
35
+ if let Some ( st) = p. start ( ) {
36
+ binders_in_pat ( acc, & st, sem) ?
37
+ }
38
+ if let Some ( ed) = p. end ( ) {
39
+ binders_in_pat ( acc, & ed, sem) ?
40
+ }
41
+ Some ( ( ) )
34
42
}
35
43
RecordPat ( p) => {
36
- let mut v = vec ! [ ] ;
37
44
for f in p. record_pat_field_list ( ) ?. fields ( ) {
38
45
let pat = f. pat ( ) ?;
39
- v . extend ( binders_in_pat ( & pat) ? ) ;
46
+ binders_in_pat ( acc , & pat, sem ) ? ;
40
47
}
41
- Some ( v )
48
+ Some ( ( ) )
42
49
}
43
- RefPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( & p ) ) ,
50
+ RefPat ( p) => p. pat ( ) . and_then ( |p| binders_in_pat ( acc , & p , sem ) ) ,
44
51
SlicePat ( p) => {
45
- let mut v = vec ! [ ] ;
46
52
for p in p. pats ( ) {
47
- v . extend ( binders_in_pat ( & p ) ? ) ;
53
+ binders_in_pat ( acc , & p , sem ) ? ;
48
54
}
49
- Some ( v )
55
+ Some ( ( ) )
50
56
}
51
57
TuplePat ( p) => {
52
- let mut v = vec ! [ ] ;
53
58
for p in p. fields ( ) {
54
- v . extend ( binders_in_pat ( & p ) ? ) ;
59
+ binders_in_pat ( acc , & p , sem ) ? ;
55
60
}
56
- Some ( v )
61
+ Some ( ( ) )
57
62
}
58
63
TupleStructPat ( p) => {
59
- let mut v = vec ! [ ] ;
60
64
for p in p. fields ( ) {
61
- v . extend ( binders_in_pat ( & p ) ? ) ;
65
+ binders_in_pat ( acc , & p , sem ) ? ;
62
66
}
63
- Some ( v )
67
+ Some ( ( ) )
64
68
}
65
69
// don't support macro pat yet
66
70
MacroPat ( _) => None ,
67
71
}
68
72
}
69
73
70
- fn binders_to_str ( binders : & [ ( String , bool ) ] , addmut : bool ) -> String {
74
+ fn binders_to_str ( binders : & [ ( Name , bool ) ] , addmut : bool ) -> String {
71
75
let vars = binders
72
76
. iter ( )
73
77
. map (
@@ -119,7 +123,8 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext)
119
123
return None ;
120
124
}
121
125
let pat = let_stmt. pat ( ) ?;
122
- let binders = binders_in_pat ( & pat) ?;
126
+ let mut binders = Vec :: new ( ) ;
127
+ binders_in_pat ( & mut binders, & pat, & ctx. sema ) ?;
123
128
124
129
let target = let_stmt. syntax ( ) . text_range ( ) ;
125
130
acc. add (
@@ -139,7 +144,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext)
139
144
// remove the mut from the pattern
140
145
for ( b, ismut) in binders. iter ( ) {
141
146
if * ismut {
142
- pat_no_mut = pat_no_mut. replace ( & format ! ( "mut {b}" ) , b ) ;
147
+ pat_no_mut = pat_no_mut. replace ( & format ! ( "mut {b}" ) , & b . to_string ( ) ) ;
143
148
}
144
149
}
145
150
0 commit comments