@@ -35,7 +35,10 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
35
35
cov_mark:: hit!( extract_var_in_comment_is_not_applicable) ;
36
36
return None ;
37
37
}
38
- let to_extract = node. ancestors ( ) . find_map ( valid_target_expr) ?;
38
+ let to_extract = node
39
+ . ancestors ( )
40
+ . take_while ( |it| it. text_range ( ) . contains_range ( ctx. frange . range ) )
41
+ . find_map ( valid_target_expr) ?;
39
42
if let Some ( ty) = ctx. sema . type_of_expr ( & to_extract) {
40
43
if ty. is_unit ( ) {
41
44
return None ;
@@ -142,41 +145,43 @@ enum Anchor {
142
145
143
146
impl Anchor {
144
147
fn from ( to_extract : & ast:: Expr ) -> Option < Anchor > {
145
- to_extract. syntax ( ) . ancestors ( ) . find_map ( |node| {
146
- if let Some ( expr) =
147
- node. parent ( ) . and_then ( ast:: BlockExpr :: cast) . and_then ( |it| it. tail_expr ( ) )
148
- {
149
- if expr. syntax ( ) == & node {
150
- cov_mark:: hit!( test_extract_var_last_expr) ;
151
- return Some ( Anchor :: Before ( node) ) ;
148
+ to_extract. syntax ( ) . ancestors ( ) . take_while ( |it| !ast:: Item :: can_cast ( it. kind ( ) ) ) . find_map (
149
+ |node| {
150
+ if let Some ( expr) =
151
+ node. parent ( ) . and_then ( ast:: BlockExpr :: cast) . and_then ( |it| it. tail_expr ( ) )
152
+ {
153
+ if expr. syntax ( ) == & node {
154
+ cov_mark:: hit!( test_extract_var_last_expr) ;
155
+ return Some ( Anchor :: Before ( node) ) ;
156
+ }
152
157
}
153
- }
154
158
155
- if let Some ( parent) = node. parent ( ) {
156
- if parent. kind ( ) == CLOSURE_EXPR {
157
- cov_mark:: hit!( test_extract_var_in_closure_no_block) ;
158
- return Some ( Anchor :: WrapInBlock ( node) ) ;
159
- }
160
- if parent. kind ( ) == MATCH_ARM {
161
- if node. kind ( ) == MATCH_GUARD {
162
- cov_mark:: hit!( test_extract_var_in_match_guard) ;
163
- } else {
164
- cov_mark:: hit!( test_extract_var_in_match_arm_no_block) ;
159
+ if let Some ( parent) = node. parent ( ) {
160
+ if parent. kind ( ) == CLOSURE_EXPR {
161
+ cov_mark:: hit!( test_extract_var_in_closure_no_block) ;
165
162
return Some ( Anchor :: WrapInBlock ( node) ) ;
166
163
}
164
+ if parent. kind ( ) == MATCH_ARM {
165
+ if node. kind ( ) == MATCH_GUARD {
166
+ cov_mark:: hit!( test_extract_var_in_match_guard) ;
167
+ } else {
168
+ cov_mark:: hit!( test_extract_var_in_match_arm_no_block) ;
169
+ return Some ( Anchor :: WrapInBlock ( node) ) ;
170
+ }
171
+ }
167
172
}
168
- }
169
173
170
- if let Some ( stmt) = ast:: Stmt :: cast ( node. clone ( ) ) {
171
- if let ast:: Stmt :: ExprStmt ( stmt) = stmt {
172
- if stmt. expr ( ) . as_ref ( ) == Some ( to_extract) {
173
- return Some ( Anchor :: Replace ( stmt) ) ;
174
+ if let Some ( stmt) = ast:: Stmt :: cast ( node. clone ( ) ) {
175
+ if let ast:: Stmt :: ExprStmt ( stmt) = stmt {
176
+ if stmt. expr ( ) . as_ref ( ) == Some ( to_extract) {
177
+ return Some ( Anchor :: Replace ( stmt) ) ;
178
+ }
174
179
}
180
+ return Some ( Anchor :: Before ( node) ) ;
175
181
}
176
- return Some ( Anchor :: Before ( node) ) ;
177
- }
178
- None
179
- } )
182
+ None
183
+ } ,
184
+ )
180
185
}
181
186
182
187
fn syntax ( & self ) -> & SyntaxNode {
@@ -844,4 +849,14 @@ fn main() {
844
849
"2 + 2" ,
845
850
) ;
846
851
}
852
+
853
+ #[ test]
854
+ fn extract_var_no_block_body ( ) {
855
+ check_assist_not_applicable (
856
+ extract_variable,
857
+ r"
858
+ const X: usize = $0100$0;
859
+ " ,
860
+ ) ;
861
+ }
847
862
}
0 commit comments