@@ -28,53 +28,37 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
28
28
/// }
29
29
/// ```
30
30
pub ( crate ) fn convert_iter_for_each_to_for ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
31
- let method;
32
-
33
- let stmt = if let Some ( stmt) = ctx. find_node_at_offset :: < ast:: ExprStmt > ( ) {
34
- method = ast:: MethodCallExpr :: cast ( stmt. syntax ( ) . first_child ( ) ?) ?;
35
- Some ( stmt)
36
- } else {
37
- method = match ctx. find_node_at_offset :: < ast:: Expr > ( ) ? {
38
- ast:: Expr :: MethodCallExpr ( expr) => expr,
39
- ast:: Expr :: ClosureExpr ( expr) => {
40
- ast:: MethodCallExpr :: cast ( expr. syntax ( ) . ancestors ( ) . nth ( 2 ) ?) ?
41
- }
42
- _ => {
43
- return None ;
44
- }
45
- } ;
46
- None
47
- } ;
31
+ let method = ctx. find_node_at_offset :: < ast:: MethodCallExpr > ( ) ?;
32
+ let stmt = method. syntax ( ) . parent ( ) . and_then ( ast:: ExprStmt :: cast) ;
48
33
49
34
let closure = match method. arg_list ( ) ?. args ( ) . next ( ) ? {
50
35
ast:: Expr :: ClosureExpr ( expr) => expr,
51
- _ => {
52
- return None ;
53
- }
36
+ _ => return None ,
54
37
} ;
55
38
56
- let ( method, parent ) = validate_method_call_expr ( & ctx. sema , method) ?;
39
+ let ( method, receiver ) = validate_method_call_expr ( & ctx. sema , method) ?;
57
40
58
41
let param_list = closure. param_list ( ) ?;
59
42
let param = param_list. params ( ) . next ( ) ?. pat ( ) ?;
60
43
let body = closure. body ( ) ?;
61
44
62
- let indent = stmt. as_ref ( ) . map_or ( method. indent_level ( ) , |stmt| stmt. indent_level ( ) ) ;
63
45
let syntax = stmt. as_ref ( ) . map_or ( method. syntax ( ) , |stmt| stmt. syntax ( ) ) ;
64
46
65
47
acc. add (
66
48
AssistId ( "convert_iter_for_each_to_for" , AssistKind :: RefactorRewrite ) ,
67
49
"Replace this `Iterator::for_each` with a for loop" ,
68
50
syntax. text_range ( ) ,
69
51
|builder| {
52
+ let indent = stmt. as_ref ( ) . map_or ( method. indent_level ( ) , |stmt| stmt. indent_level ( ) ) ;
53
+
70
54
let block = match body {
71
55
ast:: Expr :: BlockExpr ( block) => block,
72
56
_ => make:: block_expr ( Vec :: new ( ) , Some ( body) ) ,
73
57
}
74
58
. reset_indent ( )
75
59
. indent ( indent) ;
76
60
77
- let expr_for_loop = make:: expr_for_loop ( param, parent , block) ;
61
+ let expr_for_loop = make:: expr_for_loop ( param, receiver , block) ;
78
62
builder. replace ( syntax. text_range ( ) , expr_for_loop. syntax ( ) . text ( ) )
79
63
} ,
80
64
)
@@ -88,15 +72,15 @@ fn validate_method_call_expr(
88
72
return None ;
89
73
}
90
74
75
+ let receiver = expr. receiver ( ) ?;
91
76
let expr = ast:: Expr :: MethodCallExpr ( expr) ;
92
- let parent = ast:: Expr :: cast ( expr. syntax ( ) . first_child ( ) ?) ?;
93
77
94
- let it_type = sema. type_of_expr ( & parent ) ?;
95
- let module = sema. scope ( parent . syntax ( ) ) . module ( ) ?;
78
+ let it_type = sema. type_of_expr ( & receiver ) ?;
79
+ let module = sema. scope ( receiver . syntax ( ) ) . module ( ) ?;
96
80
let krate = module. krate ( ) ;
97
81
98
82
let iter_trait = FamousDefs ( sema, Some ( krate) ) . core_iter_Iterator ( ) ?;
99
- it_type. impls_trait ( sema. db , iter_trait, & [ ] ) . then ( || ( expr, parent ) )
83
+ it_type. impls_trait ( sema. db , iter_trait, & [ ] ) . then ( || ( expr, receiver ) )
100
84
}
101
85
102
86
#[ cfg( test) ]
@@ -175,34 +159,36 @@ fn main() {
175
159
}
176
160
177
161
#[ test]
178
- fn test_for_each_without_braces_stmt ( ) {
162
+ fn test_for_each_in_iter_stmt ( ) {
179
163
check_assist_with_fixtures (
180
164
r#"
181
165
use empty_iter::*;
182
166
fn main() {
183
- let x = Empty;
184
- x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
167
+ let x = Empty.iter();
168
+ x.$0for_each(|(x, y)| {
169
+ println!("x: {}, y: {}", x, y);
170
+ });
185
171
}"# ,
186
172
r#"
187
173
use empty_iter::*;
188
174
fn main() {
189
- let x = Empty;
190
- for (x, y) in x.iter() {
191
- println!("x: {}, y: {}", x, y)
175
+ let x = Empty.iter() ;
176
+ for (x, y) in x {
177
+ println!("x: {}, y: {}", x, y);
192
178
}
193
179
}
194
180
"# ,
195
181
)
196
182
}
197
183
198
184
#[ test]
199
- fn test_for_each_in_closure_stmt ( ) {
185
+ fn test_for_each_without_braces_stmt ( ) {
200
186
check_assist_with_fixtures (
201
187
r#"
202
188
use empty_iter::*;
203
189
fn main() {
204
190
let x = Empty;
205
- x.iter().for_each($0 |(x, y)| println!("x: {}, y: {}", x, y));
191
+ x.iter().$0for_each( |(x, y)| println!("x: {}, y: {}", x, y));
206
192
}"# ,
207
193
r#"
208
194
use empty_iter::*;
@@ -215,7 +201,6 @@ fn main() {
215
201
"# ,
216
202
)
217
203
}
218
-
219
204
#[ test]
220
205
fn test_for_each_not_applicable ( ) {
221
206
check_assist_not_applicable (
0 commit comments