1- use ide_db:: assists:: { AssistId , AssistKind } ;
1+ use ide_db:: {
2+ assists:: { AssistId , AssistKind } ,
3+ famous_defs:: FamousDefs ,
4+ } ;
25use syntax:: {
3- ast:: { self , make, HasArgList } ,
6+ ast:: { self , make, Expr , HasArgList } ,
47 AstNode ,
58} ;
69
@@ -21,6 +24,9 @@ use crate::{AssistContext, Assists};
2124// ```
2225pub ( crate ) fn replace_or_with_or_else ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
2326 let call: ast:: MethodCallExpr = ctx. find_node_at_offset ( ) ?;
27+
28+ is_option_or_result ( call. receiver ( ) ?, ctx) ?;
29+
2430 let ( name, arg_list) = ( call. name_ref ( ) ?, call. arg_list ( ) ?) ;
2531
2632 let replace = match & * name. text ( ) {
@@ -76,6 +82,8 @@ pub(crate) fn replace_or_with_or_else(acc: &mut Assists, ctx: &AssistContext<'_>
7682pub ( crate ) fn replace_or_else_with_or ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
7783 let call: ast:: MethodCallExpr = ctx. find_node_at_offset ( ) ?;
7884
85+ is_option_or_result ( call. receiver ( ) ?, ctx) ?;
86+
7987 let ( name, arg_list) = ( call. name_ref ( ) ?, call. arg_list ( ) ?) ;
8088
8189 let replace = match & * name. text ( ) {
@@ -115,9 +123,32 @@ pub(crate) fn replace_or_else_with_or(acc: &mut Assists, ctx: &AssistContext<'_>
115123 )
116124}
117125
126+ fn is_option_or_result ( receiver : Expr , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
127+ let ty = ctx. sema . type_of_expr ( & receiver) ?. adjusted ( ) . as_adt ( ) ?. as_enum ( ) ?;
128+ let option_enum =
129+ FamousDefs ( & ctx. sema , ctx. sema . scope ( receiver. syntax ( ) ) ?. krate ( ) ) . core_option_Option ( ) ;
130+
131+ if let Some ( option_enum) = option_enum {
132+ if ty == option_enum {
133+ return Some ( ( ) ) ;
134+ }
135+ }
136+
137+ let result_enum =
138+ FamousDefs ( & ctx. sema , ctx. sema . scope ( receiver. syntax ( ) ) ?. krate ( ) ) . core_result_Result ( ) ;
139+
140+ if let Some ( result_enum) = result_enum {
141+ if ty == result_enum {
142+ return Some ( ( ) ) ;
143+ }
144+ }
145+
146+ None
147+ }
148+
118149#[ cfg( test) ]
119150mod tests {
120- use crate :: tests:: check_assist;
151+ use crate :: tests:: { check_assist, check_assist_not_applicable } ;
121152
122153 use super :: * ;
123154
@@ -126,6 +157,7 @@ mod tests {
126157 check_assist (
127158 replace_or_with_or_else,
128159 r#"
160+ //- minicore: option
129161fn foo() {
130162 let foo = Some(1);
131163 return foo.unwrap_$0or(2);
@@ -145,6 +177,7 @@ fn foo() {
145177 check_assist (
146178 replace_or_with_or_else,
147179 r#"
180+ //- minicore: option
148181fn foo() {
149182 let foo = Some(1);
150183 return foo.unwrap_$0or(x());
@@ -164,6 +197,7 @@ fn foo() {
164197 check_assist (
165198 replace_or_with_or_else,
166199 r#"
200+ //- minicore: option
167201fn foo() {
168202 let foo = Some(1);
169203 return foo.unwrap_$0or({
@@ -195,6 +229,7 @@ fn foo() {
195229 check_assist (
196230 replace_or_else_with_or,
197231 r#"
232+ //- minicore: option
198233fn foo() {
199234 let foo = Some(1);
200235 return foo.unwrap_$0or_else(|| 2);
@@ -214,6 +249,7 @@ fn foo() {
214249 check_assist (
215250 replace_or_else_with_or,
216251 r#"
252+ //- minicore: option
217253fn foo() {
218254 let foo = Some(1);
219255 return foo.unwrap_$0or_else(x);
@@ -224,6 +260,39 @@ fn foo() {
224260 let foo = Some(1);
225261 return foo.unwrap_or(x());
226262}
263+ "# ,
264+ )
265+ }
266+
267+ #[ test]
268+ fn replace_or_else_with_or_result ( ) {
269+ check_assist (
270+ replace_or_else_with_or,
271+ r#"
272+ //- minicore: result
273+ fn foo() {
274+ let foo = Ok(1);
275+ return foo.unwrap_$0or_else(x);
276+ }
277+ "# ,
278+ r#"
279+ fn foo() {
280+ let foo = Ok(1);
281+ return foo.unwrap_or(x());
282+ }
283+ "# ,
284+ )
285+ }
286+
287+ #[ test]
288+ fn replace_or_else_with_or_not_applicable ( ) {
289+ check_assist_not_applicable (
290+ replace_or_else_with_or,
291+ r#"
292+ fn foo() {
293+ let foo = Ok(1);
294+ return foo.unwrap_$0or_else(x);
295+ }
227296"# ,
228297 )
229298 }
0 commit comments