aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists')
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs114
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs44
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs2
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs27
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs41
-rw-r--r--crates/ide_assists/src/handlers/generate_default_from_new.rs83
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs105
-rw-r--r--crates/ide_assists/src/handlers/inline_local_variable.rs55
-rw-r--r--crates/ide_assists/src/tests.rs8
9 files changed, 287 insertions, 192 deletions
diff --git a/crates/ide_assists/src/handlers/apply_demorgan.rs b/crates/ide_assists/src/handlers/apply_demorgan.rs
index c93959e66..e2bd6e456 100644
--- a/crates/ide_assists/src/handlers/apply_demorgan.rs
+++ b/crates/ide_assists/src/handlers/apply_demorgan.rs
@@ -147,74 +147,92 @@ fn opposite_logic_op(kind: ast::BinOp) -> Option<&'static str> {
147 147
148#[cfg(test)] 148#[cfg(test)]
149mod tests { 149mod tests {
150 use ide_db::helpers::FamousDefs;
151
152 use super::*;
153
154 use crate::tests::{check_assist, check_assist_not_applicable}; 150 use crate::tests::{check_assist, check_assist_not_applicable};
155 151
156 const ORDABLE_FIXTURE: &'static str = r" 152 use super::*;
157//- /lib.rs deps:core crate:ordable
158struct NonOrderable;
159struct Orderable;
160impl core::cmp::Ord for Orderable {}
161";
162
163 fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
164 let before = &format!(
165 "//- /main.rs crate:main deps:core,ordable\n{}\n{}{}",
166 ra_fixture_before,
167 FamousDefs::FIXTURE,
168 ORDABLE_FIXTURE
169 );
170 check_assist(apply_demorgan, before, &format!("{}\n", ra_fixture_after));
171 }
172 153
173 #[test] 154 #[test]
174 fn demorgan_handles_leq() { 155 fn demorgan_handles_leq() {
175 check( 156 check_assist(
176 r"use ordable::Orderable; 157 apply_demorgan,
158 r#"
159//- minicore: ord, derive
160#[derive(PartialEq, Eq, PartialOrd, Ord)]
161struct S;
162
177fn f() { 163fn f() {
178 Orderable < Orderable &&$0 Orderable <= Orderable 164 S < S &&$0 S <= S
179}", 165}
180 r"use ordable::Orderable; 166"#,
167 r#"
168#[derive(PartialEq, Eq, PartialOrd, Ord)]
169struct S;
170
181fn f() { 171fn f() {
182 !(Orderable >= Orderable || Orderable > Orderable) 172 !(S >= S || S > S)
183}", 173}
174"#,
184 ); 175 );
185 check( 176
186 r"use ordable::NonOrderable; 177 check_assist(
178 apply_demorgan,
179 r#"
180//- minicore: ord, derive
181struct S;
182
187fn f() { 183fn f() {
188 NonOrderable < NonOrderable &&$0 NonOrderable <= NonOrderable 184 S < S &&$0 S <= S
189}", 185}
190 r"use ordable::NonOrderable; 186"#,
187 r#"
188struct S;
189
191fn f() { 190fn f() {
192 !(!(NonOrderable < NonOrderable) || !(NonOrderable <= NonOrderable)) 191 !(!(S < S) || !(S <= S))
193}", 192}
193"#,
194 ); 194 );
195 } 195 }
196 196
197 #[test] 197 #[test]
198 fn demorgan_handles_geq() { 198 fn demorgan_handles_geq() {
199 check( 199 check_assist(
200 r"use ordable::Orderable; 200 apply_demorgan,
201 r#"
202//- minicore: ord, derive
203#[derive(PartialEq, Eq, PartialOrd, Ord)]
204struct S;
205
201fn f() { 206fn f() {
202 Orderable > Orderable &&$0 Orderable >= Orderable 207 S > S &&$0 S >= S
203}", 208}
204 r"use ordable::Orderable; 209"#,
210 r#"
211#[derive(PartialEq, Eq, PartialOrd, Ord)]
212struct S;
213
205fn f() { 214fn f() {
206 !(Orderable <= Orderable || Orderable < Orderable) 215 !(S <= S || S < S)
207}", 216}
217"#,
208 ); 218 );
209 check( 219 check_assist(
210 r"use ordable::NonOrderable; 220 apply_demorgan,
221 r#"
222//- minicore: ord, derive
223struct S;
224
211fn f() { 225fn f() {
212 Orderable > Orderable &&$0 Orderable >= Orderable 226 S > S &&$0 S >= S
213}", 227}
214 r"use ordable::NonOrderable; 228"#,
229 r#"
230struct S;
231
215fn f() { 232fn f() {
216 !(!(Orderable > Orderable) || !(Orderable >= Orderable)) 233 !(!(S > S) || !(S >= S))
217}", 234}
235"#,
218 ); 236 );
219 } 237 }
220 238
diff --git a/crates/ide_assists/src/handlers/convert_into_to_from.rs b/crates/ide_assists/src/handlers/convert_into_to_from.rs
index 199e1ad5c..79a0c4879 100644
--- a/crates/ide_assists/src/handlers/convert_into_to_from.rs
+++ b/crates/ide_assists/src/handlers/convert_into_to_from.rs
@@ -6,6 +6,8 @@ use syntax::ast::{self, AstNode, NameOwner};
6 6
7use crate::{AssistContext, AssistId, AssistKind, Assists}; 7use crate::{AssistContext, AssistId, AssistKind, Assists};
8 8
9// FIXME: this should be a diagnostic
10
9// Assist: convert_into_to_from 11// Assist: convert_into_to_from
10// 12//
11// Converts an Into impl to an equivalent From impl. 13// Converts an Into impl to an equivalent From impl.
@@ -114,12 +116,14 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext) -> Op
114mod tests { 116mod tests {
115 use super::*; 117 use super::*;
116 118
117 use crate::tests::check_assist; 119 use crate::tests::{check_assist, check_assist_not_applicable};
118 120
119 #[test] 121 #[test]
120 fn convert_into_to_from_converts_a_struct() { 122 fn convert_into_to_from_converts_a_struct() {
121 check_convert_into_to_from( 123 check_assist(
124 convert_into_to_from,
122 r#" 125 r#"
126//- minicore: from
123struct Thing { 127struct Thing {
124 a: String, 128 a: String,
125 b: usize 129 b: usize
@@ -154,8 +158,10 @@ impl From<usize> for Thing {
154 158
155 #[test] 159 #[test]
156 fn convert_into_to_from_converts_enums() { 160 fn convert_into_to_from_converts_enums() {
157 check_convert_into_to_from( 161 check_assist(
162 convert_into_to_from,
158 r#" 163 r#"
164//- minicore: from
159enum Thing { 165enum Thing {
160 Foo(String), 166 Foo(String),
161 Bar(String) 167 Bar(String)
@@ -190,8 +196,10 @@ impl From<Thing> for String {
190 196
191 #[test] 197 #[test]
192 fn convert_into_to_from_on_enum_with_lifetimes() { 198 fn convert_into_to_from_on_enum_with_lifetimes() {
193 check_convert_into_to_from( 199 check_assist(
200 convert_into_to_from,
194 r#" 201 r#"
202//- minicore: from
195enum Thing<'a> { 203enum Thing<'a> {
196 Foo(&'a str), 204 Foo(&'a str),
197 Bar(&'a str) 205 Bar(&'a str)
@@ -226,8 +234,10 @@ impl<'a> From<Thing<'a>> for &'a str {
226 234
227 #[test] 235 #[test]
228 fn convert_into_to_from_works_on_references() { 236 fn convert_into_to_from_works_on_references() {
229 check_convert_into_to_from( 237 check_assist(
238 convert_into_to_from,
230 r#" 239 r#"
240//- minicore: from
231struct Thing(String); 241struct Thing(String);
232 242
233impl $0core::convert::Into<String> for &Thing { 243impl $0core::convert::Into<String> for &Thing {
@@ -250,8 +260,10 @@ impl From<&Thing> for String {
250 260
251 #[test] 261 #[test]
252 fn convert_into_to_from_works_on_qualified_structs() { 262 fn convert_into_to_from_works_on_qualified_structs() {
253 check_convert_into_to_from( 263 check_assist(
264 convert_into_to_from,
254 r#" 265 r#"
266//- minicore: from
255mod things { 267mod things {
256 pub struct Thing(String); 268 pub struct Thing(String);
257 pub struct BetterThing(String); 269 pub struct BetterThing(String);
@@ -280,8 +292,10 @@ impl From<&things::Thing> for things::BetterThing {
280 292
281 #[test] 293 #[test]
282 fn convert_into_to_from_works_on_qualified_enums() { 294 fn convert_into_to_from_works_on_qualified_enums() {
283 check_convert_into_to_from( 295 check_assist(
296 convert_into_to_from,
284 r#" 297 r#"
298//- minicore: from
285mod things { 299mod things {
286 pub enum Thing { 300 pub enum Thing {
287 A(String) 301 A(String)
@@ -323,10 +337,12 @@ impl From<&things::Thing> for things::BetterThing {
323 #[test] 337 #[test]
324 fn convert_into_to_from_not_applicable_on_any_trait_named_into() { 338 fn convert_into_to_from_not_applicable_on_any_trait_named_into() {
325 check_assist_not_applicable( 339 check_assist_not_applicable(
340 convert_into_to_from,
326 r#" 341 r#"
327pub trait Into<T> {{ 342//- minicore: from
343pub trait Into<T> {
328 pub fn into(self) -> T; 344 pub fn into(self) -> T;
329}} 345}
330 346
331struct Thing { 347struct Thing {
332 a: String, 348 a: String,
@@ -342,14 +358,4 @@ impl $0Into<Thing> for String {
342"#, 358"#,
343 ); 359 );
344 } 360 }
345
346 fn check_convert_into_to_from(before: &str, after: &str) {
347 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
348 check_assist(convert_into_to_from, before, after);
349 }
350
351 fn check_assist_not_applicable(before: &str) {
352 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
353 crate::tests::check_assist_not_applicable(convert_into_to_from, before);
354 }
355} 361}
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index f2be091f4..7085a0c48 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -1384,7 +1384,7 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode)
1384 for (param, usages) in usages_for_param { 1384 for (param, usages) in usages_for_param {
1385 for usage in usages { 1385 for usage in usages {
1386 match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { 1386 match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
1387 Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { 1387 Some(ast::Expr::MethodCallExpr(_) | ast::Expr::FieldExpr(_)) => {
1388 // do nothing 1388 // do nothing
1389 } 1389 }
1390 Some(ast::Expr::RefExpr(node)) 1390 Some(ast::Expr::RefExpr(node))
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
index d3ff7b65c..6c6ff16c2 100644
--- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -48,6 +48,7 @@ pub(crate) fn extract_struct_from_enum_variant(
48 let variant_name = variant.name()?; 48 let variant_name = variant.name()?;
49 let variant_hir = ctx.sema.to_def(&variant)?; 49 let variant_hir = ctx.sema.to_def(&variant)?;
50 if existing_definition(ctx.db(), &variant_name, &variant_hir) { 50 if existing_definition(ctx.db(), &variant_name, &variant_hir) {
51 cov_mark::hit!(test_extract_enum_not_applicable_if_struct_exists);
51 return None; 52 return None;
52 } 53 }
53 54
@@ -300,18 +301,10 @@ fn reference_to_node(
300 301
301#[cfg(test)] 302#[cfg(test)]
302mod tests { 303mod tests {
303 use ide_db::helpers::FamousDefs;
304
305 use crate::tests::{check_assist, check_assist_not_applicable}; 304 use crate::tests::{check_assist, check_assist_not_applicable};
306 305
307 use super::*; 306 use super::*;
308 307
309 fn check_not_applicable(ra_fixture: &str) {
310 let fixture =
311 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
312 check_assist_not_applicable(extract_struct_from_enum_variant, &fixture)
313 }
314
315 #[test] 308 #[test]
316 fn test_extract_struct_several_fields_tuple() { 309 fn test_extract_struct_several_fields_tuple() {
317 check_assist( 310 check_assist(
@@ -699,29 +692,33 @@ fn foo() {
699 692
700 #[test] 693 #[test]
701 fn test_extract_enum_not_applicable_for_element_with_no_fields() { 694 fn test_extract_enum_not_applicable_for_element_with_no_fields() {
702 check_not_applicable("enum A { $0One }"); 695 check_assist_not_applicable(extract_struct_from_enum_variant, r#"enum A { $0One }"#);
703 } 696 }
704 697
705 #[test] 698 #[test]
706 fn test_extract_enum_not_applicable_if_struct_exists() { 699 fn test_extract_enum_not_applicable_if_struct_exists() {
707 check_not_applicable( 700 cov_mark::check!(test_extract_enum_not_applicable_if_struct_exists);
708 r#"struct One; 701 check_assist_not_applicable(
709 enum A { $0One(u8, u32) }"#, 702 extract_struct_from_enum_variant,
703 r#"
704struct One;
705enum A { $0One(u8, u32) }
706"#,
710 ); 707 );
711 } 708 }
712 709
713 #[test] 710 #[test]
714 fn test_extract_not_applicable_one_field() { 711 fn test_extract_not_applicable_one_field() {
715 check_not_applicable(r"enum A { $0One(u32) }"); 712 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0One(u32) }");
716 } 713 }
717 714
718 #[test] 715 #[test]
719 fn test_extract_not_applicable_no_field_tuple() { 716 fn test_extract_not_applicable_no_field_tuple() {
720 check_not_applicable(r"enum A { $0None() }"); 717 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0None() }");
721 } 718 }
722 719
723 #[test] 720 #[test]
724 fn test_extract_not_applicable_no_field_named() { 721 fn test_extract_not_applicable_no_field_named() {
725 check_not_applicable(r"enum A { $0None {} }"); 722 check_assist_not_applicable(extract_struct_from_enum_variant, r"enum A { $0None {} }");
726 } 723 }
727} 724}
diff --git a/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs b/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
index 588ee1350..e55c38502 100644
--- a/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
+++ b/crates/ide_assists/src/handlers/generate_default_from_enum_variant.rs
@@ -1,5 +1,4 @@
1use ide_db::helpers::FamousDefs; 1use ide_db::{helpers::FamousDefs, RootDatabase};
2use ide_db::RootDatabase;
3use syntax::ast::{self, AstNode, NameOwner}; 2use syntax::ast::{self, AstNode, NameOwner};
4 3
5use crate::{AssistContext, AssistId, AssistKind, Assists}; 4use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -92,23 +91,20 @@ mod tests {
92 91
93 use super::*; 92 use super::*;
94 93
95 fn check_not_applicable(ra_fixture: &str) {
96 let fixture =
97 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
98 check_assist_not_applicable(generate_default_from_enum_variant, &fixture)
99 }
100
101 #[test] 94 #[test]
102 fn test_generate_default_from_variant() { 95 fn test_generate_default_from_variant() {
103 check_assist( 96 check_assist(
104 generate_default_from_enum_variant, 97 generate_default_from_enum_variant,
105 r#" 98 r#"
99//- minicore: default
106enum Variant { 100enum Variant {
107 Undefined, 101 Undefined,
108 Minor$0, 102 Minor$0,
109 Major, 103 Major,
110}"#, 104}
111 r#"enum Variant { 105"#,
106 r#"
107enum Variant {
112 Undefined, 108 Undefined,
113 Minor, 109 Minor,
114 Major, 110 Major,
@@ -118,15 +114,18 @@ impl Default for Variant {
118 fn default() -> Self { 114 fn default() -> Self {
119 Self::Minor 115 Self::Minor
120 } 116 }
121}"#, 117}
118"#,
122 ); 119 );
123 } 120 }
124 121
125 #[test] 122 #[test]
126 fn test_generate_default_already_implemented() { 123 fn test_generate_default_already_implemented() {
127 cov_mark::check!(test_gen_default_impl_already_exists); 124 cov_mark::check!(test_gen_default_impl_already_exists);
128 check_not_applicable( 125 check_assist_not_applicable(
126 generate_default_from_enum_variant,
129 r#" 127 r#"
128//- minicore: default
130enum Variant { 129enum Variant {
131 Undefined, 130 Undefined,
132 Minor$0, 131 Minor$0,
@@ -137,20 +136,24 @@ impl Default for Variant {
137 fn default() -> Self { 136 fn default() -> Self {
138 Self::Minor 137 Self::Minor
139 } 138 }
140}"#, 139}
140"#,
141 ); 141 );
142 } 142 }
143 143
144 #[test] 144 #[test]
145 fn test_add_from_impl_no_element() { 145 fn test_add_from_impl_no_element() {
146 cov_mark::check!(test_gen_default_on_non_unit_variant_not_implemented); 146 cov_mark::check!(test_gen_default_on_non_unit_variant_not_implemented);
147 check_not_applicable( 147 check_assist_not_applicable(
148 generate_default_from_enum_variant,
148 r#" 149 r#"
150//- minicore: default
149enum Variant { 151enum Variant {
150 Undefined, 152 Undefined,
151 Minor(u32)$0, 153 Minor(u32)$0,
152 Major, 154 Major,
153}"#, 155}
156"#,
154 ); 157 );
155 } 158 }
156 159
@@ -158,7 +161,10 @@ enum Variant {
158 fn test_generate_default_from_variant_with_one_variant() { 161 fn test_generate_default_from_variant_with_one_variant() {
159 check_assist( 162 check_assist(
160 generate_default_from_enum_variant, 163 generate_default_from_enum_variant,
161 r#"enum Variant { Undefi$0ned }"#, 164 r#"
165//- minicore: default
166enum Variant { Undefi$0ned }
167"#,
162 r#" 168 r#"
163enum Variant { Undefined } 169enum Variant { Undefined }
164 170
@@ -166,7 +172,8 @@ impl Default for Variant {
166 fn default() -> Self { 172 fn default() -> Self {
167 Self::Undefined 173 Self::Undefined
168 } 174 }
169}"#, 175}
176"#,
170 ); 177 );
171 } 178 }
172} 179}
diff --git a/crates/ide_assists/src/handlers/generate_default_from_new.rs b/crates/ide_assists/src/handlers/generate_default_from_new.rs
index bad826366..b54ec59da 100644
--- a/crates/ide_assists/src/handlers/generate_default_from_new.rs
+++ b/crates/ide_assists/src/handlers/generate_default_from_new.rs
@@ -1,7 +1,3 @@
1use crate::{
2 assist_context::{AssistContext, Assists},
3 AssistId,
4};
5use ide_db::helpers::FamousDefs; 1use ide_db::helpers::FamousDefs;
6use itertools::Itertools; 2use itertools::Itertools;
7use stdx::format_to; 3use stdx::format_to;
@@ -10,6 +6,11 @@ use syntax::{
10 AstNode, 6 AstNode,
11}; 7};
12 8
9use crate::{
10 assist_context::{AssistContext, Assists},
11 AssistId,
12};
13
13// Assist: generate_default_from_new 14// Assist: generate_default_from_new
14// 15//
15// Generates default implementation from new method. 16// Generates default implementation from new method.
@@ -140,16 +141,16 @@ fn is_default_implemented(ctx: &AssistContext, impl_: &Impl) -> bool {
140 141
141#[cfg(test)] 142#[cfg(test)]
142mod tests { 143mod tests {
143 use ide_db::helpers::FamousDefs;
144
145 use crate::tests::{check_assist, check_assist_not_applicable}; 144 use crate::tests::{check_assist, check_assist_not_applicable};
146 145
147 use super::*; 146 use super::*;
148 147
149 #[test] 148 #[test]
150 fn generate_default() { 149 fn generate_default() {
151 check_pass( 150 check_assist(
151 generate_default_from_new,
152 r#" 152 r#"
153//- minicore: default
153struct Example { _inner: () } 154struct Example { _inner: () }
154 155
155impl Example { 156impl Example {
@@ -182,8 +183,10 @@ fn main() {}
182 183
183 #[test] 184 #[test]
184 fn generate_default2() { 185 fn generate_default2() {
185 check_pass( 186 check_assist(
187 generate_default_from_new,
186 r#" 188 r#"
189//- minicore: default
187struct Test { value: u32 } 190struct Test { value: u32 }
188 191
189impl Test { 192impl Test {
@@ -212,8 +215,10 @@ impl Default for Test {
212 215
213 #[test] 216 #[test]
214 fn new_function_with_generic() { 217 fn new_function_with_generic() {
215 check_pass( 218 check_assist(
219 generate_default_from_new,
216 r#" 220 r#"
221//- minicore: default
217pub struct Foo<T> { 222pub struct Foo<T> {
218 _bar: *mut T, 223 _bar: *mut T,
219} 224}
@@ -246,8 +251,10 @@ impl<T> Default for Foo<T> {
246 251
247 #[test] 252 #[test]
248 fn new_function_with_generics() { 253 fn new_function_with_generics() {
249 check_pass( 254 check_assist(
255 generate_default_from_new,
250 r#" 256 r#"
257//- minicore: default
251pub struct Foo<T, B> { 258pub struct Foo<T, B> {
252 _tars: *mut T, 259 _tars: *mut T,
253 _bar: *mut B, 260 _bar: *mut B,
@@ -282,8 +289,10 @@ impl<T, B> Default for Foo<T, B> {
282 289
283 #[test] 290 #[test]
284 fn new_function_with_generic_and_bound() { 291 fn new_function_with_generic_and_bound() {
285 check_pass( 292 check_assist(
293 generate_default_from_new,
286 r#" 294 r#"
295//- minicore: default
287pub struct Foo<T> { 296pub struct Foo<T> {
288 t: T, 297 t: T,
289} 298}
@@ -316,8 +325,10 @@ impl<T: From<i32>> Default for Foo<T> {
316 325
317 #[test] 326 #[test]
318 fn new_function_with_generics_and_bounds() { 327 fn new_function_with_generics_and_bounds() {
319 check_pass( 328 check_assist(
329 generate_default_from_new,
320 r#" 330 r#"
331//- minicore: default
321pub struct Foo<T, B> { 332pub struct Foo<T, B> {
322 _tars: T, 333 _tars: T,
323 _bar: B, 334 _bar: B,
@@ -352,8 +363,10 @@ impl<T: From<i32>, B: From<i64>> Default for Foo<T, B> {
352 363
353 #[test] 364 #[test]
354 fn new_function_with_generic_and_where() { 365 fn new_function_with_generic_and_where() {
355 check_pass( 366 check_assist(
367 generate_default_from_new,
356 r#" 368 r#"
369//- minicore: default
357pub struct Foo<T> { 370pub struct Foo<T> {
358 t: T, 371 t: T,
359} 372}
@@ -395,8 +408,10 @@ where
395 408
396 #[test] 409 #[test]
397 fn new_function_with_generics_and_wheres() { 410 fn new_function_with_generics_and_wheres() {
398 check_pass( 411 check_assist(
412 generate_default_from_new,
399 r#" 413 r#"
414//- minicore: default
400pub struct Foo<T, B> { 415pub struct Foo<T, B> {
401 _tars: T, 416 _tars: T,
402 _bar: B, 417 _bar: B,
@@ -441,8 +456,10 @@ where
441 #[test] 456 #[test]
442 fn new_function_with_parameters() { 457 fn new_function_with_parameters() {
443 cov_mark::check!(new_function_with_parameters); 458 cov_mark::check!(new_function_with_parameters);
444 check_not_applicable( 459 check_assist_not_applicable(
460 generate_default_from_new,
445 r#" 461 r#"
462//- minicore: default
446struct Example { _inner: () } 463struct Example { _inner: () }
447 464
448impl Example { 465impl Example {
@@ -457,7 +474,8 @@ impl Example {
457 #[test] 474 #[test]
458 fn other_function_than_new() { 475 fn other_function_than_new() {
459 cov_mark::check!(other_function_than_new); 476 cov_mark::check!(other_function_than_new);
460 check_not_applicable( 477 check_assist_not_applicable(
478 generate_default_from_new,
461 r#" 479 r#"
462struct Example { _inner: () } 480struct Example { _inner: () }
463 481
@@ -474,8 +492,10 @@ impl Example {
474 #[test] 492 #[test]
475 fn default_block_is_already_present() { 493 fn default_block_is_already_present() {
476 cov_mark::check!(default_block_is_already_present); 494 cov_mark::check!(default_block_is_already_present);
477 check_not_applicable( 495 check_assist_not_applicable(
496 generate_default_from_new,
478 r#" 497 r#"
498//- minicore: default
479struct Example { _inner: () } 499struct Example { _inner: () }
480 500
481impl Example { 501impl Example {
@@ -495,7 +515,8 @@ impl Default for Example {
495 515
496 #[test] 516 #[test]
497 fn standalone_new_function() { 517 fn standalone_new_function() {
498 check_not_applicable( 518 check_assist_not_applicable(
519 generate_default_from_new,
499 r#" 520 r#"
500fn n$0ew() -> u32 { 521fn n$0ew() -> u32 {
501 0 522 0
@@ -506,8 +527,10 @@ fn n$0ew() -> u32 {
506 527
507 #[test] 528 #[test]
508 fn multiple_struct_blocks() { 529 fn multiple_struct_blocks() {
509 check_pass( 530 check_assist(
531 generate_default_from_new,
510 r#" 532 r#"
533//- minicore: default
511struct Example { _inner: () } 534struct Example { _inner: () }
512struct Test { value: u32 } 535struct Test { value: u32 }
513 536
@@ -538,8 +561,10 @@ impl Default for Example {
538 561
539 #[test] 562 #[test]
540 fn when_struct_is_after_impl() { 563 fn when_struct_is_after_impl() {
541 check_pass( 564 check_assist(
565 generate_default_from_new,
542 r#" 566 r#"
567//- minicore: default
543impl Example { 568impl Example {
544 pub fn $0new() -> Self { 569 pub fn $0new() -> Self {
545 Self { _inner: () } 570 Self { _inner: () }
@@ -568,8 +593,10 @@ struct Example { _inner: () }
568 593
569 #[test] 594 #[test]
570 fn struct_in_module() { 595 fn struct_in_module() {
571 check_pass( 596 check_assist(
597 generate_default_from_new,
572 r#" 598 r#"
599//- minicore: default
573mod test { 600mod test {
574 struct Example { _inner: () } 601 struct Example { _inner: () }
575 602
@@ -603,8 +630,10 @@ impl Default for Example {
603 #[test] 630 #[test]
604 fn struct_in_module_with_default() { 631 fn struct_in_module_with_default() {
605 cov_mark::check!(struct_in_module_with_default); 632 cov_mark::check!(struct_in_module_with_default);
606 check_not_applicable( 633 check_assist_not_applicable(
634 generate_default_from_new,
607 r#" 635 r#"
636//- minicore: default
608mod test { 637mod test {
609 struct Example { _inner: () } 638 struct Example { _inner: () }
610 639
@@ -623,14 +652,4 @@ mod test {
623"#, 652"#,
624 ); 653 );
625 } 654 }
626
627 fn check_pass(before: &str, after: &str) {
628 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
629 check_assist(generate_default_from_new, before, after);
630 }
631
632 fn check_not_applicable(before: &str) {
633 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
634 check_assist_not_applicable(generate_default_from_new, before);
635 }
636} 655}
diff --git a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
index ce6998d82..8727be07d 100644
--- a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
+++ b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
@@ -110,14 +110,19 @@ mod tests {
110 fn test_generate_from_impl_for_enum() { 110 fn test_generate_from_impl_for_enum() {
111 check_assist( 111 check_assist(
112 generate_from_impl_for_enum, 112 generate_from_impl_for_enum,
113 "enum A { $0One(u32) }", 113 r#"
114 r#"enum A { One(u32) } 114//- minicore: from
115enum A { $0One(u32) }
116"#,
117 r#"
118enum A { One(u32) }
115 119
116impl From<u32> for A { 120impl From<u32> for A {
117 fn from(v: u32) -> Self { 121 fn from(v: u32) -> Self {
118 Self::One(v) 122 Self::One(v)
119 } 123 }
120}"#, 124}
125"#,
121 ); 126 );
122 } 127 }
123 128
@@ -125,53 +130,71 @@ impl From<u32> for A {
125 fn test_generate_from_impl_for_enum_complicated_path() { 130 fn test_generate_from_impl_for_enum_complicated_path() {
126 check_assist( 131 check_assist(
127 generate_from_impl_for_enum, 132 generate_from_impl_for_enum,
128 r#"enum A { $0One(foo::bar::baz::Boo) }"#, 133 r#"
129 r#"enum A { One(foo::bar::baz::Boo) } 134//- minicore: from
135enum A { $0One(foo::bar::baz::Boo) }
136"#,
137 r#"
138enum A { One(foo::bar::baz::Boo) }
130 139
131impl From<foo::bar::baz::Boo> for A { 140impl From<foo::bar::baz::Boo> for A {
132 fn from(v: foo::bar::baz::Boo) -> Self { 141 fn from(v: foo::bar::baz::Boo) -> Self {
133 Self::One(v) 142 Self::One(v)
134 } 143 }
135}"#, 144}
145"#,
136 ); 146 );
137 } 147 }
138 148
139 fn check_not_applicable(ra_fixture: &str) {
140 let fixture =
141 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
142 check_assist_not_applicable(generate_from_impl_for_enum, &fixture)
143 }
144
145 #[test] 149 #[test]
146 fn test_add_from_impl_no_element() { 150 fn test_add_from_impl_no_element() {
147 check_not_applicable("enum A { $0One }"); 151 check_assist_not_applicable(
152 generate_from_impl_for_enum,
153 r#"
154//- minicore: from
155enum A { $0One }
156"#,
157 );
148 } 158 }
149 159
150 #[test] 160 #[test]
151 fn test_add_from_impl_more_than_one_element_in_tuple() { 161 fn test_add_from_impl_more_than_one_element_in_tuple() {
152 check_not_applicable("enum A { $0One(u32, String) }"); 162 check_assist_not_applicable(
163 generate_from_impl_for_enum,
164 r#"
165//- minicore: from
166enum A { $0One(u32, String) }
167"#,
168 );
153 } 169 }
154 170
155 #[test] 171 #[test]
156 fn test_add_from_impl_struct_variant() { 172 fn test_add_from_impl_struct_variant() {
157 check_assist( 173 check_assist(
158 generate_from_impl_for_enum, 174 generate_from_impl_for_enum,
159 "enum A { $0One { x: u32 } }", 175 r#"
160 r#"enum A { One { x: u32 } } 176//- minicore: from
177enum A { $0One { x: u32 } }
178"#,
179 r#"
180enum A { One { x: u32 } }
161 181
162impl From<u32> for A { 182impl From<u32> for A {
163 fn from(x: u32) -> Self { 183 fn from(x: u32) -> Self {
164 Self::One { x } 184 Self::One { x }
165 } 185 }
166}"#, 186}
187"#,
167 ); 188 );
168 } 189 }
169 190
170 #[test] 191 #[test]
171 fn test_add_from_impl_already_exists() { 192 fn test_add_from_impl_already_exists() {
172 cov_mark::check!(test_add_from_impl_already_exists); 193 cov_mark::check!(test_add_from_impl_already_exists);
173 check_not_applicable( 194 check_assist_not_applicable(
195 generate_from_impl_for_enum,
174 r#" 196 r#"
197//- minicore: from
175enum A { $0One(u32), } 198enum A { $0One(u32), }
176 199
177impl From<u32> for A { 200impl From<u32> for A {
@@ -187,7 +210,9 @@ impl From<u32> for A {
187 fn test_add_from_impl_different_variant_impl_exists() { 210 fn test_add_from_impl_different_variant_impl_exists() {
188 check_assist( 211 check_assist(
189 generate_from_impl_for_enum, 212 generate_from_impl_for_enum,
190 r#"enum A { $0One(u32), Two(String), } 213 r#"
214//- minicore: from
215enum A { $0One(u32), Two(String), }
191 216
192impl From<String> for A { 217impl From<String> for A {
193 fn from(v: String) -> Self { 218 fn from(v: String) -> Self {
@@ -197,8 +222,10 @@ impl From<String> for A {
197 222
198pub trait From<T> { 223pub trait From<T> {
199 fn from(T) -> Self; 224 fn from(T) -> Self;
200}"#, 225}
201 r#"enum A { One(u32), Two(String), } 226"#,
227 r#"
228enum A { One(u32), Two(String), }
202 229
203impl From<u32> for A { 230impl From<u32> for A {
204 fn from(v: u32) -> Self { 231 fn from(v: u32) -> Self {
@@ -214,7 +241,8 @@ impl From<String> for A {
214 241
215pub trait From<T> { 242pub trait From<T> {
216 fn from(T) -> Self; 243 fn from(T) -> Self;
217}"#, 244}
245"#,
218 ); 246 );
219 } 247 }
220 248
@@ -222,14 +250,19 @@ pub trait From<T> {
222 fn test_add_from_impl_static_str() { 250 fn test_add_from_impl_static_str() {
223 check_assist( 251 check_assist(
224 generate_from_impl_for_enum, 252 generate_from_impl_for_enum,
225 "enum A { $0One(&'static str) }", 253 r#"
226 r#"enum A { One(&'static str) } 254//- minicore: from
255enum A { $0One(&'static str) }
256"#,
257 r#"
258enum A { One(&'static str) }
227 259
228impl From<&'static str> for A { 260impl From<&'static str> for A {
229 fn from(v: &'static str) -> Self { 261 fn from(v: &'static str) -> Self {
230 Self::One(v) 262 Self::One(v)
231 } 263 }
232}"#, 264}
265"#,
233 ); 266 );
234 } 267 }
235 268
@@ -237,14 +270,19 @@ impl From<&'static str> for A {
237 fn test_add_from_impl_generic_enum() { 270 fn test_add_from_impl_generic_enum() {
238 check_assist( 271 check_assist(
239 generate_from_impl_for_enum, 272 generate_from_impl_for_enum,
240 "enum Generic<T, U: Clone> { $0One(T), Two(U) }", 273 r#"
241 r#"enum Generic<T, U: Clone> { One(T), Two(U) } 274//- minicore: from
275enum Generic<T, U: Clone> { $0One(T), Two(U) }
276"#,
277 r#"
278enum Generic<T, U: Clone> { One(T), Two(U) }
242 279
243impl<T, U: Clone> From<T> for Generic<T, U> { 280impl<T, U: Clone> From<T> for Generic<T, U> {
244 fn from(v: T) -> Self { 281 fn from(v: T) -> Self {
245 Self::One(v) 282 Self::One(v)
246 } 283 }
247}"#, 284}
285"#,
248 ); 286 );
249 } 287 }
250 288
@@ -252,14 +290,19 @@ impl<T, U: Clone> From<T> for Generic<T, U> {
252 fn test_add_from_impl_with_lifetime() { 290 fn test_add_from_impl_with_lifetime() {
253 check_assist( 291 check_assist(
254 generate_from_impl_for_enum, 292 generate_from_impl_for_enum,
255 "enum Generic<'a> { $0One(&'a i32) }", 293 r#"
256 r#"enum Generic<'a> { One(&'a i32) } 294//- minicore: from
295enum Generic<'a> { $0One(&'a i32) }
296"#,
297 r#"
298enum Generic<'a> { One(&'a i32) }
257 299
258impl<'a> From<&'a i32> for Generic<'a> { 300impl<'a> From<&'a i32> for Generic<'a> {
259 fn from(v: &'a i32) -> Self { 301 fn from(v: &'a i32) -> Self {
260 Self::One(v) 302 Self::One(v)
261 } 303 }
262}"#, 304}
305"#,
263 ); 306 );
264 } 307 }
265} 308}
diff --git a/crates/ide_assists/src/handlers/inline_local_variable.rs b/crates/ide_assists/src/handlers/inline_local_variable.rs
index 2441dbb8b..945d28650 100644
--- a/crates/ide_assists/src/handlers/inline_local_variable.rs
+++ b/crates/ide_assists/src/handlers/inline_local_variable.rs
@@ -65,32 +65,35 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
65 Some(u) => u, 65 Some(u) => u,
66 None => return Some(false), 66 None => return Some(false),
67 }; 67 };
68 68 Some(
69 Some(!matches!( 69 !(matches!(
70 (&initializer_expr, usage_parent), 70 initializer_expr,
71 (ast::Expr::CallExpr(_), _) 71 ast::Expr::CallExpr(_)
72 | (ast::Expr::IndexExpr(_), _) 72 | ast::Expr::IndexExpr(_)
73 | (ast::Expr::MethodCallExpr(_), _) 73 | ast::Expr::MethodCallExpr(_)
74 | (ast::Expr::FieldExpr(_), _) 74 | ast::Expr::FieldExpr(_)
75 | (ast::Expr::TryExpr(_), _) 75 | ast::Expr::TryExpr(_)
76 | (ast::Expr::RefExpr(_), _) 76 | ast::Expr::RefExpr(_)
77 | (ast::Expr::Literal(_), _) 77 | ast::Expr::Literal(_)
78 | (ast::Expr::TupleExpr(_), _) 78 | ast::Expr::TupleExpr(_)
79 | (ast::Expr::ArrayExpr(_), _) 79 | ast::Expr::ArrayExpr(_)
80 | (ast::Expr::ParenExpr(_), _) 80 | ast::Expr::ParenExpr(_)
81 | (ast::Expr::PathExpr(_), _) 81 | ast::Expr::PathExpr(_)
82 | (ast::Expr::BlockExpr(_), _) 82 | ast::Expr::BlockExpr(_)
83 | (ast::Expr::EffectExpr(_), _) 83 | ast::Expr::EffectExpr(_),
84 | (_, ast::Expr::CallExpr(_)) 84 ) || matches!(
85 | (_, ast::Expr::TupleExpr(_)) 85 usage_parent,
86 | (_, ast::Expr::ArrayExpr(_)) 86 ast::Expr::CallExpr(_)
87 | (_, ast::Expr::ParenExpr(_)) 87 | ast::Expr::TupleExpr(_)
88 | (_, ast::Expr::ForExpr(_)) 88 | ast::Expr::ArrayExpr(_)
89 | (_, ast::Expr::WhileExpr(_)) 89 | ast::Expr::ParenExpr(_)
90 | (_, ast::Expr::BreakExpr(_)) 90 | ast::Expr::ForExpr(_)
91 | (_, ast::Expr::ReturnExpr(_)) 91 | ast::Expr::WhileExpr(_)
92 | (_, ast::Expr::MatchExpr(_)) 92 | ast::Expr::BreakExpr(_)
93 )) 93 | ast::Expr::ReturnExpr(_)
94 | ast::Expr::MatchExpr(_)
95 )),
96 )
94 }) 97 })
95 .collect::<Option<_>>() 98 .collect::<Option<_>>()
96 .map(|b| (file_id, b)) 99 .map(|b| (file_id, b))
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 60cecd94c..4e96ff1ec 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -35,6 +35,7 @@ pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
35 RootDatabase::with_single_file(text) 35 RootDatabase::with_single_file(text)
36} 36}
37 37
38#[track_caller]
38pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) { 39pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
39 let ra_fixture_after = trim_indent(ra_fixture_after); 40 let ra_fixture_after = trim_indent(ra_fixture_after);
40 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None); 41 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None);
@@ -179,9 +180,10 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
179 "unresolved assist should not contain source changes" 180 "unresolved assist should not contain source changes"
180 ), 181 ),
181 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), 182 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
182 (None, ExpectedResult::After(_)) 183 (
183 | (None, ExpectedResult::Target(_)) 184 None,
184 | (None, ExpectedResult::Unresolved) => { 185 ExpectedResult::After(_) | ExpectedResult::Target(_) | ExpectedResult::Unresolved,
186 ) => {
185 panic!("code action is not applicable") 187 panic!("code action is not applicable")
186 } 188 }
187 (None, ExpectedResult::NotApplicable) => (), 189 (None, ExpectedResult::NotApplicable) => (),