aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src')
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs114
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs3
-rw-r--r--crates/ide_assists/src/handlers/convert_into_to_from.rs50
-rw-r--r--crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs135
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs747
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs29
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs45
-rw-r--r--crates/ide_assists/src/handlers/fix_visibility.rs34
-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_deref.rs27
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs105
-rw-r--r--crates/ide_assists/src/handlers/generate_function.rs49
-rw-r--r--crates/ide_assists/src/handlers/inline_local_variable.rs55
-rw-r--r--crates/ide_assists/src/handlers/move_module_to_file.rs65
-rw-r--r--crates/ide_assists/src/handlers/qualify_path.rs1201
-rw-r--r--crates/ide_assists/src/handlers/remove_dbg.rs4
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs173
-rw-r--r--crates/ide_assists/src/handlers/replace_if_let_with_match.rs66
-rw-r--r--crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs5
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs13
-rw-r--r--crates/ide_assists/src/handlers/replace_unwrap_with_match.rs60
-rw-r--r--crates/ide_assists/src/handlers/unmerge_use.rs16
-rw-r--r--crates/ide_assists/src/lib.rs164
-rw-r--r--crates/ide_assists/src/path_transform.rs160
-rw-r--r--crates/ide_assists/src/tests.rs35
-rw-r--r--crates/ide_assists/src/tests/generated.rs27
-rw-r--r--crates/ide_assists/src/utils.rs6
28 files changed, 1679 insertions, 1833 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/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index d4748ef3a..accc345fc 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -103,8 +103,9 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
103 let scope = match scope.clone() { 103 let scope = match scope.clone() {
104 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)), 104 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
105 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)), 105 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
106 ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
106 }; 107 };
107 insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use); 108 insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
108 }, 109 },
109 ); 110 );
110 } 111 }
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..2d8b936cd 100644
--- a/crates/ide_assists/src/handlers/convert_into_to_from.rs
+++ b/crates/ide_assists/src/handlers/convert_into_to_from.rs
@@ -6,15 +6,14 @@ 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.
12// 14//
13// ``` 15// ```
14// # //- /lib.rs crate:core 16// # //- minicore: from
15// # pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
16// # //- /lib.rs crate:main deps:core
17// # use core::convert::Into;
18// impl $0Into<Thing> for usize { 17// impl $0Into<Thing> for usize {
19// fn into(self) -> Thing { 18// fn into(self) -> Thing {
20// Thing { 19// Thing {
@@ -26,7 +25,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
26// ``` 25// ```
27// -> 26// ->
28// ``` 27// ```
29// # use core::convert::Into;
30// impl From<usize> for Thing { 28// impl From<usize> for Thing {
31// fn from(val: usize) -> Self { 29// fn from(val: usize) -> Self {
32// Thing { 30// Thing {
@@ -114,12 +112,14 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext) -> Op
114mod tests { 112mod tests {
115 use super::*; 113 use super::*;
116 114
117 use crate::tests::check_assist; 115 use crate::tests::{check_assist, check_assist_not_applicable};
118 116
119 #[test] 117 #[test]
120 fn convert_into_to_from_converts_a_struct() { 118 fn convert_into_to_from_converts_a_struct() {
121 check_convert_into_to_from( 119 check_assist(
120 convert_into_to_from,
122 r#" 121 r#"
122//- minicore: from
123struct Thing { 123struct Thing {
124 a: String, 124 a: String,
125 b: usize 125 b: usize
@@ -154,8 +154,10 @@ impl From<usize> for Thing {
154 154
155 #[test] 155 #[test]
156 fn convert_into_to_from_converts_enums() { 156 fn convert_into_to_from_converts_enums() {
157 check_convert_into_to_from( 157 check_assist(
158 convert_into_to_from,
158 r#" 159 r#"
160//- minicore: from
159enum Thing { 161enum Thing {
160 Foo(String), 162 Foo(String),
161 Bar(String) 163 Bar(String)
@@ -190,8 +192,10 @@ impl From<Thing> for String {
190 192
191 #[test] 193 #[test]
192 fn convert_into_to_from_on_enum_with_lifetimes() { 194 fn convert_into_to_from_on_enum_with_lifetimes() {
193 check_convert_into_to_from( 195 check_assist(
196 convert_into_to_from,
194 r#" 197 r#"
198//- minicore: from
195enum Thing<'a> { 199enum Thing<'a> {
196 Foo(&'a str), 200 Foo(&'a str),
197 Bar(&'a str) 201 Bar(&'a str)
@@ -226,8 +230,10 @@ impl<'a> From<Thing<'a>> for &'a str {
226 230
227 #[test] 231 #[test]
228 fn convert_into_to_from_works_on_references() { 232 fn convert_into_to_from_works_on_references() {
229 check_convert_into_to_from( 233 check_assist(
234 convert_into_to_from,
230 r#" 235 r#"
236//- minicore: from
231struct Thing(String); 237struct Thing(String);
232 238
233impl $0core::convert::Into<String> for &Thing { 239impl $0core::convert::Into<String> for &Thing {
@@ -250,8 +256,10 @@ impl From<&Thing> for String {
250 256
251 #[test] 257 #[test]
252 fn convert_into_to_from_works_on_qualified_structs() { 258 fn convert_into_to_from_works_on_qualified_structs() {
253 check_convert_into_to_from( 259 check_assist(
260 convert_into_to_from,
254 r#" 261 r#"
262//- minicore: from
255mod things { 263mod things {
256 pub struct Thing(String); 264 pub struct Thing(String);
257 pub struct BetterThing(String); 265 pub struct BetterThing(String);
@@ -280,8 +288,10 @@ impl From<&things::Thing> for things::BetterThing {
280 288
281 #[test] 289 #[test]
282 fn convert_into_to_from_works_on_qualified_enums() { 290 fn convert_into_to_from_works_on_qualified_enums() {
283 check_convert_into_to_from( 291 check_assist(
292 convert_into_to_from,
284 r#" 293 r#"
294//- minicore: from
285mod things { 295mod things {
286 pub enum Thing { 296 pub enum Thing {
287 A(String) 297 A(String)
@@ -323,10 +333,12 @@ impl From<&things::Thing> for things::BetterThing {
323 #[test] 333 #[test]
324 fn convert_into_to_from_not_applicable_on_any_trait_named_into() { 334 fn convert_into_to_from_not_applicable_on_any_trait_named_into() {
325 check_assist_not_applicable( 335 check_assist_not_applicable(
336 convert_into_to_from,
326 r#" 337 r#"
327pub trait Into<T> {{ 338//- minicore: from
339pub trait Into<T> {
328 pub fn into(self) -> T; 340 pub fn into(self) -> T;
329}} 341}
330 342
331struct Thing { 343struct Thing {
332 a: String, 344 a: String,
@@ -342,14 +354,4 @@ impl $0Into<Thing> for String {
342"#, 354"#,
343 ); 355 );
344 } 356 }
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} 357}
diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
index 4e75a7b14..70754adf9 100644
--- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -11,14 +11,10 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
11// Converts an Iterator::for_each function into a for loop. 11// Converts an Iterator::for_each function into a for loop.
12// 12//
13// ``` 13// ```
14// # //- /lib.rs crate:core 14// # //- minicore: iterators
15// # pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 15// # use core::iter;
16// # pub struct SomeIter;
17// # impl self::iter::traits::iterator::Iterator for SomeIter {}
18// # //- /lib.rs crate:main deps:core
19// # use core::SomeIter;
20// fn main() { 16// fn main() {
21// let iter = SomeIter; 17// let iter = iter::repeat((9, 2));
22// iter.for_each$0(|(x, y)| { 18// iter.for_each$0(|(x, y)| {
23// println!("x: {}, y: {}", x, y); 19// println!("x: {}, y: {}", x, y);
24// }); 20// });
@@ -26,9 +22,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
26// ``` 22// ```
27// -> 23// ->
28// ``` 24// ```
29// # use core::SomeIter; 25// # use core::iter;
30// fn main() { 26// fn main() {
31// let iter = SomeIter; 27// let iter = iter::repeat((9, 2));
32// for (x, y) in iter { 28// for (x, y) in iter {
33// println!("x: {}, y: {}", x, y); 29// println!("x: {}, y: {}", x, y);
34// } 30// }
@@ -77,9 +73,11 @@ fn validate_method_call_expr(
77 expr: ast::MethodCallExpr, 73 expr: ast::MethodCallExpr,
78) -> Option<(ast::Expr, ast::Expr)> { 74) -> Option<(ast::Expr, ast::Expr)> {
79 let name_ref = expr.name_ref()?; 75 let name_ref = expr.name_ref()?;
80 if name_ref.syntax().text_range().intersect(ctx.frange.range).is_none() 76 if name_ref.syntax().text_range().intersect(ctx.frange.range).is_none() {
81 || name_ref.text() != "for_each" 77 cov_mark::hit!(test_for_each_not_applicable_invalid_cursor_pos);
82 { 78 return None;
79 }
80 if name_ref.text() != "for_each" {
83 return None; 81 return None;
84 } 82 }
85 83
@@ -98,59 +96,27 @@ fn validate_method_call_expr(
98 96
99#[cfg(test)] 97#[cfg(test)]
100mod tests { 98mod tests {
101 use crate::tests::{self, check_assist}; 99 use crate::tests::{check_assist, check_assist_not_applicable};
102 100
103 use super::*; 101 use super::*;
104 102
105 const EMPTY_ITER_FIXTURE: &'static str = r"
106//- /lib.rs deps:core crate:empty_iter
107pub struct EmptyIter;
108impl Iterator for EmptyIter {
109 type Item = usize;
110 fn next(&mut self) -> Option<Self::Item> { None }
111}
112pub struct Empty;
113impl Empty {
114 pub fn iter(&self) -> EmptyIter { EmptyIter }
115}
116";
117
118 fn check_assist_with_fixtures(before: &str, after: &str) {
119 let before = &format!(
120 "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
121 before,
122 EMPTY_ITER_FIXTURE,
123 FamousDefs::FIXTURE,
124 );
125 check_assist(convert_iter_for_each_to_for, before, after);
126 }
127
128 fn check_assist_not_applicable(before: &str) {
129 let before = &format!(
130 "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
131 before,
132 EMPTY_ITER_FIXTURE,
133 FamousDefs::FIXTURE,
134 );
135 tests::check_assist_not_applicable(convert_iter_for_each_to_for, before);
136 }
137
138 #[test] 103 #[test]
139 fn test_for_each_in_method_stmt() { 104 fn test_for_each_in_method_stmt() {
140 check_assist_with_fixtures( 105 check_assist(
106 convert_iter_for_each_to_for,
141 r#" 107 r#"
142use empty_iter::*; 108//- minicore: iterators
143fn main() { 109fn main() {
144 let x = Empty; 110 let it = core::iter::repeat(92);
145 x.iter().$0for_each(|(x, y)| { 111 it.$0for_each(|(x, y)| {
146 println!("x: {}, y: {}", x, y); 112 println!("x: {}, y: {}", x, y);
147 }); 113 });
148}"#, 114}
115"#,
149 r#" 116 r#"
150use empty_iter::*;
151fn main() { 117fn main() {
152 let x = Empty; 118 let it = core::iter::repeat(92);
153 for (x, y) in x.iter() { 119 for (x, y) in it {
154 println!("x: {}, y: {}", x, y); 120 println!("x: {}, y: {}", x, y);
155 } 121 }
156} 122}
@@ -160,43 +126,21 @@ fn main() {
160 126
161 #[test] 127 #[test]
162 fn test_for_each_in_method() { 128 fn test_for_each_in_method() {
163 check_assist_with_fixtures( 129 check_assist(
130 convert_iter_for_each_to_for,
164 r#" 131 r#"
165use empty_iter::*; 132//- minicore: iterators
166fn main() { 133fn main() {
167 let x = Empty; 134 let it = core::iter::repeat(92);
168 x.iter().$0for_each(|(x, y)| { 135 it.$0for_each(|(x, y)| {
169 println!("x: {}, y: {}", x, y); 136 println!("x: {}, y: {}", x, y);
170 }) 137 })
171}"#,
172 r#"
173use empty_iter::*;
174fn main() {
175 let x = Empty;
176 for (x, y) in x.iter() {
177 println!("x: {}, y: {}", x, y);
178 }
179} 138}
180"#, 139"#,
181 )
182 }
183
184 #[test]
185 fn test_for_each_in_iter_stmt() {
186 check_assist_with_fixtures(
187 r#"
188use empty_iter::*;
189fn main() {
190 let x = Empty.iter();
191 x.$0for_each(|(x, y)| {
192 println!("x: {}, y: {}", x, y);
193 });
194}"#,
195 r#" 140 r#"
196use empty_iter::*;
197fn main() { 141fn main() {
198 let x = Empty.iter(); 142 let it = core::iter::repeat(92);
199 for (x, y) in x { 143 for (x, y) in it {
200 println!("x: {}, y: {}", x, y); 144 println!("x: {}, y: {}", x, y);
201 } 145 }
202} 146}
@@ -206,18 +150,19 @@ fn main() {
206 150
207 #[test] 151 #[test]
208 fn test_for_each_without_braces_stmt() { 152 fn test_for_each_without_braces_stmt() {
209 check_assist_with_fixtures( 153 check_assist(
154 convert_iter_for_each_to_for,
210 r#" 155 r#"
211use empty_iter::*; 156//- minicore: iterators
212fn main() { 157fn main() {
213 let x = Empty; 158 let it = core::iter::repeat(92);
214 x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y)); 159 it.$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
215}"#, 160}
161"#,
216 r#" 162 r#"
217use empty_iter::*;
218fn main() { 163fn main() {
219 let x = Empty; 164 let it = core::iter::repeat(92);
220 for (x, y) in x.iter() { 165 for (x, y) in it {
221 println!("x: {}, y: {}", x, y) 166 println!("x: {}, y: {}", x, y)
222 } 167 }
223} 168}
@@ -228,7 +173,9 @@ fn main() {
228 #[test] 173 #[test]
229 fn test_for_each_not_applicable() { 174 fn test_for_each_not_applicable() {
230 check_assist_not_applicable( 175 check_assist_not_applicable(
176 convert_iter_for_each_to_for,
231 r#" 177 r#"
178//- minicore: iterators
232fn main() { 179fn main() {
233 ().$0for_each(|x| println!("{}", x)); 180 ().$0for_each(|x| println!("{}", x));
234}"#, 181}"#,
@@ -237,11 +184,13 @@ fn main() {
237 184
238 #[test] 185 #[test]
239 fn test_for_each_not_applicable_invalid_cursor_pos() { 186 fn test_for_each_not_applicable_invalid_cursor_pos() {
187 cov_mark::check!(test_for_each_not_applicable_invalid_cursor_pos);
240 check_assist_not_applicable( 188 check_assist_not_applicable(
189 convert_iter_for_each_to_for,
241 r#" 190 r#"
242use empty_iter::*; 191//- minicore: iterators
243fn main() { 192fn main() {
244 Empty.iter().for_each(|(x, y)| $0println!("x: {}, y: {}", x, y)); 193 core::iter::repeat(92).for_each(|(x, y)| $0println!("x: {}, y: {}", x, y));
245}"#, 194}"#,
246 ) 195 )
247 } 196 }
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index f2be091f4..870d4f665 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -109,10 +109,15 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
109 109
110 let new_indent = IndentLevel::from_node(&insert_after); 110 let new_indent = IndentLevel::from_node(&insert_after);
111 let old_indent = fun.body.indent_level(); 111 let old_indent = fun.body.indent_level();
112 let body_contains_await = body_contains_await(&fun.body);
112 113
113 builder.replace(target_range, format_replacement(ctx, &fun, old_indent)); 114 builder.replace(
115 target_range,
116 format_replacement(ctx, &fun, old_indent, body_contains_await),
117 );
114 118
115 let fn_def = format_function(ctx, module, &fun, old_indent, new_indent); 119 let fn_def =
120 format_function(ctx, module, &fun, old_indent, new_indent, body_contains_await);
116 let insert_offset = insert_after.text_range().end(); 121 let insert_offset = insert_after.text_range().end();
117 match ctx.config.snippet_cap { 122 match ctx.config.snippet_cap {
118 Some(cap) => builder.insert_snippet(cap, insert_offset, fn_def), 123 Some(cap) => builder.insert_snippet(cap, insert_offset, fn_def),
@@ -954,7 +959,12 @@ fn scope_for_fn_insertion_node(node: &SyntaxNode, anchor: Anchor) -> Option<Synt
954 last_ancestor 959 last_ancestor
955} 960}
956 961
957fn format_replacement(ctx: &AssistContext, fun: &Function, indent: IndentLevel) -> String { 962fn format_replacement(
963 ctx: &AssistContext,
964 fun: &Function,
965 indent: IndentLevel,
966 body_contains_await: bool,
967) -> String {
958 let ret_ty = fun.return_type(ctx); 968 let ret_ty = fun.return_type(ctx);
959 969
960 let args = fun.params.iter().map(|param| param.to_arg(ctx)); 970 let args = fun.params.iter().map(|param| param.to_arg(ctx));
@@ -994,6 +1004,9 @@ fn format_replacement(ctx: &AssistContext, fun: &Function, indent: IndentLevel)
994 } 1004 }
995 } 1005 }
996 format_to!(buf, "{}", expr); 1006 format_to!(buf, "{}", expr);
1007 if body_contains_await {
1008 buf.push_str(".await");
1009 }
997 if fun.ret_ty.is_unit() 1010 if fun.ret_ty.is_unit()
998 && (!fun.vars_defined_in_body_and_outlive.is_empty() || !expr.is_block_like()) 1011 && (!fun.vars_defined_in_body_and_outlive.is_empty() || !expr.is_block_like())
999 { 1012 {
@@ -1122,12 +1135,13 @@ fn format_function(
1122 fun: &Function, 1135 fun: &Function,
1123 old_indent: IndentLevel, 1136 old_indent: IndentLevel,
1124 new_indent: IndentLevel, 1137 new_indent: IndentLevel,
1138 body_contains_await: bool,
1125) -> String { 1139) -> String {
1126 let mut fn_def = String::new(); 1140 let mut fn_def = String::new();
1127 let params = make_param_list(ctx, module, fun); 1141 let params = make_param_list(ctx, module, fun);
1128 let ret_ty = make_ret_ty(ctx, module, fun); 1142 let ret_ty = make_ret_ty(ctx, module, fun);
1129 let body = make_body(ctx, old_indent, new_indent, fun); 1143 let body = make_body(ctx, old_indent, new_indent, fun);
1130 let async_kw = if body_contains_await(&fun.body) { "async " } else { "" }; 1144 let async_kw = if body_contains_await { "async " } else { "" };
1131 match ctx.config.snippet_cap { 1145 match ctx.config.snippet_cap {
1132 Some(_) => format_to!(fn_def, "\n\n{}{}fn $0{}{}", new_indent, async_kw, fun.name, params), 1146 Some(_) => format_to!(fn_def, "\n\n{}{}fn $0{}{}", new_indent, async_kw, fun.name, params),
1133 None => format_to!(fn_def, "\n\n{}{}fn {}{}", new_indent, async_kw, fun.name, params), 1147 None => format_to!(fn_def, "\n\n{}{}fn {}{}", new_indent, async_kw, fun.name, params),
@@ -1384,7 +1398,7 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode)
1384 for (param, usages) in usages_for_param { 1398 for (param, usages) in usages_for_param {
1385 for usage in usages { 1399 for usage in usages {
1386 match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { 1400 match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
1387 Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { 1401 Some(ast::Expr::MethodCallExpr(_) | ast::Expr::FieldExpr(_)) => {
1388 // do nothing 1402 // do nothing
1389 } 1403 }
1390 Some(ast::Expr::RefExpr(node)) 1404 Some(ast::Expr::RefExpr(node))
@@ -1501,7 +1515,8 @@ mod tests {
1501 r#" 1515 r#"
1502fn foo() { 1516fn foo() {
1503 foo($01 + 1$0); 1517 foo($01 + 1$0);
1504}"#, 1518}
1519"#,
1505 r#" 1520 r#"
1506fn foo() { 1521fn foo() {
1507 foo(fun_name()); 1522 foo(fun_name());
@@ -1509,7 +1524,8 @@ fn foo() {
1509 1524
1510fn $0fun_name() -> i32 { 1525fn $0fun_name() -> i32 {
1511 1 + 1 1526 1 + 1
1512}"#, 1527}
1528"#,
1513 ); 1529 );
1514 } 1530 }
1515 1531
@@ -1522,7 +1538,8 @@ mod bar {
1522 fn foo() { 1538 fn foo() {
1523 foo($01 + 1$0); 1539 foo($01 + 1$0);
1524 } 1540 }
1525}"#, 1541}
1542"#,
1526 r#" 1543 r#"
1527mod bar { 1544mod bar {
1528 fn foo() { 1545 fn foo() {
@@ -1532,7 +1549,8 @@ mod bar {
1532 fn $0fun_name() -> i32 { 1549 fn $0fun_name() -> i32 {
1533 1 + 1 1550 1 + 1
1534 } 1551 }
1535}"#, 1552}
1553"#,
1536 ); 1554 );
1537 } 1555 }
1538 1556
@@ -1543,7 +1561,8 @@ mod bar {
1543 r#" 1561 r#"
1544fn foo() { 1562fn foo() {
1545 $0{ 1 + 1 }$0; 1563 $0{ 1 + 1 }$0;
1546}"#, 1564}
1565"#,
1547 r#" 1566 r#"
1548fn foo() { 1567fn foo() {
1549 fun_name(); 1568 fun_name();
@@ -1551,7 +1570,8 @@ fn foo() {
1551 1570
1552fn $0fun_name() -> i32 { 1571fn $0fun_name() -> i32 {
1553 1 + 1 1572 1 + 1
1554}"#, 1573}
1574"#,
1555 ); 1575 );
1556 } 1576 }
1557 1577
@@ -1564,7 +1584,8 @@ fn foo() -> i32 {
1564 let k = 1; 1584 let k = 1;
1565 $0let m = 1; 1585 $0let m = 1;
1566 m + 1$0 1586 m + 1$0
1567}"#, 1587}
1588"#,
1568 r#" 1589 r#"
1569fn foo() -> i32 { 1590fn foo() -> i32 {
1570 let k = 1; 1591 let k = 1;
@@ -1574,7 +1595,8 @@ fn foo() -> i32 {
1574fn $0fun_name() -> i32 { 1595fn $0fun_name() -> i32 {
1575 let m = 1; 1596 let m = 1;
1576 m + 1 1597 m + 1
1577}"#, 1598}
1599"#,
1578 ); 1600 );
1579 } 1601 }
1580 1602
@@ -1588,7 +1610,8 @@ fn foo() {
1588 $0let m = 1; 1610 $0let m = 1;
1589 let n = m + 1;$0 1611 let n = m + 1;$0
1590 let g = 5; 1612 let g = 5;
1591}"#, 1613}
1614"#,
1592 r#" 1615 r#"
1593fn foo() { 1616fn foo() {
1594 let k = 3; 1617 let k = 3;
@@ -1599,7 +1622,8 @@ fn foo() {
1599fn $0fun_name() { 1622fn $0fun_name() {
1600 let m = 1; 1623 let m = 1;
1601 let n = m + 1; 1624 let n = m + 1;
1602}"#, 1625}
1626"#,
1603 ); 1627 );
1604 } 1628 }
1605 1629
@@ -1610,7 +1634,8 @@ fn $0fun_name() {
1610 r#" 1634 r#"
1611fn foo() { 1635fn foo() {
1612 $0if true { }$0 1636 $0if true { }$0
1613}"#, 1637}
1638"#,
1614 r#" 1639 r#"
1615fn foo() { 1640fn foo() {
1616 fun_name(); 1641 fun_name();
@@ -1618,7 +1643,8 @@ fn foo() {
1618 1643
1619fn $0fun_name() { 1644fn $0fun_name() {
1620 if true { } 1645 if true { }
1621}"#, 1646}
1647"#,
1622 ); 1648 );
1623 } 1649 }
1624 1650
@@ -1629,7 +1655,8 @@ fn $0fun_name() {
1629 r#" 1655 r#"
1630fn foo() -> i32 { 1656fn foo() -> i32 {
1631 $0if true { 1 } else { 2 }$0 1657 $0if true { 1 } else { 2 }$0
1632}"#, 1658}
1659"#,
1633 r#" 1660 r#"
1634fn foo() -> i32 { 1661fn foo() -> i32 {
1635 fun_name() 1662 fun_name()
@@ -1637,7 +1664,8 @@ fn foo() -> i32 {
1637 1664
1638fn $0fun_name() -> i32 { 1665fn $0fun_name() -> i32 {
1639 if true { 1 } else { 2 } 1666 if true { 1 } else { 2 }
1640}"#, 1667}
1668"#,
1641 ); 1669 );
1642 } 1670 }
1643 1671
@@ -1648,7 +1676,8 @@ fn $0fun_name() -> i32 {
1648 r#" 1676 r#"
1649fn foo() -> i32 { 1677fn foo() -> i32 {
1650 $0if let true = false { 1 } else { 2 }$0 1678 $0if let true = false { 1 } else { 2 }$0
1651}"#, 1679}
1680"#,
1652 r#" 1681 r#"
1653fn foo() -> i32 { 1682fn foo() -> i32 {
1654 fun_name() 1683 fun_name()
@@ -1656,7 +1685,8 @@ fn foo() -> i32 {
1656 1685
1657fn $0fun_name() -> i32 { 1686fn $0fun_name() -> i32 {
1658 if let true = false { 1 } else { 2 } 1687 if let true = false { 1 } else { 2 }
1659}"#, 1688}
1689"#,
1660 ); 1690 );
1661 } 1691 }
1662 1692
@@ -1670,7 +1700,8 @@ fn foo() -> i32 {
1670 true => 1, 1700 true => 1,
1671 false => 2, 1701 false => 2,
1672 }$0 1702 }$0
1673}"#, 1703}
1704"#,
1674 r#" 1705 r#"
1675fn foo() -> i32 { 1706fn foo() -> i32 {
1676 fun_name() 1707 fun_name()
@@ -1681,7 +1712,8 @@ fn $0fun_name() -> i32 {
1681 true => 1, 1712 true => 1,
1682 false => 2, 1713 false => 2,
1683 } 1714 }
1684}"#, 1715}
1716"#,
1685 ); 1717 );
1686 } 1718 }
1687 1719
@@ -1692,7 +1724,8 @@ fn $0fun_name() -> i32 {
1692 r#" 1724 r#"
1693fn foo() { 1725fn foo() {
1694 $0while true { }$0 1726 $0while true { }$0
1695}"#, 1727}
1728"#,
1696 r#" 1729 r#"
1697fn foo() { 1730fn foo() {
1698 fun_name(); 1731 fun_name();
@@ -1700,7 +1733,8 @@ fn foo() {
1700 1733
1701fn $0fun_name() { 1734fn $0fun_name() {
1702 while true { } 1735 while true { }
1703}"#, 1736}
1737"#,
1704 ); 1738 );
1705 } 1739 }
1706 1740
@@ -1711,7 +1745,8 @@ fn $0fun_name() {
1711 r#" 1745 r#"
1712fn foo() { 1746fn foo() {
1713 $0for v in &[0, 1] { }$0 1747 $0for v in &[0, 1] { }$0
1714}"#, 1748}
1749"#,
1715 r#" 1750 r#"
1716fn foo() { 1751fn foo() {
1717 fun_name(); 1752 fun_name();
@@ -1719,7 +1754,8 @@ fn foo() {
1719 1754
1720fn $0fun_name() { 1755fn $0fun_name() {
1721 for v in &[0, 1] { } 1756 for v in &[0, 1] { }
1722}"#, 1757}
1758"#,
1723 ); 1759 );
1724 } 1760 }
1725 1761
@@ -1732,7 +1768,8 @@ fn foo() {
1732 $0loop { 1768 $0loop {
1733 let m = 1; 1769 let m = 1;
1734 }$0 1770 }$0
1735}"#, 1771}
1772"#,
1736 r#" 1773 r#"
1737fn foo() { 1774fn foo() {
1738 fun_name() 1775 fun_name()
@@ -1742,7 +1779,8 @@ fn $0fun_name() -> ! {
1742 loop { 1779 loop {
1743 let m = 1; 1780 let m = 1;
1744 } 1781 }
1745}"#, 1782}
1783"#,
1746 ); 1784 );
1747 } 1785 }
1748 1786
@@ -1756,7 +1794,8 @@ fn foo() {
1756 let m = 1; 1794 let m = 1;
1757 break m; 1795 break m;
1758 }$0; 1796 }$0;
1759}"#, 1797}
1798"#,
1760 r#" 1799 r#"
1761fn foo() { 1800fn foo() {
1762 let v = fun_name(); 1801 let v = fun_name();
@@ -1767,7 +1806,8 @@ fn $0fun_name() -> i32 {
1767 let m = 1; 1806 let m = 1;
1768 break m; 1807 break m;
1769 } 1808 }
1770}"#, 1809}
1810"#,
1771 ); 1811 );
1772 } 1812 }
1773 1813
@@ -1781,7 +1821,8 @@ fn foo() {
1781 Some(x) => x, 1821 Some(x) => x,
1782 None => 0, 1822 None => 0,
1783 }$0; 1823 }$0;
1784}"#, 1824}
1825"#,
1785 r#" 1826 r#"
1786fn foo() { 1827fn foo() {
1787 let v: i32 = fun_name(); 1828 let v: i32 = fun_name();
@@ -1792,7 +1833,8 @@ fn $0fun_name() -> i32 {
1792 Some(x) => x, 1833 Some(x) => x,
1793 None => 0, 1834 None => 0,
1794 } 1835 }
1795}"#, 1836}
1837"#,
1796 ); 1838 );
1797 } 1839 }
1798 1840
@@ -1805,7 +1847,8 @@ fn foo() {
1805 let n = 1; 1847 let n = 1;
1806 let mut v = $0n * n;$0 1848 let mut v = $0n * n;$0
1807 v += 1; 1849 v += 1;
1808}"#, 1850}
1851"#,
1809 r#" 1852 r#"
1810fn foo() { 1853fn foo() {
1811 let n = 1; 1854 let n = 1;
@@ -1816,7 +1859,8 @@ fn foo() {
1816fn $0fun_name(n: i32) -> i32 { 1859fn $0fun_name(n: i32) -> i32 {
1817 let mut v = n * n; 1860 let mut v = n * n;
1818 v 1861 v
1819}"#, 1862}
1863"#,
1820 ); 1864 );
1821 } 1865 }
1822 1866
@@ -1832,7 +1876,8 @@ fn foo() {
1832 let mut w = 3;$0 1876 let mut w = 3;$0
1833 v += 1; 1877 v += 1;
1834 w += 1; 1878 w += 1;
1835}"#, 1879}
1880"#,
1836 r#" 1881 r#"
1837fn foo() { 1882fn foo() {
1838 let m = 2; 1883 let m = 2;
@@ -1846,7 +1891,8 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1846 let mut v = m * n; 1891 let mut v = m * n;
1847 let mut w = 3; 1892 let mut w = 3;
1848 (v, w) 1893 (v, w)
1849}"#, 1894}
1895"#,
1850 ); 1896 );
1851 } 1897 }
1852 1898
@@ -1854,12 +1900,13 @@ fn $0fun_name(m: i32, n: i32) -> (i32, i32) {
1854 fn argument_form_expr() { 1900 fn argument_form_expr() {
1855 check_assist( 1901 check_assist(
1856 extract_function, 1902 extract_function,
1857 r" 1903 r#"
1858fn foo() -> u32 { 1904fn foo() -> u32 {
1859 let n = 2; 1905 let n = 2;
1860 $0n+2$0 1906 $0n+2$0
1861}", 1907}
1862 r" 1908"#,
1909 r#"
1863fn foo() -> u32 { 1910fn foo() -> u32 {
1864 let n = 2; 1911 let n = 2;
1865 fun_name(n) 1912 fun_name(n)
@@ -1867,7 +1914,8 @@ fn foo() -> u32 {
1867 1914
1868fn $0fun_name(n: u32) -> u32 { 1915fn $0fun_name(n: u32) -> u32 {
1869 n+2 1916 n+2
1870}", 1917}
1918"#,
1871 ) 1919 )
1872 } 1920 }
1873 1921
@@ -1875,12 +1923,13 @@ fn $0fun_name(n: u32) -> u32 {
1875 fn argument_used_twice_form_expr() { 1923 fn argument_used_twice_form_expr() {
1876 check_assist( 1924 check_assist(
1877 extract_function, 1925 extract_function,
1878 r" 1926 r#"
1879fn foo() -> u32 { 1927fn foo() -> u32 {
1880 let n = 2; 1928 let n = 2;
1881 $0n+n$0 1929 $0n+n$0
1882}", 1930}
1883 r" 1931"#,
1932 r#"
1884fn foo() -> u32 { 1933fn foo() -> u32 {
1885 let n = 2; 1934 let n = 2;
1886 fun_name(n) 1935 fun_name(n)
@@ -1888,7 +1937,8 @@ fn foo() -> u32 {
1888 1937
1889fn $0fun_name(n: u32) -> u32 { 1938fn $0fun_name(n: u32) -> u32 {
1890 n+n 1939 n+n
1891}", 1940}
1941"#,
1892 ) 1942 )
1893 } 1943 }
1894 1944
@@ -1896,13 +1946,14 @@ fn $0fun_name(n: u32) -> u32 {
1896 fn two_arguments_form_expr() { 1946 fn two_arguments_form_expr() {
1897 check_assist( 1947 check_assist(
1898 extract_function, 1948 extract_function,
1899 r" 1949 r#"
1900fn foo() -> u32 { 1950fn foo() -> u32 {
1901 let n = 2; 1951 let n = 2;
1902 let m = 3; 1952 let m = 3;
1903 $0n+n*m$0 1953 $0n+n*m$0
1904}", 1954}
1905 r" 1955"#,
1956 r#"
1906fn foo() -> u32 { 1957fn foo() -> u32 {
1907 let n = 2; 1958 let n = 2;
1908 let m = 3; 1959 let m = 3;
@@ -1911,7 +1962,8 @@ fn foo() -> u32 {
1911 1962
1912fn $0fun_name(n: u32, m: u32) -> u32 { 1963fn $0fun_name(n: u32, m: u32) -> u32 {
1913 n+n*m 1964 n+n*m
1914}", 1965}
1966"#,
1915 ) 1967 )
1916 } 1968 }
1917 1969
@@ -1919,13 +1971,14 @@ fn $0fun_name(n: u32, m: u32) -> u32 {
1919 fn argument_and_locals() { 1971 fn argument_and_locals() {
1920 check_assist( 1972 check_assist(
1921 extract_function, 1973 extract_function,
1922 r" 1974 r#"
1923fn foo() -> u32 { 1975fn foo() -> u32 {
1924 let n = 2; 1976 let n = 2;
1925 $0let m = 1; 1977 $0let m = 1;
1926 n + m$0 1978 n + m$0
1927}", 1979}
1928 r" 1980"#,
1981 r#"
1929fn foo() -> u32 { 1982fn foo() -> u32 {
1930 let n = 2; 1983 let n = 2;
1931 fun_name(n) 1984 fun_name(n)
@@ -1934,7 +1987,8 @@ fn foo() -> u32 {
1934fn $0fun_name(n: u32) -> u32 { 1987fn $0fun_name(n: u32) -> u32 {
1935 let m = 1; 1988 let m = 1;
1936 n + m 1989 n + m
1937}", 1990}
1991"#,
1938 ) 1992 )
1939 } 1993 }
1940 1994
@@ -1948,18 +2002,20 @@ fn $0fun_name(n: u32) -> u32 {
1948 fn part_of_expr_stmt() { 2002 fn part_of_expr_stmt() {
1949 check_assist( 2003 check_assist(
1950 extract_function, 2004 extract_function,
1951 " 2005 r#"
1952fn foo() { 2006fn foo() {
1953 $01$0 + 1; 2007 $01$0 + 1;
1954}", 2008}
1955 " 2009"#,
2010 r#"
1956fn foo() { 2011fn foo() {
1957 fun_name() + 1; 2012 fun_name() + 1;
1958} 2013}
1959 2014
1960fn $0fun_name() -> i32 { 2015fn $0fun_name() -> i32 {
1961 1 2016 1
1962}", 2017}
2018"#,
1963 ); 2019 );
1964 } 2020 }
1965 2021
@@ -1970,7 +2026,8 @@ fn $0fun_name() -> i32 {
1970 r#" 2026 r#"
1971fn foo() { 2027fn foo() {
1972 $0bar(1 + 1)$0 2028 $0bar(1 + 1)$0
1973}"#, 2029}
2030"#,
1974 r#" 2031 r#"
1975fn foo() { 2032fn foo() {
1976 fun_name(); 2033 fun_name();
@@ -1978,7 +2035,8 @@ fn foo() {
1978 2035
1979fn $0fun_name() { 2036fn $0fun_name() {
1980 bar(1 + 1) 2037 bar(1 + 1)
1981}"#, 2038}
2039"#,
1982 ) 2040 )
1983 } 2041 }
1984 2042
@@ -1986,15 +2044,16 @@ fn $0fun_name() {
1986 fn extract_from_nested() { 2044 fn extract_from_nested() {
1987 check_assist( 2045 check_assist(
1988 extract_function, 2046 extract_function,
1989 r" 2047 r#"
1990fn main() { 2048fn main() {
1991 let x = true; 2049 let x = true;
1992 let tuple = match x { 2050 let tuple = match x {
1993 true => ($02 + 2$0, true) 2051 true => ($02 + 2$0, true)
1994 _ => (0, false) 2052 _ => (0, false)
1995 }; 2053 };
1996}", 2054}
1997 r" 2055"#,
2056 r#"
1998fn main() { 2057fn main() {
1999 let x = true; 2058 let x = true;
2000 let tuple = match x { 2059 let tuple = match x {
@@ -2005,7 +2064,8 @@ fn main() {
2005 2064
2006fn $0fun_name() -> i32 { 2065fn $0fun_name() -> i32 {
2007 2 + 2 2066 2 + 2
2008}", 2067}
2068"#,
2009 ); 2069 );
2010 } 2070 }
2011 2071
@@ -2013,18 +2073,20 @@ fn $0fun_name() -> i32 {
2013 fn param_from_closure() { 2073 fn param_from_closure() {
2014 check_assist( 2074 check_assist(
2015 extract_function, 2075 extract_function,
2016 r" 2076 r#"
2017fn main() { 2077fn main() {
2018 let lambda = |x: u32| $0x * 2$0; 2078 let lambda = |x: u32| $0x * 2$0;
2019}", 2079}
2020 r" 2080"#,
2081 r#"
2021fn main() { 2082fn main() {
2022 let lambda = |x: u32| fun_name(x); 2083 let lambda = |x: u32| fun_name(x);
2023} 2084}
2024 2085
2025fn $0fun_name(x: u32) -> u32 { 2086fn $0fun_name(x: u32) -> u32 {
2026 x * 2 2087 x * 2
2027}", 2088}
2089"#,
2028 ); 2090 );
2029 } 2091 }
2030 2092
@@ -2032,18 +2094,20 @@ fn $0fun_name(x: u32) -> u32 {
2032 fn extract_return_stmt() { 2094 fn extract_return_stmt() {
2033 check_assist( 2095 check_assist(
2034 extract_function, 2096 extract_function,
2035 r" 2097 r#"
2036fn foo() -> u32 { 2098fn foo() -> u32 {
2037 $0return 2 + 2$0; 2099 $0return 2 + 2$0;
2038}", 2100}
2039 r" 2101"#,
2102 r#"
2040fn foo() -> u32 { 2103fn foo() -> u32 {
2041 return fun_name(); 2104 return fun_name();
2042} 2105}
2043 2106
2044fn $0fun_name() -> u32 { 2107fn $0fun_name() -> u32 {
2045 2 + 2 2108 2 + 2
2046}", 2109}
2110"#,
2047 ); 2111 );
2048 } 2112 }
2049 2113
@@ -2051,13 +2115,14 @@ fn $0fun_name() -> u32 {
2051 fn does_not_add_extra_whitespace() { 2115 fn does_not_add_extra_whitespace() {
2052 check_assist( 2116 check_assist(
2053 extract_function, 2117 extract_function,
2054 r" 2118 r#"
2055fn foo() -> u32 { 2119fn foo() -> u32 {
2056 2120
2057 2121
2058 $0return 2 + 2$0; 2122 $0return 2 + 2$0;
2059}", 2123}
2060 r" 2124"#,
2125 r#"
2061fn foo() -> u32 { 2126fn foo() -> u32 {
2062 2127
2063 2128
@@ -2066,7 +2131,8 @@ fn foo() -> u32 {
2066 2131
2067fn $0fun_name() -> u32 { 2132fn $0fun_name() -> u32 {
2068 2 + 2 2133 2 + 2
2069}", 2134}
2135"#,
2070 ); 2136 );
2071 } 2137 }
2072 2138
@@ -2074,13 +2140,14 @@ fn $0fun_name() -> u32 {
2074 fn break_stmt() { 2140 fn break_stmt() {
2075 check_assist( 2141 check_assist(
2076 extract_function, 2142 extract_function,
2077 r" 2143 r#"
2078fn main() { 2144fn main() {
2079 let result = loop { 2145 let result = loop {
2080 $0break 2 + 2$0; 2146 $0break 2 + 2$0;
2081 }; 2147 };
2082}", 2148}
2083 r" 2149"#,
2150 r#"
2084fn main() { 2151fn main() {
2085 let result = loop { 2152 let result = loop {
2086 break fun_name(); 2153 break fun_name();
@@ -2089,7 +2156,8 @@ fn main() {
2089 2156
2090fn $0fun_name() -> i32 { 2157fn $0fun_name() -> i32 {
2091 2 + 2 2158 2 + 2
2092}", 2159}
2160"#,
2093 ); 2161 );
2094 } 2162 }
2095 2163
@@ -2097,18 +2165,20 @@ fn $0fun_name() -> i32 {
2097 fn extract_cast() { 2165 fn extract_cast() {
2098 check_assist( 2166 check_assist(
2099 extract_function, 2167 extract_function,
2100 r" 2168 r#"
2101fn main() { 2169fn main() {
2102 let v = $00f32 as u32$0; 2170 let v = $00f32 as u32$0;
2103}", 2171}
2104 r" 2172"#,
2173 r#"
2105fn main() { 2174fn main() {
2106 let v = fun_name(); 2175 let v = fun_name();
2107} 2176}
2108 2177
2109fn $0fun_name() -> u32 { 2178fn $0fun_name() -> u32 {
2110 0f32 as u32 2179 0f32 as u32
2111}", 2180}
2181"#,
2112 ); 2182 );
2113 } 2183 }
2114 2184
@@ -2121,15 +2191,16 @@ fn $0fun_name() -> u32 {
2121 fn method_to_freestanding() { 2191 fn method_to_freestanding() {
2122 check_assist( 2192 check_assist(
2123 extract_function, 2193 extract_function,
2124 r" 2194 r#"
2125struct S; 2195struct S;
2126 2196
2127impl S { 2197impl S {
2128 fn foo(&self) -> i32 { 2198 fn foo(&self) -> i32 {
2129 $01+1$0 2199 $01+1$0
2130 } 2200 }
2131}", 2201}
2132 r" 2202"#,
2203 r#"
2133struct S; 2204struct S;
2134 2205
2135impl S { 2206impl S {
@@ -2140,7 +2211,8 @@ impl S {
2140 2211
2141fn $0fun_name() -> i32 { 2212fn $0fun_name() -> i32 {
2142 1+1 2213 1+1
2143}", 2214}
2215"#,
2144 ); 2216 );
2145 } 2217 }
2146 2218
@@ -2148,15 +2220,16 @@ fn $0fun_name() -> i32 {
2148 fn method_with_reference() { 2220 fn method_with_reference() {
2149 check_assist( 2221 check_assist(
2150 extract_function, 2222 extract_function,
2151 r" 2223 r#"
2152struct S { f: i32 }; 2224struct S { f: i32 };
2153 2225
2154impl S { 2226impl S {
2155 fn foo(&self) -> i32 { 2227 fn foo(&self) -> i32 {
2156 $01+self.f$0 2228 $01+self.f$0
2157 } 2229 }
2158}", 2230}
2159 r" 2231"#,
2232 r#"
2160struct S { f: i32 }; 2233struct S { f: i32 };
2161 2234
2162impl S { 2235impl S {
@@ -2167,7 +2240,8 @@ impl S {
2167 fn $0fun_name(&self) -> i32 { 2240 fn $0fun_name(&self) -> i32 {
2168 1+self.f 2241 1+self.f
2169 } 2242 }
2170}", 2243}
2244"#,
2171 ); 2245 );
2172 } 2246 }
2173 2247
@@ -2175,15 +2249,16 @@ impl S {
2175 fn method_with_mut() { 2249 fn method_with_mut() {
2176 check_assist( 2250 check_assist(
2177 extract_function, 2251 extract_function,
2178 r" 2252 r#"
2179struct S { f: i32 }; 2253struct S { f: i32 };
2180 2254
2181impl S { 2255impl S {
2182 fn foo(&mut self) { 2256 fn foo(&mut self) {
2183 $0self.f += 1;$0 2257 $0self.f += 1;$0
2184 } 2258 }
2185}", 2259}
2186 r" 2260"#,
2261 r#"
2187struct S { f: i32 }; 2262struct S { f: i32 };
2188 2263
2189impl S { 2264impl S {
@@ -2194,7 +2269,8 @@ impl S {
2194 fn $0fun_name(&mut self) { 2269 fn $0fun_name(&mut self) {
2195 self.f += 1; 2270 self.f += 1;
2196 } 2271 }
2197}", 2272}
2273"#,
2198 ); 2274 );
2199 } 2275 }
2200 2276
@@ -2202,13 +2278,14 @@ impl S {
2202 fn variable_defined_inside_and_used_after_no_ret() { 2278 fn variable_defined_inside_and_used_after_no_ret() {
2203 check_assist( 2279 check_assist(
2204 extract_function, 2280 extract_function,
2205 r" 2281 r#"
2206fn foo() { 2282fn foo() {
2207 let n = 1; 2283 let n = 1;
2208 $0let k = n * n;$0 2284 $0let k = n * n;$0
2209 let m = k + 1; 2285 let m = k + 1;
2210}", 2286}
2211 r" 2287"#,
2288 r#"
2212fn foo() { 2289fn foo() {
2213 let n = 1; 2290 let n = 1;
2214 let k = fun_name(n); 2291 let k = fun_name(n);
@@ -2218,7 +2295,8 @@ fn foo() {
2218fn $0fun_name(n: i32) -> i32 { 2295fn $0fun_name(n: i32) -> i32 {
2219 let k = n * n; 2296 let k = n * n;
2220 k 2297 k
2221}", 2298}
2299"#,
2222 ); 2300 );
2223 } 2301 }
2224 2302
@@ -2226,13 +2304,14 @@ fn $0fun_name(n: i32) -> i32 {
2226 fn variable_defined_inside_and_used_after_mutably_no_ret() { 2304 fn variable_defined_inside_and_used_after_mutably_no_ret() {
2227 check_assist( 2305 check_assist(
2228 extract_function, 2306 extract_function,
2229 r" 2307 r#"
2230fn foo() { 2308fn foo() {
2231 let n = 1; 2309 let n = 1;
2232 $0let mut k = n * n;$0 2310 $0let mut k = n * n;$0
2233 k += 1; 2311 k += 1;
2234}", 2312}
2235 r" 2313"#,
2314 r#"
2236fn foo() { 2315fn foo() {
2237 let n = 1; 2316 let n = 1;
2238 let mut k = fun_name(n); 2317 let mut k = fun_name(n);
@@ -2242,7 +2321,8 @@ fn foo() {
2242fn $0fun_name(n: i32) -> i32 { 2321fn $0fun_name(n: i32) -> i32 {
2243 let mut k = n * n; 2322 let mut k = n * n;
2244 k 2323 k
2245}", 2324}
2325"#,
2246 ); 2326 );
2247 } 2327 }
2248 2328
@@ -2250,14 +2330,15 @@ fn $0fun_name(n: i32) -> i32 {
2250 fn two_variables_defined_inside_and_used_after_no_ret() { 2330 fn two_variables_defined_inside_and_used_after_no_ret() {
2251 check_assist( 2331 check_assist(
2252 extract_function, 2332 extract_function,
2253 r" 2333 r#"
2254fn foo() { 2334fn foo() {
2255 let n = 1; 2335 let n = 1;
2256 $0let k = n * n; 2336 $0let k = n * n;
2257 let m = k + 2;$0 2337 let m = k + 2;$0
2258 let h = k + m; 2338 let h = k + m;
2259}", 2339}
2260 r" 2340"#,
2341 r#"
2261fn foo() { 2342fn foo() {
2262 let n = 1; 2343 let n = 1;
2263 let (k, m) = fun_name(n); 2344 let (k, m) = fun_name(n);
@@ -2268,7 +2349,8 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2268 let k = n * n; 2349 let k = n * n;
2269 let m = k + 2; 2350 let m = k + 2;
2270 (k, m) 2351 (k, m)
2271}", 2352}
2353"#,
2272 ); 2354 );
2273 } 2355 }
2274 2356
@@ -2276,7 +2358,7 @@ fn $0fun_name(n: i32) -> (i32, i32) {
2276 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() { 2358 fn multi_variables_defined_inside_and_used_after_mutably_no_ret() {
2277 check_assist( 2359 check_assist(
2278 extract_function, 2360 extract_function,
2279 r" 2361 r#"
2280fn foo() { 2362fn foo() {
2281 let n = 1; 2363 let n = 1;
2282 $0let mut k = n * n; 2364 $0let mut k = n * n;
@@ -2285,8 +2367,9 @@ fn foo() {
2285 o += 1;$0 2367 o += 1;$0
2286 k += o; 2368 k += o;
2287 m = 1; 2369 m = 1;
2288}", 2370}
2289 r" 2371"#,
2372 r#"
2290fn foo() { 2373fn foo() {
2291 let n = 1; 2374 let n = 1;
2292 let (mut k, mut m, o) = fun_name(n); 2375 let (mut k, mut m, o) = fun_name(n);
@@ -2300,7 +2383,8 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2300 let mut o = m + 3; 2383 let mut o = m + 3;
2301 o += 1; 2384 o += 1;
2302 (k, m, o) 2385 (k, m, o)
2303}", 2386}
2387"#,
2304 ); 2388 );
2305 } 2389 }
2306 2390
@@ -2308,13 +2392,14 @@ fn $0fun_name(n: i32) -> (i32, i32, i32) {
2308 fn nontrivial_patterns_define_variables() { 2392 fn nontrivial_patterns_define_variables() {
2309 check_assist( 2393 check_assist(
2310 extract_function, 2394 extract_function,
2311 r" 2395 r#"
2312struct Counter(i32); 2396struct Counter(i32);
2313fn foo() { 2397fn foo() {
2314 $0let Counter(n) = Counter(0);$0 2398 $0let Counter(n) = Counter(0);$0
2315 let m = n; 2399 let m = n;
2316}", 2400}
2317 r" 2401"#,
2402 r#"
2318struct Counter(i32); 2403struct Counter(i32);
2319fn foo() { 2404fn foo() {
2320 let n = fun_name(); 2405 let n = fun_name();
@@ -2324,7 +2409,8 @@ fn foo() {
2324fn $0fun_name() -> i32 { 2409fn $0fun_name() -> i32 {
2325 let Counter(n) = Counter(0); 2410 let Counter(n) = Counter(0);
2326 n 2411 n
2327}", 2412}
2413"#,
2328 ); 2414 );
2329 } 2415 }
2330 2416
@@ -2332,13 +2418,14 @@ fn $0fun_name() -> i32 {
2332 fn struct_with_two_fields_pattern_define_variables() { 2418 fn struct_with_two_fields_pattern_define_variables() {
2333 check_assist( 2419 check_assist(
2334 extract_function, 2420 extract_function,
2335 r" 2421 r#"
2336struct Counter { n: i32, m: i32 }; 2422struct Counter { n: i32, m: i32 };
2337fn foo() { 2423fn foo() {
2338 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0 2424 $0let Counter { n, m: k } = Counter { n: 1, m: 2 };$0
2339 let h = n + k; 2425 let h = n + k;
2340}", 2426}
2341 r" 2427"#,
2428 r#"
2342struct Counter { n: i32, m: i32 }; 2429struct Counter { n: i32, m: i32 };
2343fn foo() { 2430fn foo() {
2344 let (n, k) = fun_name(); 2431 let (n, k) = fun_name();
@@ -2348,7 +2435,8 @@ fn foo() {
2348fn $0fun_name() -> (i32, i32) { 2435fn $0fun_name() -> (i32, i32) {
2349 let Counter { n, m: k } = Counter { n: 1, m: 2 }; 2436 let Counter { n, m: k } = Counter { n: 1, m: 2 };
2350 (n, k) 2437 (n, k)
2351}", 2438}
2439"#,
2352 ); 2440 );
2353 } 2441 }
2354 2442
@@ -2356,13 +2444,14 @@ fn $0fun_name() -> (i32, i32) {
2356 fn mut_var_from_outer_scope() { 2444 fn mut_var_from_outer_scope() {
2357 check_assist( 2445 check_assist(
2358 extract_function, 2446 extract_function,
2359 r" 2447 r#"
2360fn foo() { 2448fn foo() {
2361 let mut n = 1; 2449 let mut n = 1;
2362 $0n += 1;$0 2450 $0n += 1;$0
2363 let m = n + 1; 2451 let m = n + 1;
2364}", 2452}
2365 r" 2453"#,
2454 r#"
2366fn foo() { 2455fn foo() {
2367 let mut n = 1; 2456 let mut n = 1;
2368 fun_name(&mut n); 2457 fun_name(&mut n);
@@ -2371,7 +2460,8 @@ fn foo() {
2371 2460
2372fn $0fun_name(n: &mut i32) { 2461fn $0fun_name(n: &mut i32) {
2373 *n += 1; 2462 *n += 1;
2374}", 2463}
2464"#,
2375 ); 2465 );
2376 } 2466 }
2377 2467
@@ -2379,14 +2469,15 @@ fn $0fun_name(n: &mut i32) {
2379 fn mut_field_from_outer_scope() { 2469 fn mut_field_from_outer_scope() {
2380 check_assist( 2470 check_assist(
2381 extract_function, 2471 extract_function,
2382 r" 2472 r#"
2383struct C { n: i32 } 2473struct C { n: i32 }
2384fn foo() { 2474fn foo() {
2385 let mut c = C { n: 0 }; 2475 let mut c = C { n: 0 };
2386 $0c.n += 1;$0 2476 $0c.n += 1;$0
2387 let m = c.n + 1; 2477 let m = c.n + 1;
2388}", 2478}
2389 r" 2479"#,
2480 r#"
2390struct C { n: i32 } 2481struct C { n: i32 }
2391fn foo() { 2482fn foo() {
2392 let mut c = C { n: 0 }; 2483 let mut c = C { n: 0 };
@@ -2396,7 +2487,8 @@ fn foo() {
2396 2487
2397fn $0fun_name(c: &mut C) { 2488fn $0fun_name(c: &mut C) {
2398 c.n += 1; 2489 c.n += 1;
2399}", 2490}
2491"#,
2400 ); 2492 );
2401 } 2493 }
2402 2494
@@ -2404,7 +2496,7 @@ fn $0fun_name(c: &mut C) {
2404 fn mut_nested_field_from_outer_scope() { 2496 fn mut_nested_field_from_outer_scope() {
2405 check_assist( 2497 check_assist(
2406 extract_function, 2498 extract_function,
2407 r" 2499 r#"
2408struct P { n: i32} 2500struct P { n: i32}
2409struct C { p: P } 2501struct C { p: P }
2410fn foo() { 2502fn foo() {
@@ -2414,8 +2506,9 @@ fn foo() {
2414 $0c.p.n += u.p.n; 2506 $0c.p.n += u.p.n;
2415 let r = &mut v.p.n;$0 2507 let r = &mut v.p.n;$0
2416 let m = c.p.n + v.p.n + u.p.n; 2508 let m = c.p.n + v.p.n + u.p.n;
2417}", 2509}
2418 r" 2510"#,
2511 r#"
2419struct P { n: i32} 2512struct P { n: i32}
2420struct C { p: P } 2513struct C { p: P }
2421fn foo() { 2514fn foo() {
@@ -2429,7 +2522,8 @@ fn foo() {
2429fn $0fun_name(c: &mut C, u: &C, v: &mut C) { 2522fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2430 c.p.n += u.p.n; 2523 c.p.n += u.p.n;
2431 let r = &mut v.p.n; 2524 let r = &mut v.p.n;
2432}", 2525}
2526"#,
2433 ); 2527 );
2434 } 2528 }
2435 2529
@@ -2437,7 +2531,7 @@ fn $0fun_name(c: &mut C, u: &C, v: &mut C) {
2437 fn mut_param_many_usages_stmt() { 2531 fn mut_param_many_usages_stmt() {
2438 check_assist( 2532 check_assist(
2439 extract_function, 2533 extract_function,
2440 r" 2534 r#"
2441fn bar(k: i32) {} 2535fn bar(k: i32) {}
2442trait I: Copy { 2536trait I: Copy {
2443 fn succ(&self) -> Self; 2537 fn succ(&self) -> Self;
@@ -2458,8 +2552,9 @@ fn foo() {
2458 *v = v.succ(); 2552 *v = v.succ();
2459 n.succ();$0 2553 n.succ();$0
2460 let m = n + 1; 2554 let m = n + 1;
2461}", 2555}
2462 r" 2556"#,
2557 r#"
2463fn bar(k: i32) {} 2558fn bar(k: i32) {}
2464trait I: Copy { 2559trait I: Copy {
2465 fn succ(&self) -> Self; 2560 fn succ(&self) -> Self;
@@ -2484,7 +2579,8 @@ fn $0fun_name(n: &mut i32) {
2484 let v = n; 2579 let v = n;
2485 *v = v.succ(); 2580 *v = v.succ();
2486 n.succ(); 2581 n.succ();
2487}", 2582}
2583"#,
2488 ); 2584 );
2489 } 2585 }
2490 2586
@@ -2492,7 +2588,7 @@ fn $0fun_name(n: &mut i32) {
2492 fn mut_param_many_usages_expr() { 2588 fn mut_param_many_usages_expr() {
2493 check_assist( 2589 check_assist(
2494 extract_function, 2590 extract_function,
2495 r" 2591 r#"
2496fn bar(k: i32) {} 2592fn bar(k: i32) {}
2497trait I: Copy { 2593trait I: Copy {
2498 fn succ(&self) -> Self; 2594 fn succ(&self) -> Self;
@@ -2515,8 +2611,9 @@ fn foo() {
2515 n.succ(); 2611 n.succ();
2516 }$0 2612 }$0
2517 let m = n + 1; 2613 let m = n + 1;
2518}", 2614}
2519 r" 2615"#,
2616 r#"
2520fn bar(k: i32) {} 2617fn bar(k: i32) {}
2521trait I: Copy { 2618trait I: Copy {
2522 fn succ(&self) -> Self; 2619 fn succ(&self) -> Self;
@@ -2541,7 +2638,8 @@ fn $0fun_name(n: &mut i32) {
2541 let v = n; 2638 let v = n;
2542 *v = v.succ(); 2639 *v = v.succ();
2543 n.succ(); 2640 n.succ();
2544}", 2641}
2642"#,
2545 ); 2643 );
2546 } 2644 }
2547 2645
@@ -2549,11 +2647,12 @@ fn $0fun_name(n: &mut i32) {
2549 fn mut_param_by_value() { 2647 fn mut_param_by_value() {
2550 check_assist( 2648 check_assist(
2551 extract_function, 2649 extract_function,
2552 r" 2650 r#"
2553fn foo() { 2651fn foo() {
2554 let mut n = 1; 2652 let mut n = 1;
2555 $0n += 1;$0 2653 $0n += 1;$0
2556}", 2654}
2655"#,
2557 r" 2656 r"
2558fn foo() { 2657fn foo() {
2559 let mut n = 1; 2658 let mut n = 1;
@@ -2562,7 +2661,8 @@ fn foo() {
2562 2661
2563fn $0fun_name(mut n: i32) { 2662fn $0fun_name(mut n: i32) {
2564 n += 1; 2663 n += 1;
2565}", 2664}
2665",
2566 ); 2666 );
2567 } 2667 }
2568 2668
@@ -2570,14 +2670,15 @@ fn $0fun_name(mut n: i32) {
2570 fn mut_param_because_of_mut_ref() { 2670 fn mut_param_because_of_mut_ref() {
2571 check_assist( 2671 check_assist(
2572 extract_function, 2672 extract_function,
2573 r" 2673 r#"
2574fn foo() { 2674fn foo() {
2575 let mut n = 1; 2675 let mut n = 1;
2576 $0let v = &mut n; 2676 $0let v = &mut n;
2577 *v += 1;$0 2677 *v += 1;$0
2578 let k = n; 2678 let k = n;
2579}", 2679}
2580 r" 2680"#,
2681 r#"
2581fn foo() { 2682fn foo() {
2582 let mut n = 1; 2683 let mut n = 1;
2583 fun_name(&mut n); 2684 fun_name(&mut n);
@@ -2587,7 +2688,8 @@ fn foo() {
2587fn $0fun_name(n: &mut i32) { 2688fn $0fun_name(n: &mut i32) {
2588 let v = n; 2689 let v = n;
2589 *v += 1; 2690 *v += 1;
2590}", 2691}
2692"#,
2591 ); 2693 );
2592 } 2694 }
2593 2695
@@ -2600,8 +2702,9 @@ fn foo() {
2600 let mut n = 1; 2702 let mut n = 1;
2601 $0let v = &mut n; 2703 $0let v = &mut n;
2602 *v += 1;$0 2704 *v += 1;$0
2603}", 2705}
2604 r" 2706",
2707 r#"
2605fn foo() { 2708fn foo() {
2606 let mut n = 1; 2709 let mut n = 1;
2607 fun_name(n); 2710 fun_name(n);
@@ -2610,7 +2713,8 @@ fn foo() {
2610fn $0fun_name(mut n: i32) { 2713fn $0fun_name(mut n: i32) {
2611 let v = &mut n; 2714 let v = &mut n;
2612 *v += 1; 2715 *v += 1;
2613}", 2716}
2717"#,
2614 ); 2718 );
2615 } 2719 }
2616 2720
@@ -2618,7 +2722,7 @@ fn $0fun_name(mut n: i32) {
2618 fn mut_method_call() { 2722 fn mut_method_call() {
2619 check_assist( 2723 check_assist(
2620 extract_function, 2724 extract_function,
2621 r" 2725 r#"
2622trait I { 2726trait I {
2623 fn inc(&mut self); 2727 fn inc(&mut self);
2624} 2728}
@@ -2628,8 +2732,9 @@ impl I for i32 {
2628fn foo() { 2732fn foo() {
2629 let mut n = 1; 2733 let mut n = 1;
2630 $0n.inc();$0 2734 $0n.inc();$0
2631}", 2735}
2632 r" 2736"#,
2737 r#"
2633trait I { 2738trait I {
2634 fn inc(&mut self); 2739 fn inc(&mut self);
2635} 2740}
@@ -2643,7 +2748,8 @@ fn foo() {
2643 2748
2644fn $0fun_name(mut n: i32) { 2749fn $0fun_name(mut n: i32) {
2645 n.inc(); 2750 n.inc();
2646}", 2751}
2752"#,
2647 ); 2753 );
2648 } 2754 }
2649 2755
@@ -2651,7 +2757,7 @@ fn $0fun_name(mut n: i32) {
2651 fn shared_method_call() { 2757 fn shared_method_call() {
2652 check_assist( 2758 check_assist(
2653 extract_function, 2759 extract_function,
2654 r" 2760 r#"
2655trait I { 2761trait I {
2656 fn succ(&self); 2762 fn succ(&self);
2657} 2763}
@@ -2661,7 +2767,8 @@ impl I for i32 {
2661fn foo() { 2767fn foo() {
2662 let mut n = 1; 2768 let mut n = 1;
2663 $0n.succ();$0 2769 $0n.succ();$0
2664}", 2770}
2771"#,
2665 r" 2772 r"
2666trait I { 2773trait I {
2667 fn succ(&self); 2774 fn succ(&self);
@@ -2676,7 +2783,8 @@ fn foo() {
2676 2783
2677fn $0fun_name(n: i32) { 2784fn $0fun_name(n: i32) {
2678 n.succ(); 2785 n.succ();
2679}", 2786}
2787",
2680 ); 2788 );
2681 } 2789 }
2682 2790
@@ -2684,7 +2792,7 @@ fn $0fun_name(n: i32) {
2684 fn mut_method_call_with_other_receiver() { 2792 fn mut_method_call_with_other_receiver() {
2685 check_assist( 2793 check_assist(
2686 extract_function, 2794 extract_function,
2687 r" 2795 r#"
2688trait I { 2796trait I {
2689 fn inc(&mut self, n: i32); 2797 fn inc(&mut self, n: i32);
2690} 2798}
@@ -2695,7 +2803,8 @@ fn foo() {
2695 let mut n = 1; 2803 let mut n = 1;
2696 $0let mut m = 2; 2804 $0let mut m = 2;
2697 m.inc(n);$0 2805 m.inc(n);$0
2698}", 2806}
2807"#,
2699 r" 2808 r"
2700trait I { 2809trait I {
2701 fn inc(&mut self, n: i32); 2810 fn inc(&mut self, n: i32);
@@ -2711,7 +2820,8 @@ fn foo() {
2711fn $0fun_name(n: i32) { 2820fn $0fun_name(n: i32) {
2712 let mut m = 2; 2821 let mut m = 2;
2713 m.inc(n); 2822 m.inc(n);
2714}", 2823}
2824",
2715 ); 2825 );
2716 } 2826 }
2717 2827
@@ -2719,12 +2829,13 @@ fn $0fun_name(n: i32) {
2719 fn non_copy_without_usages_after() { 2829 fn non_copy_without_usages_after() {
2720 check_assist( 2830 check_assist(
2721 extract_function, 2831 extract_function,
2722 r" 2832 r#"
2723struct Counter(i32); 2833struct Counter(i32);
2724fn foo() { 2834fn foo() {
2725 let c = Counter(0); 2835 let c = Counter(0);
2726 $0let n = c.0;$0 2836 $0let n = c.0;$0
2727}", 2837}
2838"#,
2728 r" 2839 r"
2729struct Counter(i32); 2840struct Counter(i32);
2730fn foo() { 2841fn foo() {
@@ -2734,7 +2845,8 @@ fn foo() {
2734 2845
2735fn $0fun_name(c: Counter) { 2846fn $0fun_name(c: Counter) {
2736 let n = c.0; 2847 let n = c.0;
2737}", 2848}
2849",
2738 ); 2850 );
2739 } 2851 }
2740 2852
@@ -2748,8 +2860,9 @@ fn foo() {
2748 let c = Counter(0); 2860 let c = Counter(0);
2749 $0let n = c.0;$0 2861 $0let n = c.0;$0
2750 let m = c.0; 2862 let m = c.0;
2751}", 2863}
2752 r" 2864",
2865 r#"
2753struct Counter(i32); 2866struct Counter(i32);
2754fn foo() { 2867fn foo() {
2755 let c = Counter(0); 2868 let c = Counter(0);
@@ -2759,7 +2872,8 @@ fn foo() {
2759 2872
2760fn $0fun_name(c: &Counter) { 2873fn $0fun_name(c: &Counter) {
2761 let n = c.0; 2874 let n = c.0;
2762}", 2875}
2876"#,
2763 ); 2877 );
2764 } 2878 }
2765 2879
@@ -2767,19 +2881,15 @@ fn $0fun_name(c: &Counter) {
2767 fn copy_used_after() { 2881 fn copy_used_after() {
2768 check_assist( 2882 check_assist(
2769 extract_function, 2883 extract_function,
2770 r##" 2884 r#"
2771#[lang = "copy"] 2885//- minicore: copy
2772pub trait Copy {}
2773impl Copy for i32 {}
2774fn foo() { 2886fn foo() {
2775 let n = 0; 2887 let n = 0;
2776 $0let m = n;$0 2888 $0let m = n;$0
2777 let k = n; 2889 let k = n;
2778}"##, 2890}
2779 r##" 2891"#,
2780#[lang = "copy"] 2892 r#"
2781pub trait Copy {}
2782impl Copy for i32 {}
2783fn foo() { 2893fn foo() {
2784 let n = 0; 2894 let n = 0;
2785 fun_name(n); 2895 fun_name(n);
@@ -2788,7 +2898,8 @@ fn foo() {
2788 2898
2789fn $0fun_name(n: i32) { 2899fn $0fun_name(n: i32) {
2790 let m = n; 2900 let m = n;
2791}"##, 2901}
2902"#,
2792 ) 2903 )
2793 } 2904 }
2794 2905
@@ -2796,21 +2907,19 @@ fn $0fun_name(n: i32) {
2796 fn copy_custom_used_after() { 2907 fn copy_custom_used_after() {
2797 check_assist( 2908 check_assist(
2798 extract_function, 2909 extract_function,
2799 r##" 2910 r#"
2800#[lang = "copy"] 2911//- minicore: copy, derive
2801pub trait Copy {} 2912#[derive(Clone, Copy)]
2802struct Counter(i32); 2913struct Counter(i32);
2803impl Copy for Counter {}
2804fn foo() { 2914fn foo() {
2805 let c = Counter(0); 2915 let c = Counter(0);
2806 $0let n = c.0;$0 2916 $0let n = c.0;$0
2807 let m = c.0; 2917 let m = c.0;
2808}"##, 2918}
2809 r##" 2919"#,
2810#[lang = "copy"] 2920 r#"
2811pub trait Copy {} 2921#[derive(Clone, Copy)]
2812struct Counter(i32); 2922struct Counter(i32);
2813impl Copy for Counter {}
2814fn foo() { 2923fn foo() {
2815 let c = Counter(0); 2924 let c = Counter(0);
2816 fun_name(c); 2925 fun_name(c);
@@ -2819,7 +2928,8 @@ fn foo() {
2819 2928
2820fn $0fun_name(c: Counter) { 2929fn $0fun_name(c: Counter) {
2821 let n = c.0; 2930 let n = c.0;
2822}"##, 2931}
2932"#,
2823 ); 2933 );
2824 } 2934 }
2825 2935
@@ -2827,7 +2937,7 @@ fn $0fun_name(c: Counter) {
2827 fn indented_stmts() { 2937 fn indented_stmts() {
2828 check_assist( 2938 check_assist(
2829 extract_function, 2939 extract_function,
2830 r" 2940 r#"
2831fn foo() { 2941fn foo() {
2832 if true { 2942 if true {
2833 loop { 2943 loop {
@@ -2835,8 +2945,9 @@ fn foo() {
2835 let m = 2;$0 2945 let m = 2;$0
2836 } 2946 }
2837 } 2947 }
2838}", 2948}
2839 r" 2949"#,
2950 r#"
2840fn foo() { 2951fn foo() {
2841 if true { 2952 if true {
2842 loop { 2953 loop {
@@ -2848,7 +2959,8 @@ fn foo() {
2848fn $0fun_name() { 2959fn $0fun_name() {
2849 let n = 1; 2960 let n = 1;
2850 let m = 2; 2961 let m = 2;
2851}", 2962}
2963"#,
2852 ); 2964 );
2853 } 2965 }
2854 2966
@@ -2856,7 +2968,7 @@ fn $0fun_name() {
2856 fn indented_stmts_inside_mod() { 2968 fn indented_stmts_inside_mod() {
2857 check_assist( 2969 check_assist(
2858 extract_function, 2970 extract_function,
2859 r" 2971 r#"
2860mod bar { 2972mod bar {
2861 fn foo() { 2973 fn foo() {
2862 if true { 2974 if true {
@@ -2866,8 +2978,9 @@ mod bar {
2866 } 2978 }
2867 } 2979 }
2868 } 2980 }
2869}", 2981}
2870 r" 2982"#,
2983 r#"
2871mod bar { 2984mod bar {
2872 fn foo() { 2985 fn foo() {
2873 if true { 2986 if true {
@@ -2881,7 +2994,8 @@ mod bar {
2881 let n = 1; 2994 let n = 1;
2882 let m = 2; 2995 let m = 2;
2883 } 2996 }
2884}", 2997}
2998"#,
2885 ); 2999 );
2886 } 3000 }
2887 3001
@@ -2889,12 +3003,8 @@ mod bar {
2889 fn break_loop() { 3003 fn break_loop() {
2890 check_assist( 3004 check_assist(
2891 extract_function, 3005 extract_function,
2892 r##" 3006 r#"
2893enum Option<T> { 3007//- minicore: option
2894 #[lang = "None"] None,
2895 #[lang = "Some"] Some(T),
2896}
2897use Option::*;
2898fn foo() { 3008fn foo() {
2899 loop { 3009 loop {
2900 let n = 1; 3010 let n = 1;
@@ -2903,13 +3013,9 @@ fn foo() {
2903 let k = 2;$0 3013 let k = 2;$0
2904 let h = 1 + k; 3014 let h = 1 + k;
2905 } 3015 }
2906}"##,
2907 r##"
2908enum Option<T> {
2909 #[lang = "None"] None,
2910 #[lang = "Some"] Some(T),
2911} 3016}
2912use Option::*; 3017"#,
3018 r#"
2913fn foo() { 3019fn foo() {
2914 loop { 3020 loop {
2915 let n = 1; 3021 let n = 1;
@@ -2926,7 +3032,8 @@ fn $0fun_name(n: i32) -> Option<i32> {
2926 return None; 3032 return None;
2927 let k = 2; 3033 let k = 2;
2928 Some(k) 3034 Some(k)
2929}"##, 3035}
3036"#,
2930 ); 3037 );
2931 } 3038 }
2932 3039
@@ -2934,31 +3041,17 @@ fn $0fun_name(n: i32) -> Option<i32> {
2934 fn return_to_parent() { 3041 fn return_to_parent() {
2935 check_assist( 3042 check_assist(
2936 extract_function, 3043 extract_function,
2937 r##" 3044 r#"
2938#[lang = "copy"] 3045//- minicore: copy, result
2939pub trait Copy {}
2940impl Copy for i32 {}
2941enum Result<T, E> {
2942 #[lang = "Ok"] Ok(T),
2943 #[lang = "Err"] Err(E),
2944}
2945use Result::*;
2946fn foo() -> i64 { 3046fn foo() -> i64 {
2947 let n = 1; 3047 let n = 1;
2948 $0let m = n + 1; 3048 $0let m = n + 1;
2949 return 1; 3049 return 1;
2950 let k = 2;$0 3050 let k = 2;$0
2951 (n + k) as i64 3051 (n + k) as i64
2952}"##, 3052}
2953 r##" 3053"#,
2954#[lang = "copy"] 3054 r#"
2955pub trait Copy {}
2956impl Copy for i32 {}
2957enum Result<T, E> {
2958 #[lang = "Ok"] Ok(T),
2959 #[lang = "Err"] Err(E),
2960}
2961use Result::*;
2962fn foo() -> i64 { 3055fn foo() -> i64 {
2963 let n = 1; 3056 let n = 1;
2964 let k = match fun_name(n) { 3057 let k = match fun_name(n) {
@@ -2973,7 +3066,8 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2973 return Err(1); 3066 return Err(1);
2974 let k = 2; 3067 let k = 2;
2975 Ok(k) 3068 Ok(k)
2976}"##, 3069}
3070"#,
2977 ); 3071 );
2978 } 3072 }
2979 3073
@@ -2982,7 +3076,7 @@ fn $0fun_name(n: i32) -> Result<i32, i64> {
2982 cov_mark::check!(external_control_flow_break_and_continue); 3076 cov_mark::check!(external_control_flow_break_and_continue);
2983 check_assist_not_applicable( 3077 check_assist_not_applicable(
2984 extract_function, 3078 extract_function,
2985 r##" 3079 r#"
2986fn foo() { 3080fn foo() {
2987 loop { 3081 loop {
2988 let n = 1; 3082 let n = 1;
@@ -2993,7 +3087,8 @@ fn foo() {
2993 let k = k + 1;$0 3087 let k = k + 1;$0
2994 let r = n + k; 3088 let r = n + k;
2995 } 3089 }
2996}"##, 3090}
3091"#,
2997 ); 3092 );
2998 } 3093 }
2999 3094
@@ -3002,7 +3097,7 @@ fn foo() {
3002 cov_mark::check!(external_control_flow_return_and_bc); 3097 cov_mark::check!(external_control_flow_return_and_bc);
3003 check_assist_not_applicable( 3098 check_assist_not_applicable(
3004 extract_function, 3099 extract_function,
3005 r##" 3100 r#"
3006fn foo() { 3101fn foo() {
3007 loop { 3102 loop {
3008 let n = 1; 3103 let n = 1;
@@ -3013,7 +3108,8 @@ fn foo() {
3013 let k = k + 1;$0 3108 let k = k + 1;$0
3014 let r = n + k; 3109 let r = n + k;
3015 } 3110 }
3016}"##, 3111}
3112"#,
3017 ); 3113 );
3018 } 3114 }
3019 3115
@@ -3021,7 +3117,7 @@ fn foo() {
3021 fn break_loop_with_if() { 3117 fn break_loop_with_if() {
3022 check_assist( 3118 check_assist(
3023 extract_function, 3119 extract_function,
3024 r##" 3120 r#"
3025fn foo() { 3121fn foo() {
3026 loop { 3122 loop {
3027 let mut n = 1; 3123 let mut n = 1;
@@ -3030,8 +3126,9 @@ fn foo() {
3030 n += m;$0 3126 n += m;$0
3031 let h = 1 + n; 3127 let h = 1 + n;
3032 } 3128 }
3033}"##, 3129}
3034 r##" 3130"#,
3131 r#"
3035fn foo() { 3132fn foo() {
3036 loop { 3133 loop {
3037 let mut n = 1; 3134 let mut n = 1;
@@ -3047,7 +3144,8 @@ fn $0fun_name(n: &mut i32) -> bool {
3047 return true; 3144 return true;
3048 *n += m; 3145 *n += m;
3049 false 3146 false
3050}"##, 3147}
3148"#,
3051 ); 3149 );
3052 } 3150 }
3053 3151
@@ -3055,7 +3153,7 @@ fn $0fun_name(n: &mut i32) -> bool {
3055 fn break_loop_nested() { 3153 fn break_loop_nested() {
3056 check_assist( 3154 check_assist(
3057 extract_function, 3155 extract_function,
3058 r##" 3156 r#"
3059fn foo() { 3157fn foo() {
3060 loop { 3158 loop {
3061 let mut n = 1; 3159 let mut n = 1;
@@ -3065,8 +3163,9 @@ fn foo() {
3065 }$0 3163 }$0
3066 let h = 1; 3164 let h = 1;
3067 } 3165 }
3068}"##, 3166}
3069 r##" 3167"#,
3168 r#"
3070fn foo() { 3169fn foo() {
3071 loop { 3170 loop {
3072 let mut n = 1; 3171 let mut n = 1;
@@ -3083,7 +3182,8 @@ fn $0fun_name(n: i32) -> bool {
3083 return true; 3182 return true;
3084 } 3183 }
3085 false 3184 false
3086}"##, 3185}
3186"#,
3087 ); 3187 );
3088 } 3188 }
3089 3189
@@ -3091,7 +3191,7 @@ fn $0fun_name(n: i32) -> bool {
3091 fn return_from_nested_loop() { 3191 fn return_from_nested_loop() {
3092 check_assist( 3192 check_assist(
3093 extract_function, 3193 extract_function,
3094 r##" 3194 r#"
3095fn foo() { 3195fn foo() {
3096 loop { 3196 loop {
3097 let n = 1; 3197 let n = 1;
@@ -3103,8 +3203,9 @@ fn foo() {
3103 let m = k + 1;$0 3203 let m = k + 1;$0
3104 let h = 1 + m; 3204 let h = 1 + m;
3105 } 3205 }
3106}"##, 3206}
3107 r##" 3207"#,
3208 r#"
3108fn foo() { 3209fn foo() {
3109 loop { 3210 loop {
3110 let n = 1; 3211 let n = 1;
@@ -3123,7 +3224,8 @@ fn $0fun_name() -> Option<i32> {
3123 } 3224 }
3124 let m = k + 1; 3225 let m = k + 1;
3125 Some(m) 3226 Some(m)
3126}"##, 3227}
3228"#,
3127 ); 3229 );
3128 } 3230 }
3129 3231
@@ -3131,7 +3233,7 @@ fn $0fun_name() -> Option<i32> {
3131 fn break_from_nested_loop() { 3233 fn break_from_nested_loop() {
3132 check_assist( 3234 check_assist(
3133 extract_function, 3235 extract_function,
3134 r##" 3236 r#"
3135fn foo() { 3237fn foo() {
3136 loop { 3238 loop {
3137 let n = 1; 3239 let n = 1;
@@ -3142,8 +3244,9 @@ fn foo() {
3142 let m = k + 1;$0 3244 let m = k + 1;$0
3143 let h = 1 + m; 3245 let h = 1 + m;
3144 } 3246 }
3145}"##, 3247}
3146 r##" 3248"#,
3249 r#"
3147fn foo() { 3250fn foo() {
3148 loop { 3251 loop {
3149 let n = 1; 3252 let n = 1;
@@ -3159,7 +3262,8 @@ fn $0fun_name() -> i32 {
3159 } 3262 }
3160 let m = k + 1; 3263 let m = k + 1;
3161 m 3264 m
3162}"##, 3265}
3266"#,
3163 ); 3267 );
3164 } 3268 }
3165 3269
@@ -3167,7 +3271,7 @@ fn $0fun_name() -> i32 {
3167 fn break_from_nested_and_outer_loops() { 3271 fn break_from_nested_and_outer_loops() {
3168 check_assist( 3272 check_assist(
3169 extract_function, 3273 extract_function,
3170 r##" 3274 r#"
3171fn foo() { 3275fn foo() {
3172 loop { 3276 loop {
3173 let n = 1; 3277 let n = 1;
@@ -3181,8 +3285,9 @@ fn foo() {
3181 let m = k + 1;$0 3285 let m = k + 1;$0
3182 let h = 1 + m; 3286 let h = 1 + m;
3183 } 3287 }
3184}"##, 3288}
3185 r##" 3289"#,
3290 r#"
3186fn foo() { 3291fn foo() {
3187 loop { 3292 loop {
3188 let n = 1; 3293 let n = 1;
@@ -3204,7 +3309,8 @@ fn $0fun_name() -> Option<i32> {
3204 } 3309 }
3205 let m = k + 1; 3310 let m = k + 1;
3206 Some(m) 3311 Some(m)
3207}"##, 3312}
3313"#,
3208 ); 3314 );
3209 } 3315 }
3210 3316
@@ -3212,7 +3318,7 @@ fn $0fun_name() -> Option<i32> {
3212 fn return_from_nested_fn() { 3318 fn return_from_nested_fn() {
3213 check_assist( 3319 check_assist(
3214 extract_function, 3320 extract_function,
3215 r##" 3321 r#"
3216fn foo() { 3322fn foo() {
3217 loop { 3323 loop {
3218 let n = 1; 3324 let n = 1;
@@ -3223,8 +3329,9 @@ fn foo() {
3223 let m = k + 1;$0 3329 let m = k + 1;$0
3224 let h = 1 + m; 3330 let h = 1 + m;
3225 } 3331 }
3226}"##, 3332}
3227 r##" 3333"#,
3334 r#"
3228fn foo() { 3335fn foo() {
3229 loop { 3336 loop {
3230 let n = 1; 3337 let n = 1;
@@ -3240,7 +3347,8 @@ fn $0fun_name() -> i32 {
3240 } 3347 }
3241 let m = k + 1; 3348 let m = k + 1;
3242 m 3349 m
3243}"##, 3350}
3351"#,
3244 ); 3352 );
3245 } 3353 }
3246 3354
@@ -3248,7 +3356,7 @@ fn $0fun_name() -> i32 {
3248 fn break_with_value() { 3356 fn break_with_value() {
3249 check_assist( 3357 check_assist(
3250 extract_function, 3358 extract_function,
3251 r##" 3359 r#"
3252fn foo() -> i32 { 3360fn foo() -> i32 {
3253 loop { 3361 loop {
3254 let n = 1; 3362 let n = 1;
@@ -3259,8 +3367,9 @@ fn foo() -> i32 {
3259 let m = k + 1;$0 3367 let m = k + 1;$0
3260 let h = 1; 3368 let h = 1;
3261 } 3369 }
3262}"##, 3370}
3263 r##" 3371"#,
3372 r#"
3264fn foo() -> i32 { 3373fn foo() -> i32 {
3265 loop { 3374 loop {
3266 let n = 1; 3375 let n = 1;
@@ -3278,7 +3387,8 @@ fn $0fun_name() -> Option<i32> {
3278 } 3387 }
3279 let m = k + 1; 3388 let m = k + 1;
3280 None 3389 None
3281}"##, 3390}
3391"#,
3282 ); 3392 );
3283 } 3393 }
3284 3394
@@ -3286,7 +3396,7 @@ fn $0fun_name() -> Option<i32> {
3286 fn break_with_value_and_return() { 3396 fn break_with_value_and_return() {
3287 check_assist( 3397 check_assist(
3288 extract_function, 3398 extract_function,
3289 r##" 3399 r#"
3290fn foo() -> i64 { 3400fn foo() -> i64 {
3291 loop { 3401 loop {
3292 let n = 1; 3402 let n = 1;
@@ -3298,8 +3408,9 @@ fn foo() -> i64 {
3298 let m = k + 1;$0 3408 let m = k + 1;$0
3299 let h = 1 + m; 3409 let h = 1 + m;
3300 } 3410 }
3301}"##, 3411}
3302 r##" 3412"#,
3413 r#"
3303fn foo() -> i64 { 3414fn foo() -> i64 {
3304 loop { 3415 loop {
3305 let n = 1; 3416 let n = 1;
@@ -3318,7 +3429,8 @@ fn $0fun_name() -> Result<i32, i64> {
3318 } 3429 }
3319 let m = k + 1; 3430 let m = k + 1;
3320 Ok(m) 3431 Ok(m)
3321}"##, 3432}
3433"#,
3322 ); 3434 );
3323 } 3435 }
3324 3436
@@ -3326,9 +3438,8 @@ fn $0fun_name() -> Result<i32, i64> {
3326 fn try_option() { 3438 fn try_option() {
3327 check_assist( 3439 check_assist(
3328 extract_function, 3440 extract_function,
3329 r##" 3441 r#"
3330enum Option<T> { None, Some(T), } 3442//- minicore: option
3331use Option::*;
3332fn bar() -> Option<i32> { None } 3443fn bar() -> Option<i32> { None }
3333fn foo() -> Option<()> { 3444fn foo() -> Option<()> {
3334 let n = bar()?; 3445 let n = bar()?;
@@ -3336,10 +3447,9 @@ fn foo() -> Option<()> {
3336 let m = k + 1;$0 3447 let m = k + 1;$0
3337 let h = 1 + m; 3448 let h = 1 + m;
3338 Some(()) 3449 Some(())
3339}"##, 3450}
3340 r##" 3451"#,
3341enum Option<T> { None, Some(T), } 3452 r#"
3342use Option::*;
3343fn bar() -> Option<i32> { None } 3453fn bar() -> Option<i32> { None }
3344fn foo() -> Option<()> { 3454fn foo() -> Option<()> {
3345 let n = bar()?; 3455 let n = bar()?;
@@ -3352,7 +3462,8 @@ fn $0fun_name() -> Option<i32> {
3352 let k = foo()?; 3462 let k = foo()?;
3353 let m = k + 1; 3463 let m = k + 1;
3354 Some(m) 3464 Some(m)
3355}"##, 3465}
3466"#,
3356 ); 3467 );
3357 } 3468 }
3358 3469
@@ -3360,19 +3471,17 @@ fn $0fun_name() -> Option<i32> {
3360 fn try_option_unit() { 3471 fn try_option_unit() {
3361 check_assist( 3472 check_assist(
3362 extract_function, 3473 extract_function,
3363 r##" 3474 r#"
3364enum Option<T> { None, Some(T), } 3475//- minicore: option
3365use Option::*;
3366fn foo() -> Option<()> { 3476fn foo() -> Option<()> {
3367 let n = 1; 3477 let n = 1;
3368 $0let k = foo()?; 3478 $0let k = foo()?;
3369 let m = k + 1;$0 3479 let m = k + 1;$0
3370 let h = 1 + n; 3480 let h = 1 + n;
3371 Some(()) 3481 Some(())
3372}"##, 3482}
3373 r##" 3483"#,
3374enum Option<T> { None, Some(T), } 3484 r#"
3375use Option::*;
3376fn foo() -> Option<()> { 3485fn foo() -> Option<()> {
3377 let n = 1; 3486 let n = 1;
3378 fun_name()?; 3487 fun_name()?;
@@ -3384,7 +3493,8 @@ fn $0fun_name() -> Option<()> {
3384 let k = foo()?; 3493 let k = foo()?;
3385 let m = k + 1; 3494 let m = k + 1;
3386 Some(()) 3495 Some(())
3387}"##, 3496}
3497"#,
3388 ); 3498 );
3389 } 3499 }
3390 3500
@@ -3392,19 +3502,17 @@ fn $0fun_name() -> Option<()> {
3392 fn try_result() { 3502 fn try_result() {
3393 check_assist( 3503 check_assist(
3394 extract_function, 3504 extract_function,
3395 r##" 3505 r#"
3396enum Result<T, E> { Ok(T), Err(E), } 3506//- minicore: result
3397use Result::*;
3398fn foo() -> Result<(), i64> { 3507fn foo() -> Result<(), i64> {
3399 let n = 1; 3508 let n = 1;
3400 $0let k = foo()?; 3509 $0let k = foo()?;
3401 let m = k + 1;$0 3510 let m = k + 1;$0
3402 let h = 1 + m; 3511 let h = 1 + m;
3403 Ok(()) 3512 Ok(())
3404}"##, 3513}
3405 r##" 3514"#,
3406enum Result<T, E> { Ok(T), Err(E), } 3515 r#"
3407use Result::*;
3408fn foo() -> Result<(), i64> { 3516fn foo() -> Result<(), i64> {
3409 let n = 1; 3517 let n = 1;
3410 let m = fun_name()?; 3518 let m = fun_name()?;
@@ -3416,7 +3524,8 @@ fn $0fun_name() -> Result<i32, i64> {
3416 let k = foo()?; 3524 let k = foo()?;
3417 let m = k + 1; 3525 let m = k + 1;
3418 Ok(m) 3526 Ok(m)
3419}"##, 3527}
3528"#,
3420 ); 3529 );
3421 } 3530 }
3422 3531
@@ -3424,9 +3533,8 @@ fn $0fun_name() -> Result<i32, i64> {
3424 fn try_option_with_return() { 3533 fn try_option_with_return() {
3425 check_assist( 3534 check_assist(
3426 extract_function, 3535 extract_function,
3427 r##" 3536 r#"
3428enum Option<T> { None, Some(T) } 3537//- minicore: option
3429use Option::*;
3430fn foo() -> Option<()> { 3538fn foo() -> Option<()> {
3431 let n = 1; 3539 let n = 1;
3432 $0let k = foo()?; 3540 $0let k = foo()?;
@@ -3436,10 +3544,9 @@ fn foo() -> Option<()> {
3436 let m = k + 1;$0 3544 let m = k + 1;$0
3437 let h = 1 + m; 3545 let h = 1 + m;
3438 Some(()) 3546 Some(())
3439}"##, 3547}
3440 r##" 3548"#,
3441enum Option<T> { None, Some(T) } 3549 r#"
3442use Option::*;
3443fn foo() -> Option<()> { 3550fn foo() -> Option<()> {
3444 let n = 1; 3551 let n = 1;
3445 let m = fun_name()?; 3552 let m = fun_name()?;
@@ -3454,7 +3561,8 @@ fn $0fun_name() -> Option<i32> {
3454 } 3561 }
3455 let m = k + 1; 3562 let m = k + 1;
3456 Some(m) 3563 Some(m)
3457}"##, 3564}
3565"#,
3458 ); 3566 );
3459 } 3567 }
3460 3568
@@ -3462,9 +3570,8 @@ fn $0fun_name() -> Option<i32> {
3462 fn try_result_with_return() { 3570 fn try_result_with_return() {
3463 check_assist( 3571 check_assist(
3464 extract_function, 3572 extract_function,
3465 r##" 3573 r#"
3466enum Result<T, E> { Ok(T), Err(E), } 3574//- minicore: result
3467use Result::*;
3468fn foo() -> Result<(), i64> { 3575fn foo() -> Result<(), i64> {
3469 let n = 1; 3576 let n = 1;
3470 $0let k = foo()?; 3577 $0let k = foo()?;
@@ -3474,10 +3581,9 @@ fn foo() -> Result<(), i64> {
3474 let m = k + 1;$0 3581 let m = k + 1;$0
3475 let h = 1 + m; 3582 let h = 1 + m;
3476 Ok(()) 3583 Ok(())
3477}"##, 3584}
3478 r##" 3585"#,
3479enum Result<T, E> { Ok(T), Err(E), } 3586 r#"
3480use Result::*;
3481fn foo() -> Result<(), i64> { 3587fn foo() -> Result<(), i64> {
3482 let n = 1; 3588 let n = 1;
3483 let m = fun_name()?; 3589 let m = fun_name()?;
@@ -3492,7 +3598,8 @@ fn $0fun_name() -> Result<i32, i64> {
3492 } 3598 }
3493 let m = k + 1; 3599 let m = k + 1;
3494 Ok(m) 3600 Ok(m)
3495}"##, 3601}
3602"#,
3496 ); 3603 );
3497 } 3604 }
3498 3605
@@ -3501,9 +3608,8 @@ fn $0fun_name() -> Result<i32, i64> {
3501 cov_mark::check!(external_control_flow_try_and_bc); 3608 cov_mark::check!(external_control_flow_try_and_bc);
3502 check_assist_not_applicable( 3609 check_assist_not_applicable(
3503 extract_function, 3610 extract_function,
3504 r##" 3611 r#"
3505enum Option<T> { None, Some(T) } 3612//- minicore: option
3506use Option::*;
3507fn foo() -> Option<()> { 3613fn foo() -> Option<()> {
3508 loop { 3614 loop {
3509 let n = Some(1); 3615 let n = Some(1);
@@ -3514,7 +3620,8 @@ fn foo() -> Option<()> {
3514 let r = n + k; 3620 let r = n + k;
3515 } 3621 }
3516 Some(()) 3622 Some(())
3517}"##, 3623}
3624"#,
3518 ); 3625 );
3519 } 3626 }
3520 3627
@@ -3523,9 +3630,8 @@ fn foo() -> Option<()> {
3523 cov_mark::check!(external_control_flow_try_and_return_non_err); 3630 cov_mark::check!(external_control_flow_try_and_return_non_err);
3524 check_assist_not_applicable( 3631 check_assist_not_applicable(
3525 extract_function, 3632 extract_function,
3526 r##" 3633 r#"
3527enum Result<T, E> { Ok(T), Err(E), } 3634//- minicore: result
3528use Result::*;
3529fn foo() -> Result<(), i64> { 3635fn foo() -> Result<(), i64> {
3530 let n = 1; 3636 let n = 1;
3531 $0let k = foo()?; 3637 $0let k = foo()?;
@@ -3535,7 +3641,8 @@ fn foo() -> Result<(), i64> {
3535 let m = k + 1;$0 3641 let m = k + 1;$0
3536 let h = 1 + m; 3642 let h = 1 + m;
3537 Ok(()) 3643 Ok(())
3538}"##, 3644}
3645"#,
3539 ); 3646 );
3540 } 3647 }
3541 3648
@@ -3543,7 +3650,7 @@ fn foo() -> Result<(), i64> {
3543 fn param_usage_in_macro() { 3650 fn param_usage_in_macro() {
3544 check_assist( 3651 check_assist(
3545 extract_function, 3652 extract_function,
3546 r" 3653 r#"
3547macro_rules! m { 3654macro_rules! m {
3548 ($val:expr) => { $val }; 3655 ($val:expr) => { $val };
3549} 3656}
@@ -3552,8 +3659,9 @@ fn foo() {
3552 let n = 1; 3659 let n = 1;
3553 $0let k = n * m!(n);$0 3660 $0let k = n * m!(n);$0
3554 let m = k + 1; 3661 let m = k + 1;
3555}", 3662}
3556 r" 3663"#,
3664 r#"
3557macro_rules! m { 3665macro_rules! m {
3558 ($val:expr) => { $val }; 3666 ($val:expr) => { $val };
3559} 3667}
@@ -3567,7 +3675,8 @@ fn foo() {
3567fn $0fun_name(n: i32) -> i32 { 3675fn $0fun_name(n: i32) -> i32 {
3568 let k = n * m!(n); 3676 let k = n * m!(n);
3569 k 3677 k
3570}", 3678}
3679"#,
3571 ); 3680 );
3572 } 3681 }
3573 3682
@@ -3575,7 +3684,8 @@ fn $0fun_name(n: i32) -> i32 {
3575 fn extract_with_await() { 3684 fn extract_with_await() {
3576 check_assist( 3685 check_assist(
3577 extract_function, 3686 extract_function,
3578 r#"fn main() { 3687 r#"
3688fn main() {
3579 $0some_function().await;$0 3689 $0some_function().await;$0
3580} 3690}
3581 3691
@@ -3585,7 +3695,7 @@ async fn some_function() {
3585"#, 3695"#,
3586 r#" 3696 r#"
3587fn main() { 3697fn main() {
3588 fun_name(); 3698 fun_name().await;
3589} 3699}
3590 3700
3591async fn $0fun_name() { 3701async fn $0fun_name() {
@@ -3603,7 +3713,8 @@ async fn some_function() {
3603 fn extract_with_await_in_args() { 3713 fn extract_with_await_in_args() {
3604 check_assist( 3714 check_assist(
3605 extract_function, 3715 extract_function,
3606 r#"fn main() { 3716 r#"
3717fn main() {
3607 $0function_call("a", some_function().await);$0 3718 $0function_call("a", some_function().await);$0
3608} 3719}
3609 3720
@@ -3613,7 +3724,7 @@ async fn some_function() {
3613"#, 3724"#,
3614 r#" 3725 r#"
3615fn main() { 3726fn main() {
3616 fun_name(); 3727 fun_name().await;
3617} 3728}
3618 3729
3619async fn $0fun_name() { 3730async fn $0fun_name() {
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..430710448 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
@@ -235,7 +236,7 @@ fn apply_references(
235 import: Option<(ImportScope, hir::ModPath)>, 236 import: Option<(ImportScope, hir::ModPath)>,
236) { 237) {
237 if let Some((scope, path)) = import { 238 if let Some((scope, path)) = import {
238 insert_use(&scope, mod_path_to_ast(&path), insert_use_cfg); 239 insert_use(&scope, mod_path_to_ast(&path), &insert_use_cfg);
239 } 240 }
240 // deep clone to prevent cycle 241 // deep clone to prevent cycle
241 let path = make::path_from_segments(iter::once(segment.clone_subtree()), false); 242 let path = make::path_from_segments(iter::once(segment.clone_subtree()), false);
@@ -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/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index 5a43bdd6f..318faa0fc 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -278,8 +278,6 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: ExtendedVariant) -> Op
278 278
279#[cfg(test)] 279#[cfg(test)]
280mod tests { 280mod tests {
281 use ide_db::helpers::FamousDefs;
282
283 use crate::tests::{ 281 use crate::tests::{
284 check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved, 282 check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved,
285 }; 283 };
@@ -483,26 +481,21 @@ fn main() {
483 check_assist( 481 check_assist(
484 fill_match_arms, 482 fill_match_arms,
485 r#" 483 r#"
486enum Option<T> { Some(T), None } 484//- minicore: option
487use Option::*;
488
489fn main() { 485fn main() {
490 match None$0 { 486 match None$0 {
491 None => {} 487 None => {}
492 } 488 }
493} 489}
494 "#, 490"#,
495 r#" 491 r#"
496enum Option<T> { Some(T), None }
497use Option::*;
498
499fn main() { 492fn main() {
500 match None { 493 match None {
501 None => {} 494 None => {}
502 Some(${0:_}) => todo!(), 495 Some(${0:_}) => todo!(),
503 } 496 }
504} 497}
505 "#, 498"#,
506 ); 499 );
507 } 500 }
508 501
@@ -716,7 +709,10 @@ fn main() {
716 709
717 #[test] 710 #[test]
718 fn fill_match_arms_tuple_of_enum_partial_with_wildcards() { 711 fn fill_match_arms_tuple_of_enum_partial_with_wildcards() {
719 let ra_fixture = r#" 712 check_assist(
713 fill_match_arms,
714 r#"
715//- minicore: option
720fn main() { 716fn main() {
721 let a = Some(1); 717 let a = Some(1);
722 let b = Some(()); 718 let b = Some(());
@@ -725,10 +721,7 @@ fn main() {
725 (None, Some(_)) => {} 721 (None, Some(_)) => {}
726 } 722 }
727} 723}
728"#; 724"#,
729 check_assist(
730 fill_match_arms,
731 &format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
732 r#" 725 r#"
733fn main() { 726fn main() {
734 let a = Some(1); 727 let a = Some(1);
@@ -746,17 +739,17 @@ fn main() {
746 #[test] 739 #[test]
747 fn fill_match_arms_partial_with_deep_pattern() { 740 fn fill_match_arms_partial_with_deep_pattern() {
748 // Fixme: cannot handle deep patterns 741 // Fixme: cannot handle deep patterns
749 let ra_fixture = r#" 742 check_assist_not_applicable(
743 fill_match_arms,
744 r#"
745//- minicore: option
750fn main() { 746fn main() {
751 match $0Some(true) { 747 match $0Some(true) {
752 Some(true) => {} 748 Some(true) => {}
753 None => {} 749 None => {}
754 } 750 }
755} 751}
756"#; 752"#,
757 check_assist_not_applicable(
758 fill_match_arms,
759 &format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE),
760 ); 753 );
761 } 754 }
762 755
@@ -1007,17 +1000,15 @@ fn foo(a: A) {
1007 #[test] 1000 #[test]
1008 fn option_order() { 1001 fn option_order() {
1009 cov_mark::check!(option_order); 1002 cov_mark::check!(option_order);
1010 let before = r#" 1003 check_assist(
1004 fill_match_arms,
1005 r#"
1006//- minicore: option
1011fn foo(opt: Option<i32>) { 1007fn foo(opt: Option<i32>) {
1012 match opt$0 { 1008 match opt$0 {
1013 } 1009 }
1014} 1010}
1015"#; 1011"#,
1016 let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
1017
1018 check_assist(
1019 fill_match_arms,
1020 before,
1021 r#" 1012 r#"
1022fn foo(opt: Option<i32>) { 1013fn foo(opt: Option<i32>) {
1023 match opt { 1014 match opt {
diff --git a/crates/ide_assists/src/handlers/fix_visibility.rs b/crates/ide_assists/src/handlers/fix_visibility.rs
index 9b432e92f..f834bf16a 100644
--- a/crates/ide_assists/src/handlers/fix_visibility.rs
+++ b/crates/ide_assists/src/handlers/fix_visibility.rs
@@ -361,8 +361,6 @@ pub struct Foo { pub bar: () }
361 } 361 }
362 362
363 #[test] 363 #[test]
364 #[ignore]
365 // FIXME reenable this test when `Semantics::resolve_record_field` works with union fields
366 fn fix_visibility_of_union_field() { 364 fn fix_visibility_of_union_field() {
367 check_assist( 365 check_assist(
368 fix_visibility, 366 fix_visibility,
@@ -583,25 +581,25 @@ pub struct Foo { pub(crate) bar: () }
583 } 581 }
584 582
585 #[test] 583 #[test]
586 #[ignore]
587 // FIXME handle reexports properly
588 fn fix_visibility_of_reexport() { 584 fn fix_visibility_of_reexport() {
585 // FIXME: broken test, this should fix visibility of the re-export
586 // rather than the struct.
589 check_assist( 587 check_assist(
590 fix_visibility, 588 fix_visibility,
591 r" 589 r#"
592 mod foo { 590mod foo {
593 use bar::Baz; 591 use bar::Baz;
594 mod bar { pub(super) struct Baz; } 592 mod bar { pub(super) struct Baz; }
595 } 593}
596 foo::Baz$0 594foo::Baz$0
597 ", 595"#,
598 r" 596 r#"
599 mod foo { 597mod foo {
600 $0pub(crate) use bar::Baz; 598 use bar::Baz;
601 mod bar { pub(super) struct Baz; } 599 mod bar { $0pub(crate) struct Baz; }
602 } 600}
603 foo::Baz 601foo::Baz
604 ", 602"#,
605 ) 603 )
606 } 604 }
607} 605}
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_deref.rs b/crates/ide_assists/src/handlers/generate_deref.rs
index 4998ff7a4..4e10fdb85 100644
--- a/crates/ide_assists/src/handlers/generate_deref.rs
+++ b/crates/ide_assists/src/handlers/generate_deref.rs
@@ -182,23 +182,17 @@ impl std::ops::Deref for B {
182 ); 182 );
183 } 183 }
184 184
185 fn check_not_applicable(ra_fixture: &str) {
186 let fixture = format!(
187 "//- /main.rs crate:main deps:core,std\n{}\n{}",
188 ra_fixture,
189 FamousDefs::FIXTURE
190 );
191 check_assist_not_applicable(generate_deref, &fixture)
192 }
193
194 #[test] 185 #[test]
195 fn test_generate_record_deref_not_applicable_if_already_impl() { 186 fn test_generate_record_deref_not_applicable_if_already_impl() {
196 cov_mark::check!(test_add_record_deref_impl_already_exists); 187 cov_mark::check!(test_add_record_deref_impl_already_exists);
197 check_not_applicable( 188 check_assist_not_applicable(
198 r#"struct A { } 189 generate_deref,
190 r#"
191//- minicore: deref
192struct A { }
199struct B { $0a: A } 193struct B { $0a: A }
200 194
201impl std::ops::Deref for B { 195impl core::ops::Deref for B {
202 type Target = A; 196 type Target = A;
203 197
204 fn deref(&self) -> &Self::Target { 198 fn deref(&self) -> &Self::Target {
@@ -211,11 +205,14 @@ impl std::ops::Deref for B {
211 #[test] 205 #[test]
212 fn test_generate_field_deref_not_applicable_if_already_impl() { 206 fn test_generate_field_deref_not_applicable_if_already_impl() {
213 cov_mark::check!(test_add_field_deref_impl_already_exists); 207 cov_mark::check!(test_add_field_deref_impl_already_exists);
214 check_not_applicable( 208 check_assist_not_applicable(
215 r#"struct A { } 209 generate_deref,
210 r#"
211//- minicore: deref
212struct A { }
216struct B($0A) 213struct B($0A)
217 214
218impl std::ops::Deref for B { 215impl core::ops::Deref for B {
219 type Target = A; 216 type Target = A;
220 217
221 fn deref(&self) -> &Self::Target { 218 fn deref(&self) -> &Self::Target {
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/generate_function.rs b/crates/ide_assists/src/handlers/generate_function.rs
index 706c995ac..6a658d4cf 100644
--- a/crates/ide_assists/src/handlers/generate_function.rs
+++ b/crates/ide_assists/src/handlers/generate_function.rs
@@ -811,9 +811,8 @@ fn bar(baz: Baz::Bof) ${0:-> ()} {
811 } 811 }
812 812
813 #[test] 813 #[test]
814 #[ignore]
815 // FIXME fix printing the generics of a `Ty` to make this test pass
816 fn add_function_with_generic_arg() { 814 fn add_function_with_generic_arg() {
815 // FIXME: This is wrong, generated `bar` should include generic parameter.
817 check_assist( 816 check_assist(
818 generate_function, 817 generate_function,
819 r" 818 r"
@@ -826,7 +825,7 @@ fn foo<T>(t: T) {
826 bar(t) 825 bar(t)
827} 826}
828 827
829fn bar<T>(t: T) ${0:-> ()} { 828fn bar(t: T) ${0:-> ()} {
830 todo!() 829 todo!()
831} 830}
832", 831",
@@ -834,9 +833,8 @@ fn bar<T>(t: T) ${0:-> ()} {
834 } 833 }
835 834
836 #[test] 835 #[test]
837 #[ignore]
838 // FIXME Fix function type printing to make this test pass
839 fn add_function_with_fn_arg() { 836 fn add_function_with_fn_arg() {
837 // FIXME: The argument in `bar` is wrong.
840 check_assist( 838 check_assist(
841 generate_function, 839 generate_function,
842 r" 840 r"
@@ -857,7 +855,7 @@ fn foo() {
857 bar(Baz::new); 855 bar(Baz::new);
858} 856}
859 857
860fn bar(arg: fn() -> Baz) ${0:-> ()} { 858fn bar(new: fn) ${0:-> ()} {
861 todo!() 859 todo!()
862} 860}
863", 861",
@@ -865,9 +863,8 @@ fn bar(arg: fn() -> Baz) ${0:-> ()} {
865 } 863 }
866 864
867 #[test] 865 #[test]
868 #[ignore]
869 // FIXME Fix closure type printing to make this test pass
870 fn add_function_with_closure_arg() { 866 fn add_function_with_closure_arg() {
867 // FIXME: The argument in `bar` is wrong.
871 check_assist( 868 check_assist(
872 generate_function, 869 generate_function,
873 r" 870 r"
@@ -882,7 +879,7 @@ fn foo() {
882 bar(closure) 879 bar(closure)
883} 880}
884 881
885fn bar(closure: impl Fn(i64) -> i64) ${0:-> ()} { 882fn bar(closure: ()) ${0:-> ()} {
886 todo!() 883 todo!()
887} 884}
888", 885",
@@ -986,13 +983,10 @@ fn foo() {
986 } 983 }
987 984
988 #[test] 985 #[test]
989 #[ignore]
990 // Ignored until local imports are supported.
991 // See https://github.com/rust-analyzer/rust-analyzer/issues/1165
992 fn qualified_path_uses_correct_scope() { 986 fn qualified_path_uses_correct_scope() {
993 check_assist( 987 check_assist(
994 generate_function, 988 generate_function,
995 " 989 r#"
996mod foo { 990mod foo {
997 pub struct Foo; 991 pub struct Foo;
998} 992}
@@ -1001,8 +995,8 @@ fn bar() {
1001 let foo = Foo; 995 let foo = Foo;
1002 baz$0(foo) 996 baz$0(foo)
1003} 997}
1004", 998"#,
1005 " 999 r#"
1006mod foo { 1000mod foo {
1007 pub struct Foo; 1001 pub struct Foo;
1008} 1002}
@@ -1015,7 +1009,7 @@ fn bar() {
1015fn baz(foo: foo::Foo) ${0:-> ()} { 1009fn baz(foo: foo::Foo) ${0:-> ()} {
1016 todo!() 1010 todo!()
1017} 1011}
1018", 1012"#,
1019 ) 1013 )
1020 } 1014 }
1021 1015
@@ -1141,40 +1135,29 @@ fn bar() {}
1141 // The assist is only active if the cursor is on an unresolved path, 1135 // The assist is only active if the cursor is on an unresolved path,
1142 // but the assist should only be offered if the path is a function call. 1136 // but the assist should only be offered if the path is a function call.
1143 generate_function, 1137 generate_function,
1144 r" 1138 r#"
1145fn foo() { 1139fn foo() {
1146 bar(b$0az); 1140 bar(b$0az);
1147} 1141}
1148 1142
1149fn bar(baz: ()) {} 1143fn bar(baz: ()) {}
1150", 1144"#,
1151 ) 1145 )
1152 } 1146 }
1153 1147
1154 #[test] 1148 #[test]
1155 #[ignore]
1156 fn create_method_with_no_args() { 1149 fn create_method_with_no_args() {
1157 check_assist( 1150 // FIXME: This is wrong, this should just work.
1151 check_assist_not_applicable(
1158 generate_function, 1152 generate_function,
1159 r" 1153 r#"
1160struct Foo; 1154struct Foo;
1161impl Foo { 1155impl Foo {
1162 fn foo(&self) { 1156 fn foo(&self) {
1163 self.bar()$0; 1157 self.bar()$0;
1164 } 1158 }
1165} 1159}
1166 ", 1160 "#,
1167 r"
1168struct Foo;
1169impl Foo {
1170 fn foo(&self) {
1171 self.bar();
1172 }
1173 fn bar(&self) {
1174 todo!();
1175 }
1176}
1177 ",
1178 ) 1161 )
1179 } 1162 }
1180} 1163}
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/handlers/move_module_to_file.rs b/crates/ide_assists/src/handlers/move_module_to_file.rs
index 93f702c55..cfc54be8d 100644
--- a/crates/ide_assists/src/handlers/move_module_to_file.rs
+++ b/crates/ide_assists/src/handlers/move_module_to_file.rs
@@ -1,5 +1,8 @@
1use std::iter;
2
1use ast::edit::IndentLevel; 3use ast::edit::IndentLevel;
2use ide_db::base_db::AnchoredPathBuf; 4use ide_db::base_db::AnchoredPathBuf;
5use itertools::Itertools;
3use stdx::format_to; 6use stdx::format_to;
4use syntax::{ 7use syntax::{
5 ast::{self, edit::AstNodeEdit, NameOwner}, 8 ast::{self, edit::AstNodeEdit, NameOwner},
@@ -34,7 +37,10 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt
34 37
35 let module_name = module_ast.name()?; 38 let module_name = module_ast.name()?;
36 39
37 let module_def = ctx.sema.to_def(&module_ast)?; 40 // get to the outermost module syntax so we can grab the module of file we are in
41 let outermost_mod_decl =
42 iter::successors(Some(module_ast.clone()), |module| module.parent()).last()?;
43 let module_def = ctx.sema.to_def(&outermost_mod_decl)?;
38 let parent_module = module_def.parent(ctx.db())?; 44 let parent_module = module_def.parent(ctx.db())?;
39 45
40 acc.add( 46 acc.add(
@@ -43,11 +49,19 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt
43 target, 49 target,
44 |builder| { 50 |builder| {
45 let path = { 51 let path = {
46 let dir = match parent_module.name(ctx.db()) { 52 let mut buf = String::from("./");
47 Some(name) if !parent_module.is_mod_rs(ctx.db()) => format!("{}/", name), 53 match parent_module.name(ctx.db()) {
48 _ => String::new(), 54 Some(name) if !parent_module.is_mod_rs(ctx.db()) => {
49 }; 55 format_to!(buf, "{}/", name)
50 format!("./{}{}.rs", dir, module_name) 56 }
57 _ => (),
58 }
59 let segments = iter::successors(Some(module_ast.clone()), |module| module.parent())
60 .filter_map(|it| it.name())
61 .collect::<Vec<_>>();
62 format_to!(buf, "{}", segments.into_iter().rev().format("/"));
63 format_to!(buf, ".rs");
64 buf
51 }; 65 };
52 let contents = { 66 let contents = {
53 let items = module_items.dedent(IndentLevel(1)).to_string(); 67 let items = module_items.dedent(IndentLevel(1)).to_string();
@@ -59,14 +73,13 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt
59 items 73 items
60 }; 74 };
61 75
62 let mut buf = String::new(); 76 let buf = format!("mod {};", module_name);
63 format_to!(buf, "mod {};", module_name);
64 77
65 let replacement_start = if let Some(mod_token) = module_ast.mod_token() { 78 let replacement_start = match module_ast.mod_token() {
66 mod_token.text_range().start() 79 Some(mod_token) => mod_token.text_range(),
67 } else { 80 None => module_ast.syntax().text_range(),
68 module_ast.syntax().text_range().start() 81 }
69 }; 82 .start();
70 83
71 builder.replace( 84 builder.replace(
72 TextRange::new(replacement_start, module_ast.syntax().text_range().end()), 85 TextRange::new(replacement_start, module_ast.syntax().text_range().end()),
@@ -212,4 +225,30 @@ mod tests;
212"#, 225"#,
213 ); 226 );
214 } 227 }
228
229 #[test]
230 fn extract_nested() {
231 check_assist(
232 move_module_to_file,
233 r#"
234//- /lib.rs
235mod foo;
236//- /foo.rs
237mod bar {
238 mod baz {
239 mod qux$0 {}
240 }
241}
242"#,
243 r#"
244//- /foo.rs
245mod bar {
246 mod baz {
247 mod qux;
248 }
249}
250//- /foo/bar/baz/qux.rs
251"#,
252 );
253 }
215} 254}
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs
index f91770a76..1d7be183a 100644
--- a/crates/ide_assists/src/handlers/qualify_path.rs
+++ b/crates/ide_assists/src/handlers/qualify_path.rs
@@ -216,28 +216,28 @@ mod tests {
216 cov_mark::check!(qualify_path_unqualified_name); 216 cov_mark::check!(qualify_path_unqualified_name);
217 check_assist( 217 check_assist(
218 qualify_path, 218 qualify_path,
219 r" 219 r#"
220 mod std { 220mod std {
221 pub mod fmt { 221 pub mod fmt {
222 pub struct Formatter; 222 pub struct Formatter;
223 } 223 }
224 } 224}
225 225
226 use std::fmt; 226use std::fmt;
227 227
228 $0Formatter 228$0Formatter
229 ", 229"#,
230 r" 230 r#"
231 mod std { 231mod std {
232 pub mod fmt { 232 pub mod fmt {
233 pub struct Formatter; 233 pub struct Formatter;
234 } 234 }
235 } 235}
236 236
237 use std::fmt; 237use std::fmt;
238 238
239 fmt::Formatter 239fmt::Formatter
240 ", 240"#,
241 ); 241 );
242 } 242 }
243 243
@@ -245,20 +245,20 @@ mod tests {
245 fn applicable_when_found_an_import() { 245 fn applicable_when_found_an_import() {
246 check_assist( 246 check_assist(
247 qualify_path, 247 qualify_path,
248 r" 248 r#"
249 $0PubStruct 249$0PubStruct
250 250
251 pub mod PubMod { 251pub mod PubMod {
252 pub struct PubStruct; 252 pub struct PubStruct;
253 } 253}
254 ", 254"#,
255 r" 255 r#"
256 PubMod::PubStruct 256PubMod::PubStruct
257 257
258 pub mod PubMod { 258pub mod PubMod {
259 pub struct PubStruct; 259 pub struct PubStruct;
260 } 260}
261 ", 261"#,
262 ); 262 );
263 } 263 }
264 264
@@ -266,26 +266,26 @@ mod tests {
266 fn applicable_in_macros() { 266 fn applicable_in_macros() {
267 check_assist( 267 check_assist(
268 qualify_path, 268 qualify_path,
269 r" 269 r#"
270 macro_rules! foo { 270macro_rules! foo {
271 ($i:ident) => { fn foo(a: $i) {} } 271 ($i:ident) => { fn foo(a: $i) {} }
272 } 272}
273 foo!(Pub$0Struct); 273foo!(Pub$0Struct);
274 274
275 pub mod PubMod { 275pub mod PubMod {
276 pub struct PubStruct; 276 pub struct PubStruct;
277 } 277}
278 ", 278"#,
279 r" 279 r#"
280 macro_rules! foo { 280macro_rules! foo {
281 ($i:ident) => { fn foo(a: $i) {} } 281 ($i:ident) => { fn foo(a: $i) {} }
282 } 282}
283 foo!(PubMod::PubStruct); 283foo!(PubMod::PubStruct);
284 284
285 pub mod PubMod { 285pub mod PubMod {
286 pub struct PubStruct; 286 pub struct PubStruct;
287 } 287}
288 ", 288"#,
289 ); 289 );
290 } 290 }
291 291
@@ -293,32 +293,32 @@ mod tests {
293 fn applicable_when_found_multiple_imports() { 293 fn applicable_when_found_multiple_imports() {
294 check_assist( 294 check_assist(
295 qualify_path, 295 qualify_path,
296 r" 296 r#"
297 PubSt$0ruct 297PubSt$0ruct
298 298
299 pub mod PubMod1 { 299pub mod PubMod1 {
300 pub struct PubStruct; 300 pub struct PubStruct;
301 } 301}
302 pub mod PubMod2 { 302pub mod PubMod2 {
303 pub struct PubStruct; 303 pub struct PubStruct;
304 } 304}
305 pub mod PubMod3 { 305pub mod PubMod3 {
306 pub struct PubStruct; 306 pub struct PubStruct;
307 } 307}
308 ", 308"#,
309 r" 309 r#"
310 PubMod3::PubStruct 310PubMod3::PubStruct
311 311
312 pub mod PubMod1 { 312pub mod PubMod1 {
313 pub struct PubStruct; 313 pub struct PubStruct;
314 } 314}
315 pub mod PubMod2 { 315pub mod PubMod2 {
316 pub struct PubStruct; 316 pub struct PubStruct;
317 } 317}
318 pub mod PubMod3 { 318pub mod PubMod3 {
319 pub struct PubStruct; 319 pub struct PubStruct;
320 } 320}
321 ", 321"#,
322 ); 322 );
323 } 323 }
324 324
@@ -326,15 +326,15 @@ mod tests {
326 fn not_applicable_for_already_imported_types() { 326 fn not_applicable_for_already_imported_types() {
327 check_assist_not_applicable( 327 check_assist_not_applicable(
328 qualify_path, 328 qualify_path,
329 r" 329 r#"
330 use PubMod::PubStruct; 330use PubMod::PubStruct;
331 331
332 PubStruct$0 332PubStruct$0
333 333
334 pub mod PubMod { 334pub mod PubMod {
335 pub struct PubStruct; 335 pub struct PubStruct;
336 } 336}
337 ", 337"#,
338 ); 338 );
339 } 339 }
340 340
@@ -342,35 +342,32 @@ mod tests {
342 fn not_applicable_for_types_with_private_paths() { 342 fn not_applicable_for_types_with_private_paths() {
343 check_assist_not_applicable( 343 check_assist_not_applicable(
344 qualify_path, 344 qualify_path,
345 r" 345 r#"
346 PrivateStruct$0 346PrivateStruct$0
347 347
348 pub mod PubMod { 348pub mod PubMod {
349 struct PrivateStruct; 349 struct PrivateStruct;
350 } 350}
351 ", 351"#,
352 ); 352 );
353 } 353 }
354 354
355 #[test] 355 #[test]
356 fn not_applicable_when_no_imports_found() { 356 fn not_applicable_when_no_imports_found() {
357 check_assist_not_applicable( 357 check_assist_not_applicable(qualify_path, r#"PubStruct$0"#);
358 qualify_path,
359 "
360 PubStruct$0",
361 );
362 } 358 }
363 359
364 #[test] 360 #[test]
365 fn not_applicable_in_import_statements() { 361 fn not_applicable_in_import_statements() {
366 check_assist_not_applicable( 362 check_assist_not_applicable(
367 qualify_path, 363 qualify_path,
368 r" 364 r#"
369 use PubStruct$0; 365use PubStruct$0;
370 366
371 pub mod PubMod { 367pub mod PubMod {
372 pub struct PubStruct; 368 pub struct PubStruct;
373 }", 369}
370"#,
374 ); 371 );
375 } 372 }
376 373
@@ -378,20 +375,20 @@ mod tests {
378 fn qualify_function() { 375 fn qualify_function() {
379 check_assist( 376 check_assist(
380 qualify_path, 377 qualify_path,
381 r" 378 r#"
382 test_function$0 379test_function$0
383 380
384 pub mod PubMod { 381pub mod PubMod {
385 pub fn test_function() {}; 382 pub fn test_function() {};
386 } 383}
387 ", 384"#,
388 r" 385 r#"
389 PubMod::test_function 386PubMod::test_function
390 387
391 pub mod PubMod { 388pub mod PubMod {
392 pub fn test_function() {}; 389 pub fn test_function() {};
393 } 390}
394 ", 391"#,
395 ); 392 );
396 } 393 }
397 394
@@ -399,7 +396,7 @@ mod tests {
399 fn qualify_macro() { 396 fn qualify_macro() {
400 check_assist( 397 check_assist(
401 qualify_path, 398 qualify_path,
402 r" 399 r#"
403//- /lib.rs crate:crate_with_macro 400//- /lib.rs crate:crate_with_macro
404#[macro_export] 401#[macro_export]
405macro_rules! foo { 402macro_rules! foo {
@@ -410,12 +407,12 @@ macro_rules! foo {
410fn main() { 407fn main() {
411 foo$0 408 foo$0
412} 409}
413", 410"#,
414 r" 411 r#"
415fn main() { 412fn main() {
416 crate_with_macro::foo 413 crate_with_macro::foo
417} 414}
418", 415"#,
419 ); 416 );
420 } 417 }
421 418
@@ -423,13 +420,13 @@ fn main() {
423 fn qualify_path_target() { 420 fn qualify_path_target() {
424 check_assist_target( 421 check_assist_target(
425 qualify_path, 422 qualify_path,
426 r" 423 r#"
427 struct AssistInfo { 424struct AssistInfo {
428 group_label: Option<$0GroupLabel>, 425 group_label: Option<$0GroupLabel>,
429 } 426}
430 427
431 mod m { pub struct GroupLabel; } 428mod m { pub struct GroupLabel; }
432 ", 429"#,
433 "GroupLabel", 430 "GroupLabel",
434 ) 431 )
435 } 432 }
@@ -438,20 +435,20 @@ fn main() {
438 fn not_applicable_when_path_start_is_imported() { 435 fn not_applicable_when_path_start_is_imported() {
439 check_assist_not_applicable( 436 check_assist_not_applicable(
440 qualify_path, 437 qualify_path,
441 r" 438 r#"
442 pub mod mod1 { 439pub mod mod1 {
443 pub mod mod2 { 440 pub mod mod2 {
444 pub mod mod3 { 441 pub mod mod3 {
445 pub struct TestStruct; 442 pub struct TestStruct;
446 } 443 }
447 } 444 }
448 } 445}
449 446
450 use mod1::mod2; 447use mod1::mod2;
451 fn main() { 448fn main() {
452 mod2::mod3::TestStruct$0 449 mod2::mod3::TestStruct$0
453 } 450}
454 ", 451"#,
455 ); 452 );
456 } 453 }
457 454
@@ -459,16 +456,16 @@ fn main() {
459 fn not_applicable_for_imported_function() { 456 fn not_applicable_for_imported_function() {
460 check_assist_not_applicable( 457 check_assist_not_applicable(
461 qualify_path, 458 qualify_path,
462 r" 459 r#"
463 pub mod test_mod { 460pub mod test_mod {
464 pub fn test_function() {} 461 pub fn test_function() {}
465 } 462}
466 463
467 use test_mod::test_function; 464use test_mod::test_function;
468 fn main() { 465fn main() {
469 test_function$0 466 test_function$0
470 } 467}
471 ", 468"#,
472 ); 469 );
473 } 470 }
474 471
@@ -476,30 +473,30 @@ fn main() {
476 fn associated_struct_function() { 473 fn associated_struct_function() {
477 check_assist( 474 check_assist(
478 qualify_path, 475 qualify_path,
479 r" 476 r#"
480 mod test_mod { 477mod test_mod {
481 pub struct TestStruct {} 478 pub struct TestStruct {}
482 impl TestStruct { 479 impl TestStruct {
483 pub fn test_function() {} 480 pub fn test_function() {}
484 } 481 }
485 } 482}
486 483
487 fn main() { 484fn main() {
488 TestStruct::test_function$0 485 TestStruct::test_function$0
489 } 486}
490 ", 487"#,
491 r" 488 r#"
492 mod test_mod { 489mod test_mod {
493 pub struct TestStruct {} 490 pub struct TestStruct {}
494 impl TestStruct { 491 impl TestStruct {
495 pub fn test_function() {} 492 pub fn test_function() {}
496 } 493 }
497 } 494}
498 495
499 fn main() { 496fn main() {
500 test_mod::TestStruct::test_function 497 test_mod::TestStruct::test_function
501 } 498}
502 ", 499"#,
503 ); 500 );
504 } 501 }
505 502
@@ -508,62 +505,50 @@ fn main() {
508 cov_mark::check!(qualify_path_qualifier_start); 505 cov_mark::check!(qualify_path_qualifier_start);
509 check_assist( 506 check_assist(
510 qualify_path, 507 qualify_path,
511 r" 508 r#"
512 mod test_mod { 509mod test_mod {
513 pub struct TestStruct {} 510 pub struct TestStruct {}
514 impl TestStruct { 511 impl TestStruct {
515 const TEST_CONST: u8 = 42; 512 const TEST_CONST: u8 = 42;
516 } 513 }
517 } 514}
518 515
519 fn main() { 516fn main() {
520 TestStruct::TEST_CONST$0 517 TestStruct::TEST_CONST$0
521 } 518}
522 ", 519"#,
523 r" 520 r#"
524 mod test_mod { 521mod test_mod {
525 pub struct TestStruct {} 522 pub struct TestStruct {}
526 impl TestStruct { 523 impl TestStruct {
527 const TEST_CONST: u8 = 42; 524 const TEST_CONST: u8 = 42;
528 } 525 }
529 } 526}
530 527
531 fn main() { 528fn main() {
532 test_mod::TestStruct::TEST_CONST 529 test_mod::TestStruct::TEST_CONST
533 } 530}
534 ", 531"#,
535 ); 532 );
536 } 533 }
537 534
538 #[test] 535 #[test]
539 #[ignore = "FIXME: non-trait assoc items completion is unsupported yet, see FIXME in the import_assets.rs for more details"]
540 fn associated_struct_const_unqualified() { 536 fn associated_struct_const_unqualified() {
541 check_assist( 537 // FIXME: non-trait assoc items completion is unsupported yet, see FIXME in the import_assets.rs for more details
538 check_assist_not_applicable(
542 qualify_path, 539 qualify_path,
543 r" 540 r#"
544 mod test_mod { 541mod test_mod {
545 pub struct TestStruct {} 542 pub struct TestStruct {}
546 impl TestStruct { 543 impl TestStruct {
547 const TEST_CONST: u8 = 42; 544 const TEST_CONST: u8 = 42;
548 } 545 }
549 } 546}
550
551 fn main() {
552 TEST_CONST$0
553 }
554 ",
555 r"
556 mod test_mod {
557 pub struct TestStruct {}
558 impl TestStruct {
559 const TEST_CONST: u8 = 42;
560 }
561 }
562 547
563 fn main() { 548fn main() {
564 test_mod::TestStruct::TEST_CONST 549 TEST_CONST$0
565 } 550}
566 ", 551"#,
567 ); 552 );
568 } 553 }
569 554
@@ -571,36 +556,36 @@ fn main() {
571 fn associated_trait_function() { 556 fn associated_trait_function() {
572 check_assist( 557 check_assist(
573 qualify_path, 558 qualify_path,
574 r" 559 r#"
575 mod test_mod { 560mod test_mod {
576 pub trait TestTrait { 561 pub trait TestTrait {
577 fn test_function(); 562 fn test_function();
578 } 563 }
579 pub struct TestStruct {} 564 pub struct TestStruct {}
580 impl TestTrait for TestStruct { 565 impl TestTrait for TestStruct {
581 fn test_function() {} 566 fn test_function() {}
582 } 567 }
583 } 568}
584 569
585 fn main() { 570fn main() {
586 test_mod::TestStruct::test_function$0 571 test_mod::TestStruct::test_function$0
587 } 572}
588 ", 573"#,
589 r" 574 r#"
590 mod test_mod { 575mod test_mod {
591 pub trait TestTrait { 576 pub trait TestTrait {
592 fn test_function(); 577 fn test_function();
593 } 578 }
594 pub struct TestStruct {} 579 pub struct TestStruct {}
595 impl TestTrait for TestStruct { 580 impl TestTrait for TestStruct {
596 fn test_function() {} 581 fn test_function() {}
597 } 582 }
598 } 583}
599 584
600 fn main() { 585fn main() {
601 <test_mod::TestStruct as test_mod::TestTrait>::test_function 586 <test_mod::TestStruct as test_mod::TestTrait>::test_function
602 } 587}
603 ", 588"#,
604 ); 589 );
605 } 590 }
606 591
@@ -608,31 +593,31 @@ fn main() {
608 fn not_applicable_for_imported_trait_for_function() { 593 fn not_applicable_for_imported_trait_for_function() {
609 check_assist_not_applicable( 594 check_assist_not_applicable(
610 qualify_path, 595 qualify_path,
611 r" 596 r#"
612 mod test_mod { 597mod test_mod {
613 pub trait TestTrait { 598 pub trait TestTrait {
614 fn test_function(); 599 fn test_function();
615 } 600 }
616 pub trait TestTrait2 { 601 pub trait TestTrait2 {
617 fn test_function(); 602 fn test_function();
618 } 603 }
619 pub enum TestEnum { 604 pub enum TestEnum {
620 One, 605 One,
621 Two, 606 Two,
622 } 607 }
623 impl TestTrait2 for TestEnum { 608 impl TestTrait2 for TestEnum {
624 fn test_function() {} 609 fn test_function() {}
625 } 610 }
626 impl TestTrait for TestEnum { 611 impl TestTrait for TestEnum {
627 fn test_function() {} 612 fn test_function() {}
628 } 613 }
629 } 614}
630 615
631 use test_mod::TestTrait2; 616use test_mod::TestTrait2;
632 fn main() { 617fn main() {
633 test_mod::TestEnum::test_function$0; 618 test_mod::TestEnum::test_function$0;
634 } 619}
635 ", 620"#,
636 ) 621 )
637 } 622 }
638 623
@@ -641,36 +626,36 @@ fn main() {
641 cov_mark::check!(qualify_path_trait_assoc_item); 626 cov_mark::check!(qualify_path_trait_assoc_item);
642 check_assist( 627 check_assist(
643 qualify_path, 628 qualify_path,
644 r" 629 r#"
645 mod test_mod { 630mod test_mod {
646 pub trait TestTrait { 631 pub trait TestTrait {
647 const TEST_CONST: u8; 632 const TEST_CONST: u8;
648 } 633 }
649 pub struct TestStruct {} 634 pub struct TestStruct {}
650 impl TestTrait for TestStruct { 635 impl TestTrait for TestStruct {
651 const TEST_CONST: u8 = 42; 636 const TEST_CONST: u8 = 42;
652 } 637 }
653 } 638}
654 639
655 fn main() { 640fn main() {
656 test_mod::TestStruct::TEST_CONST$0 641 test_mod::TestStruct::TEST_CONST$0
657 } 642}
658 ", 643"#,
659 r" 644 r#"
660 mod test_mod { 645mod test_mod {
661 pub trait TestTrait { 646 pub trait TestTrait {
662 const TEST_CONST: u8; 647 const TEST_CONST: u8;
663 } 648 }
664 pub struct TestStruct {} 649 pub struct TestStruct {}
665 impl TestTrait for TestStruct { 650 impl TestTrait for TestStruct {
666 const TEST_CONST: u8 = 42; 651 const TEST_CONST: u8 = 42;
667 } 652 }
668 } 653}
669 654
670 fn main() { 655fn main() {
671 <test_mod::TestStruct as test_mod::TestTrait>::TEST_CONST 656 <test_mod::TestStruct as test_mod::TestTrait>::TEST_CONST
672 } 657}
673 ", 658"#,
674 ); 659 );
675 } 660 }
676 661
@@ -678,31 +663,31 @@ fn main() {
678 fn not_applicable_for_imported_trait_for_const() { 663 fn not_applicable_for_imported_trait_for_const() {
679 check_assist_not_applicable( 664 check_assist_not_applicable(
680 qualify_path, 665 qualify_path,
681 r" 666 r#"
682 mod test_mod { 667mod test_mod {
683 pub trait TestTrait { 668 pub trait TestTrait {
684 const TEST_CONST: u8; 669 const TEST_CONST: u8;
685 } 670 }
686 pub trait TestTrait2 { 671 pub trait TestTrait2 {
687 const TEST_CONST: f64; 672 const TEST_CONST: f64;
688 } 673 }
689 pub enum TestEnum { 674 pub enum TestEnum {
690 One, 675 One,
691 Two, 676 Two,
692 } 677 }
693 impl TestTrait2 for TestEnum { 678 impl TestTrait2 for TestEnum {
694 const TEST_CONST: f64 = 42.0; 679 const TEST_CONST: f64 = 42.0;
695 } 680 }
696 impl TestTrait for TestEnum { 681 impl TestTrait for TestEnum {
697 const TEST_CONST: u8 = 42; 682 const TEST_CONST: u8 = 42;
698 } 683 }
699 } 684}
700 685
701 use test_mod::TestTrait2; 686use test_mod::TestTrait2;
702 fn main() { 687fn main() {
703 test_mod::TestEnum::TEST_CONST$0; 688 test_mod::TestEnum::TEST_CONST$0;
704 } 689}
705 ", 690"#,
706 ) 691 )
707 } 692 }
708 693
@@ -711,38 +696,38 @@ fn main() {
711 cov_mark::check!(qualify_path_trait_method); 696 cov_mark::check!(qualify_path_trait_method);
712 check_assist( 697 check_assist(
713 qualify_path, 698 qualify_path,
714 r" 699 r#"
715 mod test_mod { 700mod test_mod {
716 pub trait TestTrait { 701 pub trait TestTrait {
717 fn test_method(&self); 702 fn test_method(&self);
718 } 703 }
719 pub struct TestStruct {} 704 pub struct TestStruct {}
720 impl TestTrait for TestStruct { 705 impl TestTrait for TestStruct {
721 fn test_method(&self) {} 706 fn test_method(&self) {}
722 } 707 }
723 } 708}
724 709
725 fn main() { 710fn main() {
726 let test_struct = test_mod::TestStruct {}; 711 let test_struct = test_mod::TestStruct {};
727 test_struct.test_meth$0od() 712 test_struct.test_meth$0od()
728 } 713}
729 ", 714"#,
730 r" 715 r#"
731 mod test_mod { 716mod test_mod {
732 pub trait TestTrait { 717 pub trait TestTrait {
733 fn test_method(&self); 718 fn test_method(&self);
734 } 719 }
735 pub struct TestStruct {} 720 pub struct TestStruct {}
736 impl TestTrait for TestStruct { 721 impl TestTrait for TestStruct {
737 fn test_method(&self) {} 722 fn test_method(&self) {}
738 } 723 }
739 } 724}
740 725
741 fn main() { 726fn main() {
742 let test_struct = test_mod::TestStruct {}; 727 let test_struct = test_mod::TestStruct {};
743 test_mod::TestTrait::test_method(&test_struct) 728 test_mod::TestTrait::test_method(&test_struct)
744 } 729}
745 ", 730"#,
746 ); 731 );
747 } 732 }
748 733
@@ -750,38 +735,38 @@ fn main() {
750 fn trait_method_multi_params() { 735 fn trait_method_multi_params() {
751 check_assist( 736 check_assist(
752 qualify_path, 737 qualify_path,
753 r" 738 r#"
754 mod test_mod { 739mod test_mod {
755 pub trait TestTrait { 740 pub trait TestTrait {
756 fn test_method(&self, test: i32); 741 fn test_method(&self, test: i32);
757 } 742 }
758 pub struct TestStruct {} 743 pub struct TestStruct {}
759 impl TestTrait for TestStruct { 744 impl TestTrait for TestStruct {
760 fn test_method(&self, test: i32) {} 745 fn test_method(&self, test: i32) {}
761 } 746 }
762 } 747}
763 748
764 fn main() { 749fn main() {
765 let test_struct = test_mod::TestStruct {}; 750 let test_struct = test_mod::TestStruct {};
766 test_struct.test_meth$0od(42) 751 test_struct.test_meth$0od(42)
767 } 752}
768 ", 753"#,
769 r" 754 r#"
770 mod test_mod { 755mod test_mod {
771 pub trait TestTrait { 756 pub trait TestTrait {
772 fn test_method(&self, test: i32); 757 fn test_method(&self, test: i32);
773 } 758 }
774 pub struct TestStruct {} 759 pub struct TestStruct {}
775 impl TestTrait for TestStruct { 760 impl TestTrait for TestStruct {
776 fn test_method(&self, test: i32) {} 761 fn test_method(&self, test: i32) {}
777 } 762 }
778 } 763}
779 764
780 fn main() { 765fn main() {
781 let test_struct = test_mod::TestStruct {}; 766 let test_struct = test_mod::TestStruct {};
782 test_mod::TestTrait::test_method(&test_struct, 42) 767 test_mod::TestTrait::test_method(&test_struct, 42)
783 } 768}
784 ", 769"#,
785 ); 770 );
786 } 771 }
787 772
@@ -789,38 +774,38 @@ fn main() {
789 fn trait_method_consume() { 774 fn trait_method_consume() {
790 check_assist( 775 check_assist(
791 qualify_path, 776 qualify_path,
792 r" 777 r#"
793 mod test_mod { 778mod test_mod {
794 pub trait TestTrait { 779 pub trait TestTrait {
795 fn test_method(self); 780 fn test_method(self);
796 } 781 }
797 pub struct TestStruct {} 782 pub struct TestStruct {}
798 impl TestTrait for TestStruct { 783 impl TestTrait for TestStruct {
799 fn test_method(self) {} 784 fn test_method(self) {}
800 } 785 }
801 } 786}
802 787
803 fn main() { 788fn main() {
804 let test_struct = test_mod::TestStruct {}; 789 let test_struct = test_mod::TestStruct {};
805 test_struct.test_meth$0od() 790 test_struct.test_meth$0od()
806 } 791}
807 ", 792"#,
808 r" 793 r#"
809 mod test_mod { 794mod test_mod {
810 pub trait TestTrait { 795 pub trait TestTrait {
811 fn test_method(self); 796 fn test_method(self);
812 } 797 }
813 pub struct TestStruct {} 798 pub struct TestStruct {}
814 impl TestTrait for TestStruct { 799 impl TestTrait for TestStruct {
815 fn test_method(self) {} 800 fn test_method(self) {}
816 } 801 }
817 } 802}
818 803
819 fn main() { 804fn main() {
820 let test_struct = test_mod::TestStruct {}; 805 let test_struct = test_mod::TestStruct {};
821 test_mod::TestTrait::test_method(test_struct) 806 test_mod::TestTrait::test_method(test_struct)
822 } 807}
823 ", 808"#,
824 ); 809 );
825 } 810 }
826 811
@@ -828,29 +813,29 @@ fn main() {
828 fn trait_method_cross_crate() { 813 fn trait_method_cross_crate() {
829 check_assist( 814 check_assist(
830 qualify_path, 815 qualify_path,
831 r" 816 r#"
832 //- /main.rs crate:main deps:dep 817//- /main.rs crate:main deps:dep
833 fn main() { 818fn main() {
834 let test_struct = dep::test_mod::TestStruct {}; 819 let test_struct = dep::test_mod::TestStruct {};
835 test_struct.test_meth$0od() 820 test_struct.test_meth$0od()
836 } 821}
837 //- /dep.rs crate:dep 822//- /dep.rs crate:dep
838 pub mod test_mod { 823pub mod test_mod {
839 pub trait TestTrait { 824 pub trait TestTrait {
840 fn test_method(&self); 825 fn test_method(&self);
841 } 826 }
842 pub struct TestStruct {} 827 pub struct TestStruct {}
843 impl TestTrait for TestStruct { 828 impl TestTrait for TestStruct {
844 fn test_method(&self) {} 829 fn test_method(&self) {}
845 } 830 }
846 } 831}
847 ", 832"#,
848 r" 833 r#"
849 fn main() { 834fn main() {
850 let test_struct = dep::test_mod::TestStruct {}; 835 let test_struct = dep::test_mod::TestStruct {};
851 dep::test_mod::TestTrait::test_method(&test_struct) 836 dep::test_mod::TestTrait::test_method(&test_struct)
852 } 837}
853 ", 838"#,
854 ); 839 );
855 } 840 }
856 841
@@ -858,27 +843,27 @@ fn main() {
858 fn assoc_fn_cross_crate() { 843 fn assoc_fn_cross_crate() {
859 check_assist( 844 check_assist(
860 qualify_path, 845 qualify_path,
861 r" 846 r#"
862 //- /main.rs crate:main deps:dep 847//- /main.rs crate:main deps:dep
863 fn main() { 848fn main() {
864 dep::test_mod::TestStruct::test_func$0tion 849 dep::test_mod::TestStruct::test_func$0tion
865 } 850}
866 //- /dep.rs crate:dep 851//- /dep.rs crate:dep
867 pub mod test_mod { 852pub mod test_mod {
868 pub trait TestTrait { 853 pub trait TestTrait {
869 fn test_function(); 854 fn test_function();
870 } 855 }
871 pub struct TestStruct {} 856 pub struct TestStruct {}
872 impl TestTrait for TestStruct { 857 impl TestTrait for TestStruct {
873 fn test_function() {} 858 fn test_function() {}
874 } 859 }
875 } 860}
876 ", 861"#,
877 r" 862 r#"
878 fn main() { 863fn main() {
879 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::test_function 864 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::test_function
880 } 865}
881 ", 866"#,
882 ); 867 );
883 } 868 }
884 869
@@ -886,27 +871,27 @@ fn main() {
886 fn assoc_const_cross_crate() { 871 fn assoc_const_cross_crate() {
887 check_assist( 872 check_assist(
888 qualify_path, 873 qualify_path,
889 r" 874 r#"
890 //- /main.rs crate:main deps:dep 875//- /main.rs crate:main deps:dep
891 fn main() { 876fn main() {
892 dep::test_mod::TestStruct::CONST$0 877 dep::test_mod::TestStruct::CONST$0
893 } 878}
894 //- /dep.rs crate:dep 879//- /dep.rs crate:dep
895 pub mod test_mod { 880pub mod test_mod {
896 pub trait TestTrait { 881 pub trait TestTrait {
897 const CONST: bool; 882 const CONST: bool;
898 } 883 }
899 pub struct TestStruct {} 884 pub struct TestStruct {}
900 impl TestTrait for TestStruct { 885 impl TestTrait for TestStruct {
901 const CONST: bool = true; 886 const CONST: bool = true;
902 } 887 }
903 } 888}
904 ", 889"#,
905 r" 890 r#"
906 fn main() { 891fn main() {
907 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::CONST 892 <dep::test_mod::TestStruct as dep::test_mod::TestTrait>::CONST
908 } 893}
909 ", 894"#,
910 ); 895 );
911 } 896 }
912 897
@@ -914,23 +899,23 @@ fn main() {
914 fn assoc_fn_as_method_cross_crate() { 899 fn assoc_fn_as_method_cross_crate() {
915 check_assist_not_applicable( 900 check_assist_not_applicable(
916 qualify_path, 901 qualify_path,
917 r" 902 r#"
918 //- /main.rs crate:main deps:dep 903//- /main.rs crate:main deps:dep
919 fn main() { 904fn main() {
920 let test_struct = dep::test_mod::TestStruct {}; 905 let test_struct = dep::test_mod::TestStruct {};
921 test_struct.test_func$0tion() 906 test_struct.test_func$0tion()
922 } 907}
923 //- /dep.rs crate:dep 908//- /dep.rs crate:dep
924 pub mod test_mod { 909pub mod test_mod {
925 pub trait TestTrait { 910 pub trait TestTrait {
926 fn test_function(); 911 fn test_function();
927 } 912 }
928 pub struct TestStruct {} 913 pub struct TestStruct {}
929 impl TestTrait for TestStruct { 914 impl TestTrait for TestStruct {
930 fn test_function() {} 915 fn test_function() {}
931 } 916 }
932 } 917}
933 ", 918"#,
934 ); 919 );
935 } 920 }
936 921
@@ -938,23 +923,23 @@ fn main() {
938 fn private_trait_cross_crate() { 923 fn private_trait_cross_crate() {
939 check_assist_not_applicable( 924 check_assist_not_applicable(
940 qualify_path, 925 qualify_path,
941 r" 926 r#"
942 //- /main.rs crate:main deps:dep 927//- /main.rs crate:main deps:dep
943 fn main() { 928fn main() {
944 let test_struct = dep::test_mod::TestStruct {}; 929 let test_struct = dep::test_mod::TestStruct {};
945 test_struct.test_meth$0od() 930 test_struct.test_meth$0od()
946 } 931}
947 //- /dep.rs crate:dep 932//- /dep.rs crate:dep
948 pub mod test_mod { 933pub mod test_mod {
949 trait TestTrait { 934 trait TestTrait {
950 fn test_method(&self); 935 fn test_method(&self);
951 } 936 }
952 pub struct TestStruct {} 937 pub struct TestStruct {}
953 impl TestTrait for TestStruct { 938 impl TestTrait for TestStruct {
954 fn test_method(&self) {} 939 fn test_method(&self) {}
955 } 940 }
956 } 941}
957 ", 942"#,
958 ); 943 );
959 } 944 }
960 945
@@ -962,32 +947,32 @@ fn main() {
962 fn not_applicable_for_imported_trait_for_method() { 947 fn not_applicable_for_imported_trait_for_method() {
963 check_assist_not_applicable( 948 check_assist_not_applicable(
964 qualify_path, 949 qualify_path,
965 r" 950 r#"
966 mod test_mod { 951mod test_mod {
967 pub trait TestTrait { 952 pub trait TestTrait {
968 fn test_method(&self); 953 fn test_method(&self);
969 } 954 }
970 pub trait TestTrait2 { 955 pub trait TestTrait2 {
971 fn test_method(&self); 956 fn test_method(&self);
972 } 957 }
973 pub enum TestEnum { 958 pub enum TestEnum {
974 One, 959 One,
975 Two, 960 Two,
976 } 961 }
977 impl TestTrait2 for TestEnum { 962 impl TestTrait2 for TestEnum {
978 fn test_method(&self) {} 963 fn test_method(&self) {}
979 } 964 }
980 impl TestTrait for TestEnum { 965 impl TestTrait for TestEnum {
981 fn test_method(&self) {} 966 fn test_method(&self) {}
982 } 967 }
983 } 968}
984 969
985 use test_mod::TestTrait2; 970use test_mod::TestTrait2;
986 fn main() { 971fn main() {
987 let one = test_mod::TestEnum::One; 972 let one = test_mod::TestEnum::One;
988 one.test$0_method(); 973 one.test$0_method();
989 } 974}
990 ", 975"#,
991 ) 976 )
992 } 977 }
993 978
@@ -1114,7 +1099,7 @@ fn main() {}
1114 fn keep_generic_annotations_leading_colon() { 1099 fn keep_generic_annotations_leading_colon() {
1115 check_assist( 1100 check_assist(
1116 qualify_path, 1101 qualify_path,
1117 r" 1102 r#"
1118//- /lib.rs crate:dep 1103//- /lib.rs crate:dep
1119pub mod generic { pub struct Thing<'a, T>(&'a T); } 1104pub mod generic { pub struct Thing<'a, T>(&'a T); }
1120 1105
@@ -1122,7 +1107,7 @@ pub mod generic { pub struct Thing<'a, T>(&'a T); }
1122fn foo() -> Thin$0g::<'static, ()> {} 1107fn foo() -> Thin$0g::<'static, ()> {}
1123 1108
1124fn main() {} 1109fn main() {}
1125", 1110"#,
1126 r" 1111 r"
1127fn foo() -> dep::generic::Thing::<'static, ()> {} 1112fn foo() -> dep::generic::Thing::<'static, ()> {}
1128 1113
@@ -1135,30 +1120,30 @@ fn main() {}
1135 fn associated_struct_const_generic() { 1120 fn associated_struct_const_generic() {
1136 check_assist( 1121 check_assist(
1137 qualify_path, 1122 qualify_path,
1138 r" 1123 r#"
1139 mod test_mod { 1124mod test_mod {
1140 pub struct TestStruct<T> {} 1125 pub struct TestStruct<T> {}
1141 impl<T> TestStruct<T> { 1126 impl<T> TestStruct<T> {
1142 const TEST_CONST: u8 = 42; 1127 const TEST_CONST: u8 = 42;
1143 } 1128 }
1144 } 1129}
1145 1130
1146 fn main() { 1131fn main() {
1147 TestStruct::<()>::TEST_CONST$0 1132 TestStruct::<()>::TEST_CONST$0
1148 } 1133}
1149 ", 1134"#,
1150 r" 1135 r#"
1151 mod test_mod { 1136mod test_mod {
1152 pub struct TestStruct<T> {} 1137 pub struct TestStruct<T> {}
1153 impl<T> TestStruct<T> { 1138 impl<T> TestStruct<T> {
1154 const TEST_CONST: u8 = 42; 1139 const TEST_CONST: u8 = 42;
1155 } 1140 }
1156 } 1141}
1157 1142
1158 fn main() { 1143fn main() {
1159 test_mod::TestStruct::<()>::TEST_CONST 1144 test_mod::TestStruct::<()>::TEST_CONST
1160 } 1145}
1161 ", 1146"#,
1162 ); 1147 );
1163 } 1148 }
1164 1149
@@ -1166,36 +1151,36 @@ fn main() {}
1166 fn associated_trait_const_generic() { 1151 fn associated_trait_const_generic() {
1167 check_assist( 1152 check_assist(
1168 qualify_path, 1153 qualify_path,
1169 r" 1154 r#"
1170 mod test_mod { 1155mod test_mod {
1171 pub trait TestTrait { 1156 pub trait TestTrait {
1172 const TEST_CONST: u8; 1157 const TEST_CONST: u8;
1173 } 1158 }
1174 pub struct TestStruct<T> {} 1159 pub struct TestStruct<T> {}
1175 impl<T> TestTrait for TestStruct<T> { 1160 impl<T> TestTrait for TestStruct<T> {
1176 const TEST_CONST: u8 = 42; 1161 const TEST_CONST: u8 = 42;
1177 } 1162 }
1178 } 1163}
1179 1164
1180 fn main() { 1165fn main() {
1181 test_mod::TestStruct::<()>::TEST_CONST$0 1166 test_mod::TestStruct::<()>::TEST_CONST$0
1182 } 1167}
1183 ", 1168"#,
1184 r" 1169 r#"
1185 mod test_mod { 1170mod test_mod {
1186 pub trait TestTrait { 1171 pub trait TestTrait {
1187 const TEST_CONST: u8; 1172 const TEST_CONST: u8;
1188 } 1173 }
1189 pub struct TestStruct<T> {} 1174 pub struct TestStruct<T> {}
1190 impl<T> TestTrait for TestStruct<T> { 1175 impl<T> TestTrait for TestStruct<T> {
1191 const TEST_CONST: u8 = 42; 1176 const TEST_CONST: u8 = 42;
1192 } 1177 }
1193 } 1178}
1194 1179
1195 fn main() { 1180fn main() {
1196 <test_mod::TestStruct::<()> as test_mod::TestTrait>::TEST_CONST 1181 <test_mod::TestStruct::<()> as test_mod::TestTrait>::TEST_CONST
1197 } 1182}
1198 ", 1183"#,
1199 ); 1184 );
1200 } 1185 }
1201 1186
@@ -1203,38 +1188,38 @@ fn main() {}
1203 fn trait_method_generic() { 1188 fn trait_method_generic() {
1204 check_assist( 1189 check_assist(
1205 qualify_path, 1190 qualify_path,
1206 r" 1191 r#"
1207 mod test_mod { 1192mod test_mod {
1208 pub trait TestTrait { 1193 pub trait TestTrait {
1209 fn test_method<T>(&self); 1194 fn test_method<T>(&self);
1210 } 1195 }
1211 pub struct TestStruct {} 1196 pub struct TestStruct {}
1212 impl TestTrait for TestStruct { 1197 impl TestTrait for TestStruct {
1213 fn test_method<T>(&self) {} 1198 fn test_method<T>(&self) {}
1214 } 1199 }
1215 } 1200}
1216 1201
1217 fn main() { 1202fn main() {
1218 let test_struct = test_mod::TestStruct {}; 1203 let test_struct = test_mod::TestStruct {};
1219 test_struct.test_meth$0od::<()>() 1204 test_struct.test_meth$0od::<()>()
1220 } 1205}
1221 ", 1206"#,
1222 r" 1207 r#"
1223 mod test_mod { 1208mod test_mod {
1224 pub trait TestTrait { 1209 pub trait TestTrait {
1225 fn test_method<T>(&self); 1210 fn test_method<T>(&self);
1226 } 1211 }
1227 pub struct TestStruct {} 1212 pub struct TestStruct {}
1228 impl TestTrait for TestStruct { 1213 impl TestTrait for TestStruct {
1229 fn test_method<T>(&self) {} 1214 fn test_method<T>(&self) {}
1230 } 1215 }
1231 } 1216}
1232 1217
1233 fn main() { 1218fn main() {
1234 let test_struct = test_mod::TestStruct {}; 1219 let test_struct = test_mod::TestStruct {};
1235 test_mod::TestTrait::test_method::<()>(&test_struct) 1220 test_mod::TestTrait::test_method::<()>(&test_struct)
1236 } 1221}
1237 ", 1222"#,
1238 ); 1223 );
1239 } 1224 }
1240} 1225}
diff --git a/crates/ide_assists/src/handlers/remove_dbg.rs b/crates/ide_assists/src/handlers/remove_dbg.rs
index b20fe992d..5866d8974 100644
--- a/crates/ide_assists/src/handlers/remove_dbg.rs
+++ b/crates/ide_assists/src/handlers/remove_dbg.rs
@@ -35,14 +35,14 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
35 .prev_sibling_or_token() 35 .prev_sibling_or_token()
36 .and_then(whitespace_start) 36 .and_then(whitespace_start)
37 .map(|start| TextRange::new(start, macro_call.syntax().text_range().end())) 37 .map(|start| TextRange::new(start, macro_call.syntax().text_range().end()))
38 .unwrap_or(macro_call.syntax().text_range()) 38 .unwrap_or_else(|| macro_call.syntax().text_range())
39 }, 39 },
40 ast::ExprStmt(it) => { 40 ast::ExprStmt(it) => {
41 let start = it 41 let start = it
42 .syntax() 42 .syntax()
43 .prev_sibling_or_token() 43 .prev_sibling_or_token()
44 .and_then(whitespace_start) 44 .and_then(whitespace_start)
45 .unwrap_or(it.syntax().text_range().start()); 45 .unwrap_or_else(|| it.syntax().text_range().start());
46 let end = it.syntax().text_range().end(); 46 let end = it.syntax().text_range().end();
47 47
48 TextRange::new(start, end) 48 TextRange::new(start, end)
diff --git a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
index 50b05ab0b..5f2aa016f 100644
--- a/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
+++ b/crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs
@@ -85,38 +85,48 @@ fn is_ref_and_impls_iter_method(
85 let krate = scope.module()?.krate(); 85 let krate = scope.module()?.krate();
86 let traits_in_scope = scope.traits_in_scope(); 86 let traits_in_scope = scope.traits_in_scope();
87 let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?; 87 let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
88 let has_wanted_method = typ.iterate_method_candidates( 88
89 sema.db, 89 let has_wanted_method = typ
90 krate, 90 .iterate_method_candidates(
91 &traits_in_scope, 91 sema.db,
92 Some(&wanted_method), 92 krate,
93 |_, func| { 93 &traits_in_scope,
94 if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) { 94 Some(&wanted_method),
95 return Some(()); 95 |_, func| {
96 } 96 if func.ret_type(sema.db).impls_trait(sema.db, iter_trait, &[]) {
97 None 97 return Some(());
98 }, 98 }
99 ); 99 None
100 has_wanted_method.and(Some((expr_behind_ref, wanted_method))) 100 },
101 )
102 .is_some();
103 if !has_wanted_method {
104 return None;
105 }
106
107 Some((expr_behind_ref, wanted_method))
101} 108}
102 109
103/// Whether iterable implements core::Iterator 110/// Whether iterable implements core::Iterator
104fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool { 111fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
105 let it_typ = if let Some(i) = sema.type_of_expr(iterable) { 112 let it_typ = match sema.type_of_expr(iterable) {
106 i 113 Some(it) => it,
107 } else { 114 None => return false,
108 return false;
109 }; 115 };
110 let module = if let Some(m) = sema.scope(iterable.syntax()).module() { 116
111 m 117 let module = match sema.scope(iterable.syntax()).module() {
112 } else { 118 Some(it) => it,
113 return false; 119 None => return false,
114 }; 120 };
121
115 let krate = module.krate(); 122 let krate = module.krate();
116 if let Some(iter_trait) = FamousDefs(sema, Some(krate)).core_iter_Iterator() { 123 match FamousDefs(sema, Some(krate)).core_iter_Iterator() {
117 return it_typ.impls_trait(sema.db, iter_trait, &[]); 124 Some(iter_trait) => {
125 cov_mark::hit!(test_already_impls_iterator);
126 it_typ.impls_trait(sema.db, iter_trait, &[])
127 }
128 None => false,
118 } 129 }
119 false
120} 130}
121 131
122#[cfg(test)] 132#[cfg(test)]
@@ -125,33 +135,6 @@ mod tests {
125 135
126 use super::*; 136 use super::*;
127 137
128 const EMPTY_ITER_FIXTURE: &'static str = r"
129//- /lib.rs deps:core crate:empty_iter
130pub struct EmptyIter;
131impl Iterator for EmptyIter {
132 type Item = usize;
133 fn next(&mut self) -> Option<Self::Item> { None }
134}
135
136pub struct Empty;
137impl Empty {
138 pub fn iter(&self) -> EmptyIter { EmptyIter }
139 pub fn iter_mut(&self) -> EmptyIter { EmptyIter }
140}
141
142pub struct NoIterMethod;
143";
144
145 fn check_assist_with_fixtures(before: &str, after: &str) {
146 let before = &format!(
147 "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
148 before,
149 FamousDefs::FIXTURE,
150 EMPTY_ITER_FIXTURE
151 );
152 check_assist(replace_for_loop_with_for_each, before, after);
153 }
154
155 #[test] 138 #[test]
156 fn test_not_for() { 139 fn test_not_for() {
157 check_assist_not_applicable( 140 check_assist_not_applicable(
@@ -201,33 +184,50 @@ fn main() {
201 184
202 #[test] 185 #[test]
203 fn test_for_borrowed() { 186 fn test_for_borrowed() {
204 check_assist_with_fixtures( 187 check_assist(
205 r" 188 replace_for_loop_with_for_each,
206use empty_iter::*; 189 r#"
190//- minicore: iterators
191use core::iter::{Repeat, repeat};
192
193struct S;
194impl S {
195 fn iter(&self) -> Repeat<i32> { repeat(92) }
196 fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) }
197}
198
207fn main() { 199fn main() {
208 let x = Empty; 200 let x = S;
209 for $0v in &x { 201 for $0v in &x {
210 let a = v * 2; 202 let a = v * 2;
211 } 203 }
212} 204}
213", 205"#,
214 r" 206 r#"
215use empty_iter::*; 207use core::iter::{Repeat, repeat};
208
209struct S;
210impl S {
211 fn iter(&self) -> Repeat<i32> { repeat(92) }
212 fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) }
213}
214
216fn main() { 215fn main() {
217 let x = Empty; 216 let x = S;
218 x.iter().for_each(|v| { 217 x.iter().for_each(|v| {
219 let a = v * 2; 218 let a = v * 2;
220 }); 219 });
221} 220}
222", 221"#,
223 ) 222 )
224 } 223 }
225 224
226 #[test] 225 #[test]
227 fn test_for_borrowed_no_iter_method() { 226 fn test_for_borrowed_no_iter_method() {
228 check_assist_with_fixtures( 227 check_assist(
228 replace_for_loop_with_for_each,
229 r" 229 r"
230use empty_iter::*; 230struct NoIterMethod;
231fn main() { 231fn main() {
232 let x = NoIterMethod; 232 let x = NoIterMethod;
233 for $0v in &x { 233 for $0v in &x {
@@ -236,7 +236,7 @@ fn main() {
236} 236}
237", 237",
238 r" 238 r"
239use empty_iter::*; 239struct NoIterMethod;
240fn main() { 240fn main() {
241 let x = NoIterMethod; 241 let x = NoIterMethod;
242 (&x).into_iter().for_each(|v| { 242 (&x).into_iter().for_each(|v| {
@@ -249,25 +249,41 @@ fn main() {
249 249
250 #[test] 250 #[test]
251 fn test_for_borrowed_mut() { 251 fn test_for_borrowed_mut() {
252 check_assist_with_fixtures( 252 check_assist(
253 r" 253 replace_for_loop_with_for_each,
254use empty_iter::*; 254 r#"
255//- minicore: iterators
256use core::iter::{Repeat, repeat};
257
258struct S;
259impl S {
260 fn iter(&self) -> Repeat<i32> { repeat(92) }
261 fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) }
262}
263
255fn main() { 264fn main() {
256 let x = Empty; 265 let x = S;
257 for $0v in &mut x { 266 for $0v in &mut x {
258 let a = v * 2; 267 let a = v * 2;
259 } 268 }
260} 269}
261", 270"#,
262 r" 271 r#"
263use empty_iter::*; 272use core::iter::{Repeat, repeat};
273
274struct S;
275impl S {
276 fn iter(&self) -> Repeat<i32> { repeat(92) }
277 fn iter_mut(&mut self) -> Repeat<i32> { repeat(92) }
278}
279
264fn main() { 280fn main() {
265 let x = Empty; 281 let x = S;
266 x.iter_mut().for_each(|v| { 282 x.iter_mut().for_each(|v| {
267 let a = v * 2; 283 let a = v * 2;
268 }); 284 });
269} 285}
270", 286"#,
271 ) 287 )
272 } 288 }
273 289
@@ -296,21 +312,20 @@ fn main() {
296 312
297 #[test] 313 #[test]
298 fn test_already_impls_iterator() { 314 fn test_already_impls_iterator() {
299 check_assist_with_fixtures( 315 cov_mark::check!(test_already_impls_iterator);
316 check_assist(
317 replace_for_loop_with_for_each,
300 r#" 318 r#"
301use empty_iter::*; 319//- minicore: iterators
302fn main() { 320fn main() {
303 let x = Empty; 321 for$0 a in core::iter::repeat(92).take(1) {
304 for$0 a in x.iter().take(1) {
305 println!("{}", a); 322 println!("{}", a);
306 } 323 }
307} 324}
308"#, 325"#,
309 r#" 326 r#"
310use empty_iter::*;
311fn main() { 327fn main() {
312 let x = Empty; 328 core::iter::repeat(92).take(1).for_each(|a| {
313 x.iter().take(1).for_each(|a| {
314 println!("{}", a); 329 println!("{}", a);
315 }); 330 });
316} 331}
diff --git a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
index 9404aa26d..f37aa0d53 100644
--- a/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_if_let_with_match.rs
@@ -262,9 +262,7 @@ impl VariantData {
262 check_assist( 262 check_assist(
263 replace_if_let_with_match, 263 replace_if_let_with_match,
264 r#" 264 r#"
265enum Option<T> { Some(T), None } 265//- minicore: option
266use Option::*;
267
268fn foo(x: Option<i32>) { 266fn foo(x: Option<i32>) {
269 $0if let Some(x) = x { 267 $0if let Some(x) = x {
270 println!("{}", x) 268 println!("{}", x)
@@ -272,18 +270,15 @@ fn foo(x: Option<i32>) {
272 println!("none") 270 println!("none")
273 } 271 }
274} 272}
275 "#, 273"#,
276 r#" 274 r#"
277enum Option<T> { Some(T), None }
278use Option::*;
279
280fn foo(x: Option<i32>) { 275fn foo(x: Option<i32>) {
281 match x { 276 match x {
282 Some(x) => println!("{}", x), 277 Some(x) => println!("{}", x),
283 None => println!("none"), 278 None => println!("none"),
284 } 279 }
285} 280}
286 "#, 281"#,
287 ); 282 );
288 } 283 }
289 284
@@ -292,9 +287,7 @@ fn foo(x: Option<i32>) {
292 check_assist( 287 check_assist(
293 replace_if_let_with_match, 288 replace_if_let_with_match,
294 r#" 289 r#"
295enum Option<T> { Some(T), None } 290//- minicore: option
296use Option::*;
297
298fn foo(x: Option<i32>) { 291fn foo(x: Option<i32>) {
299 $0if let None = x { 292 $0if let None = x {
300 println!("none") 293 println!("none")
@@ -302,18 +295,15 @@ fn foo(x: Option<i32>) {
302 println!("some") 295 println!("some")
303 } 296 }
304} 297}
305 "#, 298"#,
306 r#" 299 r#"
307enum Option<T> { Some(T), None }
308use Option::*;
309
310fn foo(x: Option<i32>) { 300fn foo(x: Option<i32>) {
311 match x { 301 match x {
312 None => println!("none"), 302 None => println!("none"),
313 Some(_) => println!("some"), 303 Some(_) => println!("some"),
314 } 304 }
315} 305}
316 "#, 306"#,
317 ); 307 );
318 } 308 }
319 309
@@ -322,9 +312,7 @@ fn foo(x: Option<i32>) {
322 check_assist( 312 check_assist(
323 replace_if_let_with_match, 313 replace_if_let_with_match,
324 r#" 314 r#"
325enum Result<T, E> { Ok(T), Err(E) } 315//- minicore: result
326use Result::*;
327
328fn foo(x: Result<i32, ()>) { 316fn foo(x: Result<i32, ()>) {
329 $0if let Ok(x) = x { 317 $0if let Ok(x) = x {
330 println!("{}", x) 318 println!("{}", x)
@@ -332,18 +320,15 @@ fn foo(x: Result<i32, ()>) {
332 println!("none") 320 println!("none")
333 } 321 }
334} 322}
335 "#, 323"#,
336 r#" 324 r#"
337enum Result<T, E> { Ok(T), Err(E) }
338use Result::*;
339
340fn foo(x: Result<i32, ()>) { 325fn foo(x: Result<i32, ()>) {
341 match x { 326 match x {
342 Ok(x) => println!("{}", x), 327 Ok(x) => println!("{}", x),
343 Err(_) => println!("none"), 328 Err(_) => println!("none"),
344 } 329 }
345} 330}
346 "#, 331"#,
347 ); 332 );
348 } 333 }
349 334
@@ -352,9 +337,7 @@ fn foo(x: Result<i32, ()>) {
352 check_assist( 337 check_assist(
353 replace_if_let_with_match, 338 replace_if_let_with_match,
354 r#" 339 r#"
355enum Result<T, E> { Ok(T), Err(E) } 340//- minicore: result
356use Result::*;
357
358fn foo(x: Result<i32, ()>) { 341fn foo(x: Result<i32, ()>) {
359 $0if let Err(x) = x { 342 $0if let Err(x) = x {
360 println!("{}", x) 343 println!("{}", x)
@@ -362,18 +345,15 @@ fn foo(x: Result<i32, ()>) {
362 println!("ok") 345 println!("ok")
363 } 346 }
364} 347}
365 "#, 348"#,
366 r#" 349 r#"
367enum Result<T, E> { Ok(T), Err(E) }
368use Result::*;
369
370fn foo(x: Result<i32, ()>) { 350fn foo(x: Result<i32, ()>) {
371 match x { 351 match x {
372 Err(x) => println!("{}", x), 352 Err(x) => println!("{}", x),
373 Ok(_) => println!("ok"), 353 Ok(_) => println!("ok"),
374 } 354 }
375} 355}
376 "#, 356"#,
377 ); 357 );
378 } 358 }
379 359
@@ -488,20 +468,15 @@ impl VariantData {
488 check_assist( 468 check_assist(
489 replace_match_with_if_let, 469 replace_match_with_if_let,
490 r#" 470 r#"
491enum Option<T> { Some(T), None } 471//- minicore: option
492use Option::*;
493
494fn foo(x: Option<i32>) { 472fn foo(x: Option<i32>) {
495 $0match x { 473 $0match x {
496 Some(x) => println!("{}", x), 474 Some(x) => println!("{}", x),
497 None => println!("none"), 475 None => println!("none"),
498 } 476 }
499} 477}
500 "#, 478"#,
501 r#" 479 r#"
502enum Option<T> { Some(T), None }
503use Option::*;
504
505fn foo(x: Option<i32>) { 480fn foo(x: Option<i32>) {
506 if let Some(x) = x { 481 if let Some(x) = x {
507 println!("{}", x) 482 println!("{}", x)
@@ -509,7 +484,7 @@ fn foo(x: Option<i32>) {
509 println!("none") 484 println!("none")
510 } 485 }
511} 486}
512 "#, 487"#,
513 ); 488 );
514 } 489 }
515 490
@@ -518,20 +493,15 @@ fn foo(x: Option<i32>) {
518 check_assist( 493 check_assist(
519 replace_match_with_if_let, 494 replace_match_with_if_let,
520 r#" 495 r#"
521enum Result<T, E> { Ok(T), Err(E) } 496//- minicore: result
522use Result::*;
523
524fn foo(x: Result<i32, ()>) { 497fn foo(x: Result<i32, ()>) {
525 $0match x { 498 $0match x {
526 Ok(x) => println!("{}", x), 499 Ok(x) => println!("{}", x),
527 Err(_) => println!("none"), 500 Err(_) => println!("none"),
528 } 501 }
529} 502}
530 "#, 503"#,
531 r#" 504 r#"
532enum Result<T, E> { Ok(T), Err(E) }
533use Result::*;
534
535fn foo(x: Result<i32, ()>) { 505fn foo(x: Result<i32, ()>) {
536 if let Ok(x) = x { 506 if let Ok(x) = x {
537 println!("{}", x) 507 println!("{}", x)
@@ -539,7 +509,7 @@ fn foo(x: Result<i32, ()>) {
539 println!("none") 509 println!("none")
540 } 510 }
541} 511}
542 "#, 512"#,
543 ); 513 );
544 } 514 }
545 515
diff --git a/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs
index 540a905cc..a2af2035f 100644
--- a/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs
+++ b/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs
@@ -105,12 +105,13 @@ fn foo<B: Bar
105 } 105 }
106 106
107 #[test] 107 #[test]
108 #[ignore = "This case is very rare but there is no simple solutions to fix it."]
109 fn replace_impl_trait_with_exist_generic_letter() { 108 fn replace_impl_trait_with_exist_generic_letter() {
109 // FIXME: This is wrong, we should pick a different name if the one we
110 // want is already bound.
110 check_assist( 111 check_assist(
111 replace_impl_trait_with_generic, 112 replace_impl_trait_with_generic,
112 r#"fn foo<B>(bar: $0impl Bar) {}"#, 113 r#"fn foo<B>(bar: $0impl Bar) {}"#,
113 r#"fn foo<B, C: Bar>(bar: C) {}"#, 114 r#"fn foo<B, B: Bar>(bar: B) {}"#,
114 ); 115 );
115 } 116 }
116 117
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
index 39f5eb4ff..26778ee74 100644
--- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -32,7 +32,6 @@ pub(crate) fn replace_qualified_name_with_use(
32 32
33 let target = path.syntax().text_range(); 33 let target = path.syntax().text_range();
34 let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?; 34 let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?;
35 let syntax = scope.as_syntax_node();
36 acc.add( 35 acc.add(
37 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), 36 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
38 "Replace qualified path with use", 37 "Replace qualified path with use",
@@ -40,11 +39,13 @@ pub(crate) fn replace_qualified_name_with_use(
40 |builder| { 39 |builder| {
41 // Now that we've brought the name into scope, re-qualify all paths that could be 40 // Now that we've brought the name into scope, re-qualify all paths that could be
42 // affected (that is, all paths inside the node we added the `use` to). 41 // affected (that is, all paths inside the node we added the `use` to).
43 let syntax = builder.make_syntax_mut(syntax.clone()); 42 let scope = match scope {
44 if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { 43 ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
45 shorten_paths(&syntax, &path.clone_for_update()); 44 ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
46 insert_use(import_scope, path, ctx.config.insert_use); 45 ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
47 } 46 };
47 shorten_paths(scope.as_syntax_node(), &path.clone_for_update());
48 insert_use(&scope, path, &ctx.config.insert_use);
48 }, 49 },
49 ) 50 )
50} 51}
diff --git a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
index a3bfa221c..f39c48d8f 100644
--- a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
+++ b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs
@@ -20,17 +20,16 @@ use ide_db::ty_filter::TryEnum;
20// Replaces `unwrap` with a `match` expression. Works for Result and Option. 20// Replaces `unwrap` with a `match` expression. Works for Result and Option.
21// 21//
22// ``` 22// ```
23// enum Result<T, E> { Ok(T), Err(E) } 23// # //- minicore: result
24// fn main() { 24// fn main() {
25// let x: Result<i32, i32> = Result::Ok(92); 25// let x: Result<i32, i32> = Ok(92);
26// let y = x.$0unwrap(); 26// let y = x.$0unwrap();
27// } 27// }
28// ``` 28// ```
29// -> 29// ->
30// ``` 30// ```
31// enum Result<T, E> { Ok(T), Err(E) }
32// fn main() { 31// fn main() {
33// let x: Result<i32, i32> = Result::Ok(92); 32// let x: Result<i32, i32> = Ok(92);
34// let y = match x { 33// let y = match x {
35// Ok(it) => it, 34// Ok(it) => it,
36// $0_ => unreachable!(), 35// $0_ => unreachable!(),
@@ -97,25 +96,24 @@ mod tests {
97 fn test_replace_result_unwrap_with_match() { 96 fn test_replace_result_unwrap_with_match() {
98 check_assist( 97 check_assist(
99 replace_unwrap_with_match, 98 replace_unwrap_with_match,
100 r" 99 r#"
101enum Result<T, E> { Ok(T), Err(E) } 100//- minicore: result
102fn i<T>(a: T) -> T { a } 101fn i<T>(a: T) -> T { a }
103fn main() { 102fn main() {
104 let x: Result<i32, i32> = Result::Ok(92); 103 let x: Result<i32, i32> = Ok(92);
105 let y = i(x).$0unwrap(); 104 let y = i(x).$0unwrap();
106} 105}
107 ", 106"#,
108 r" 107 r#"
109enum Result<T, E> { Ok(T), Err(E) }
110fn i<T>(a: T) -> T { a } 108fn i<T>(a: T) -> T { a }
111fn main() { 109fn main() {
112 let x: Result<i32, i32> = Result::Ok(92); 110 let x: Result<i32, i32> = Ok(92);
113 let y = match i(x) { 111 let y = match i(x) {
114 Ok(it) => it, 112 Ok(it) => it,
115 $0_ => unreachable!(), 113 $0_ => unreachable!(),
116 }; 114 };
117} 115}
118 ", 116"#,
119 ) 117 )
120 } 118 }
121 119
@@ -123,25 +121,24 @@ fn main() {
123 fn test_replace_option_unwrap_with_match() { 121 fn test_replace_option_unwrap_with_match() {
124 check_assist( 122 check_assist(
125 replace_unwrap_with_match, 123 replace_unwrap_with_match,
126 r" 124 r#"
127enum Option<T> { Some(T), None } 125//- minicore: option
128fn i<T>(a: T) -> T { a } 126fn i<T>(a: T) -> T { a }
129fn main() { 127fn main() {
130 let x = Option::Some(92); 128 let x = Some(92);
131 let y = i(x).$0unwrap(); 129 let y = i(x).$0unwrap();
132} 130}
133 ", 131"#,
134 r" 132 r#"
135enum Option<T> { Some(T), None }
136fn i<T>(a: T) -> T { a } 133fn i<T>(a: T) -> T { a }
137fn main() { 134fn main() {
138 let x = Option::Some(92); 135 let x = Some(92);
139 let y = match i(x) { 136 let y = match i(x) {
140 Some(it) => it, 137 Some(it) => it,
141 $0_ => unreachable!(), 138 $0_ => unreachable!(),
142 }; 139 };
143} 140}
144 ", 141"#,
145 ); 142 );
146 } 143 }
147 144
@@ -149,25 +146,24 @@ fn main() {
149 fn test_replace_result_unwrap_with_match_chaining() { 146 fn test_replace_result_unwrap_with_match_chaining() {
150 check_assist( 147 check_assist(
151 replace_unwrap_with_match, 148 replace_unwrap_with_match,
152 r" 149 r#"
153enum Result<T, E> { Ok(T), Err(E) } 150//- minicore: result
154fn i<T>(a: T) -> T { a } 151fn i<T>(a: T) -> T { a }
155fn main() { 152fn main() {
156 let x: Result<i32, i32> = Result::Ok(92); 153 let x: Result<i32, i32> = Ok(92);
157 let y = i(x).$0unwrap().count_zeroes(); 154 let y = i(x).$0unwrap().count_zeroes();
158} 155}
159 ", 156"#,
160 r" 157 r#"
161enum Result<T, E> { Ok(T), Err(E) }
162fn i<T>(a: T) -> T { a } 158fn i<T>(a: T) -> T { a }
163fn main() { 159fn main() {
164 let x: Result<i32, i32> = Result::Ok(92); 160 let x: Result<i32, i32> = Ok(92);
165 let y = match i(x) { 161 let y = match i(x) {
166 Ok(it) => it, 162 Ok(it) => it,
167 $0_ => unreachable!(), 163 $0_ => unreachable!(),
168 }.count_zeroes(); 164 }.count_zeroes();
169} 165}
170 ", 166"#,
171 ) 167 )
172 } 168 }
173 169
@@ -175,14 +171,14 @@ fn main() {
175 fn replace_unwrap_with_match_target() { 171 fn replace_unwrap_with_match_target() {
176 check_assist_target( 172 check_assist_target(
177 replace_unwrap_with_match, 173 replace_unwrap_with_match,
178 r" 174 r#"
179enum Option<T> { Some(T), None } 175//- minicore: option
180fn i<T>(a: T) -> T { a } 176fn i<T>(a: T) -> T { a }
181fn main() { 177fn main() {
182 let x = Option::Some(92); 178 let x = Some(92);
183 let y = i(x).$0unwrap(); 179 let y = i(x).$0unwrap();
184} 180}
185 ", 181"#,
186 r"i(x).unwrap()", 182 r"i(x).unwrap()",
187 ); 183 );
188 } 184 }
diff --git a/crates/ide_assists/src/handlers/unmerge_use.rs b/crates/ide_assists/src/handlers/unmerge_use.rs
index 8d271e056..14e862cd0 100644
--- a/crates/ide_assists/src/handlers/unmerge_use.rs
+++ b/crates/ide_assists/src/handlers/unmerge_use.rs
@@ -73,7 +73,11 @@ fn resolve_full_path(tree: &ast::UseTree) -> Option<ast::Path> {
73 for path in paths { 73 for path in paths {
74 final_path = ast::make::path_concat(path, final_path) 74 final_path = ast::make::path_concat(path, final_path)
75 } 75 }
76 Some(final_path) 76 if final_path.segment().map_or(false, |it| it.self_token().is_some()) {
77 final_path.qualifier()
78 } else {
79 Some(final_path)
80 }
77} 81}
78 82
79#[cfg(test)] 83#[cfg(test)]
@@ -223,4 +227,14 @@ pub use std::fmt::Display;
223", 227",
224 ); 228 );
225 } 229 }
230
231 #[test]
232 fn unmerge_use_item_on_self() {
233 check_assist(
234 unmerge_use,
235 r"use std::process::{Command, self$0};",
236 r"use std::process::{Command};
237use std::process;",
238 );
239 }
226} 240}
diff --git a/crates/ide_assists/src/lib.rs b/crates/ide_assists/src/lib.rs
index 331a6df2b..86a57ce5d 100644
--- a/crates/ide_assists/src/lib.rs
+++ b/crates/ide_assists/src/lib.rs
@@ -15,158 +15,32 @@ mod assist_context;
15#[cfg(test)] 15#[cfg(test)]
16mod tests; 16mod tests;
17pub mod utils; 17pub mod utils;
18pub mod path_transform;
19
20use std::str::FromStr;
21 18
22use hir::Semantics; 19use hir::Semantics;
23use ide_db::{base_db::FileRange, label::Label, source_change::SourceChange, RootDatabase}; 20use ide_db::{base_db::FileRange, RootDatabase};
24use syntax::TextRange; 21use syntax::TextRange;
25 22
26pub(crate) use crate::assist_context::{AssistContext, Assists}; 23pub(crate) use crate::assist_context::{AssistContext, Assists};
27 24
28pub use assist_config::AssistConfig; 25pub use assist_config::AssistConfig;
29 26pub use ide_db::assists::{
30#[derive(Debug, Clone, Copy, PartialEq, Eq)] 27 Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel, SingleResolve,
31pub enum AssistKind { 28};
32 // FIXME: does the None variant make sense? Probably not. 29
33 None, 30/// Return all the assists applicable at the given position.
34 31pub fn assists(
35 QuickFix, 32 db: &RootDatabase,
36 Generate, 33 config: &AssistConfig,
37 Refactor, 34 resolve: AssistResolveStrategy,
38 RefactorExtract, 35 range: FileRange,
39 RefactorInline, 36) -> Vec<Assist> {
40 RefactorRewrite, 37 let sema = Semantics::new(db);
41} 38 let ctx = AssistContext::new(sema, config, range);
42 39 let mut acc = Assists::new(&ctx, resolve);
43impl AssistKind { 40 handlers::all().iter().for_each(|handler| {
44 pub fn contains(self, other: AssistKind) -> bool { 41 handler(&mut acc, &ctx);
45 if self == other { 42 });
46 return true; 43 acc.finish()
47 }
48
49 match self {
50 AssistKind::None | AssistKind::Generate => true,
51 AssistKind::Refactor => match other {
52 AssistKind::RefactorExtract
53 | AssistKind::RefactorInline
54 | AssistKind::RefactorRewrite => true,
55 _ => false,
56 },
57 _ => false,
58 }
59 }
60
61 pub fn name(&self) -> &str {
62 match self {
63 AssistKind::None => "None",
64 AssistKind::QuickFix => "QuickFix",
65 AssistKind::Generate => "Generate",
66 AssistKind::Refactor => "Refactor",
67 AssistKind::RefactorExtract => "RefactorExtract",
68 AssistKind::RefactorInline => "RefactorInline",
69 AssistKind::RefactorRewrite => "RefactorRewrite",
70 }
71 }
72}
73
74impl FromStr for AssistKind {
75 type Err = String;
76
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 match s {
79 "None" => Ok(AssistKind::None),
80 "QuickFix" => Ok(AssistKind::QuickFix),
81 "Generate" => Ok(AssistKind::Generate),
82 "Refactor" => Ok(AssistKind::Refactor),
83 "RefactorExtract" => Ok(AssistKind::RefactorExtract),
84 "RefactorInline" => Ok(AssistKind::RefactorInline),
85 "RefactorRewrite" => Ok(AssistKind::RefactorRewrite),
86 unknown => Err(format!("Unknown AssistKind: '{}'", unknown)),
87 }
88 }
89}
90
91/// Unique identifier of the assist, should not be shown to the user
92/// directly.
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub struct AssistId(pub &'static str, pub AssistKind);
95
96/// A way to control how many asssist to resolve during the assist resolution.
97/// When an assist is resolved, its edits are calculated that might be costly to always do by default.
98#[derive(Debug)]
99pub enum AssistResolveStrategy {
100 /// No assists should be resolved.
101 None,
102 /// All assists should be resolved.
103 All,
104 /// Only a certain assist should be resolved.
105 Single(SingleResolve),
106}
107
108/// Hold the [`AssistId`] data of a certain assist to resolve.
109/// The original id object cannot be used due to a `'static` lifetime
110/// and the requirement to construct this struct dynamically during the resolve handling.
111#[derive(Debug)]
112pub struct SingleResolve {
113 /// The id of the assist.
114 pub assist_id: String,
115 // The kind of the assist.
116 pub assist_kind: AssistKind,
117}
118
119impl AssistResolveStrategy {
120 pub fn should_resolve(&self, id: &AssistId) -> bool {
121 match self {
122 AssistResolveStrategy::None => false,
123 AssistResolveStrategy::All => true,
124 AssistResolveStrategy::Single(single_resolve) => {
125 single_resolve.assist_id == id.0 && single_resolve.assist_kind == id.1
126 }
127 }
128 }
129}
130
131#[derive(Clone, Debug)]
132pub struct GroupLabel(pub String);
133
134#[derive(Debug, Clone)]
135pub struct Assist {
136 pub id: AssistId,
137 /// Short description of the assist, as shown in the UI.
138 pub label: Label,
139 pub group: Option<GroupLabel>,
140 /// Target ranges are used to sort assists: the smaller the target range,
141 /// the more specific assist is, and so it should be sorted first.
142 pub target: TextRange,
143 /// Computing source change sometimes is much more costly then computing the
144 /// other fields. Additionally, the actual change is not required to show
145 /// the lightbulb UI, it only is needed when the user tries to apply an
146 /// assist. So, we compute it lazily: the API allow requesting assists with
147 /// or without source change. We could (and in fact, used to) distinguish
148 /// between resolved and unresolved assists at the type level, but this is
149 /// cumbersome, especially if you want to embed an assist into another data
150 /// structure, such as a diagnostic.
151 pub source_change: Option<SourceChange>,
152}
153
154impl Assist {
155 /// Return all the assists applicable at the given position.
156 pub fn get(
157 db: &RootDatabase,
158 config: &AssistConfig,
159 resolve: AssistResolveStrategy,
160 range: FileRange,
161 ) -> Vec<Assist> {
162 let sema = Semantics::new(db);
163 let ctx = AssistContext::new(sema, config, range);
164 let mut acc = Assists::new(&ctx, resolve);
165 handlers::all().iter().for_each(|handler| {
166 handler(&mut acc, &ctx);
167 });
168 acc.finish()
169 }
170} 44}
171 45
172mod handlers { 46mod handlers {
diff --git a/crates/ide_assists/src/path_transform.rs b/crates/ide_assists/src/path_transform.rs
deleted file mode 100644
index 48a7fa06a..000000000
--- a/crates/ide_assists/src/path_transform.rs
+++ /dev/null
@@ -1,160 +0,0 @@
1//! See [`PathTransform`].
2
3use hir::{HirDisplay, SemanticsScope};
4use ide_db::helpers::mod_path_to_ast;
5use rustc_hash::FxHashMap;
6use syntax::{
7 ast::{self, AstNode},
8 ted,
9};
10
11/// `PathTransform` substitutes path in SyntaxNodes in bulk.
12///
13/// This is mostly useful for IDE code generation. If you paste some existing
14/// code into a new context (for example, to add method overrides to an `impl`
15/// block), you generally want to appropriately qualify the names, and sometimes
16/// you might want to substitute generic parameters as well:
17///
18/// ```
19/// mod x {
20/// pub struct A<V>;
21/// pub trait T<U> { fn foo(&self, _: U) -> A<U>; }
22/// }
23///
24/// mod y {
25/// use x::T;
26///
27/// impl T<()> for () {
28/// // If we invoke **Add Missing Members** here, we want to copy-paste `foo`.
29/// // But we want a slightly-modified version of it:
30/// fn foo(&self, _: ()) -> x::A<()> {}
31/// }
32/// }
33/// ```
34pub(crate) struct PathTransform<'a> {
35 pub(crate) subst: (hir::Trait, ast::Impl),
36 pub(crate) target_scope: &'a SemanticsScope<'a>,
37 pub(crate) source_scope: &'a SemanticsScope<'a>,
38}
39
40impl<'a> PathTransform<'a> {
41 pub(crate) fn apply(&self, item: ast::AssocItem) {
42 if let Some(ctx) = self.build_ctx() {
43 ctx.apply(item)
44 }
45 }
46 fn build_ctx(&self) -> Option<Ctx<'a>> {
47 let db = self.source_scope.db;
48 let target_module = self.target_scope.module()?;
49 let source_module = self.source_scope.module()?;
50
51 let substs = get_syntactic_substs(self.subst.1.clone()).unwrap_or_default();
52 let generic_def: hir::GenericDef = self.subst.0.into();
53 let substs_by_param: FxHashMap<_, _> = generic_def
54 .type_params(db)
55 .into_iter()
56 // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
57 .skip(1)
58 // The actual list of trait type parameters may be longer than the one
59 // used in the `impl` block due to trailing default type parameters.
60 // For that case we extend the `substs` with an empty iterator so we
61 // can still hit those trailing values and check if they actually have
62 // a default type. If they do, go for that type from `hir` to `ast` so
63 // the resulting change can be applied correctly.
64 .zip(substs.into_iter().map(Some).chain(std::iter::repeat(None)))
65 .filter_map(|(k, v)| match v {
66 Some(v) => Some((k, v)),
67 None => {
68 let default = k.default(db)?;
69 Some((
70 k,
71 ast::make::ty(&default.display_source_code(db, source_module.into()).ok()?),
72 ))
73 }
74 })
75 .collect();
76
77 let res = Ctx { substs: substs_by_param, target_module, source_scope: self.source_scope };
78 Some(res)
79 }
80}
81
82struct Ctx<'a> {
83 substs: FxHashMap<hir::TypeParam, ast::Type>,
84 target_module: hir::Module,
85 source_scope: &'a SemanticsScope<'a>,
86}
87
88impl<'a> Ctx<'a> {
89 fn apply(&self, item: ast::AssocItem) {
90 for event in item.syntax().preorder() {
91 let node = match event {
92 syntax::WalkEvent::Enter(_) => continue,
93 syntax::WalkEvent::Leave(it) => it,
94 };
95 if let Some(path) = ast::Path::cast(node.clone()) {
96 self.transform_path(path);
97 }
98 }
99 }
100 fn transform_path(&self, path: ast::Path) -> Option<()> {
101 if path.qualifier().is_some() {
102 return None;
103 }
104 if path.segment().and_then(|s| s.param_list()).is_some() {
105 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
106 return None;
107 }
108
109 let resolution = self.source_scope.speculative_resolve(&path)?;
110
111 match resolution {
112 hir::PathResolution::TypeParam(tp) => {
113 if let Some(subst) = self.substs.get(&tp) {
114 ted::replace(path.syntax(), subst.clone_subtree().clone_for_update().syntax())
115 }
116 }
117 hir::PathResolution::Def(def) => {
118 let found_path =
119 self.target_module.find_use_path(self.source_scope.db.upcast(), def)?;
120 let res = mod_path_to_ast(&found_path).clone_for_update();
121 if let Some(args) = path.segment().and_then(|it| it.generic_arg_list()) {
122 if let Some(segment) = res.segment() {
123 let old = segment.get_or_create_generic_arg_list();
124 ted::replace(old.syntax(), args.clone_subtree().syntax().clone_for_update())
125 }
126 }
127 ted::replace(path.syntax(), res.syntax())
128 }
129 hir::PathResolution::Local(_)
130 | hir::PathResolution::ConstParam(_)
131 | hir::PathResolution::SelfType(_)
132 | hir::PathResolution::Macro(_)
133 | hir::PathResolution::AssocItem(_) => (),
134 }
135 Some(())
136 }
137}
138
139// FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
140// trait ref, and then go from the types in the substs back to the syntax).
141fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Vec<ast::Type>> {
142 let target_trait = impl_def.trait_()?;
143 let path_type = match target_trait {
144 ast::Type::PathType(path) => path,
145 _ => return None,
146 };
147 let generic_arg_list = path_type.path()?.segment()?.generic_arg_list()?;
148
149 let mut result = Vec::new();
150 for generic_arg in generic_arg_list.generic_args() {
151 match generic_arg {
152 ast::GenericArg::TypeArg(type_arg) => result.push(type_arg.ty()?),
153 ast::GenericArg::AssocTypeArg(_)
154 | ast::GenericArg::LifetimeArg(_)
155 | ast::GenericArg::ConstArg(_) => (),
156 }
157 }
158
159 Some(result)
160}
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index bdf9cb71c..841537c77 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -16,8 +16,8 @@ use syntax::TextRange;
16use test_utils::{assert_eq_text, extract_offset}; 16use test_utils::{assert_eq_text, extract_offset};
17 17
18use crate::{ 18use crate::{
19 handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, AssistResolveStrategy, 19 assists, handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind,
20 Assists, SingleResolve, 20 AssistResolveStrategy, Assists, SingleResolve,
21}; 21};
22 22
23pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { 23pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
@@ -28,6 +28,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
28 prefix_kind: hir::PrefixKind::Plain, 28 prefix_kind: hir::PrefixKind::Plain,
29 enforce_granularity: true, 29 enforce_granularity: true,
30 group: true, 30 group: true,
31 skip_glob_imports: true,
31 }, 32 },
32}; 33};
33 34
@@ -35,6 +36,7 @@ pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
35 RootDatabase::with_single_file(text) 36 RootDatabase::with_single_file(text)
36} 37}
37 38
39#[track_caller]
38pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) { 40pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
39 let ra_fixture_after = trim_indent(ra_fixture_after); 41 let ra_fixture_after = trim_indent(ra_fixture_after);
40 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None); 42 check(assist, ra_fixture_before, ExpectedResult::After(&ra_fixture_after), None);
@@ -78,14 +80,14 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
78 let before = db.file_text(file_id).to_string(); 80 let before = db.file_text(file_id).to_string();
79 let frange = FileRange { file_id, range: selection.into() }; 81 let frange = FileRange { file_id, range: selection.into() };
80 82
81 let assist = Assist::get(&db, &TEST_CONFIG, AssistResolveStrategy::All, frange) 83 let assist = assists(&db, &TEST_CONFIG, AssistResolveStrategy::All, frange)
82 .into_iter() 84 .into_iter()
83 .find(|assist| assist.id.0 == assist_id) 85 .find(|assist| assist.id.0 == assist_id)
84 .unwrap_or_else(|| { 86 .unwrap_or_else(|| {
85 panic!( 87 panic!(
86 "\n\nAssist is not applicable: {}\nAvailable assists: {}", 88 "\n\nAssist is not applicable: {}\nAvailable assists: {}",
87 assist_id, 89 assist_id,
88 Assist::get(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange) 90 assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange)
89 .into_iter() 91 .into_iter()
90 .map(|assist| assist.id.0) 92 .map(|assist| assist.id.0)
91 .collect::<Vec<_>>() 93 .collect::<Vec<_>>()
@@ -179,9 +181,10 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
179 "unresolved assist should not contain source changes" 181 "unresolved assist should not contain source changes"
180 ), 182 ),
181 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), 183 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
182 (None, ExpectedResult::After(_)) 184 (
183 | (None, ExpectedResult::Target(_)) 185 None,
184 | (None, ExpectedResult::Unresolved) => { 186 ExpectedResult::After(_) | ExpectedResult::Target(_) | ExpectedResult::Unresolved,
187 ) => {
185 panic!("code action is not applicable") 188 panic!("code action is not applicable")
186 } 189 }
187 (None, ExpectedResult::NotApplicable) => (), 190 (None, ExpectedResult::NotApplicable) => (),
@@ -210,7 +213,7 @@ fn assist_order_field_struct() {
210 let (before_cursor_pos, before) = extract_offset(before); 213 let (before_cursor_pos, before) = extract_offset(before);
211 let (db, file_id) = with_single_file(&before); 214 let (db, file_id) = with_single_file(&before);
212 let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; 215 let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) };
213 let assists = Assist::get(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange); 216 let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange);
214 let mut assists = assists.iter(); 217 let mut assists = assists.iter();
215 218
216 assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)"); 219 assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)");
@@ -235,7 +238,7 @@ pub fn test_some_range(a: int) -> bool {
235"#, 238"#,
236 ); 239 );
237 240
238 let assists = Assist::get(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange); 241 let assists = assists(&db, &TEST_CONFIG, AssistResolveStrategy::None, frange);
239 let expected = labels(&assists); 242 let expected = labels(&assists);
240 243
241 expect![[r#" 244 expect![[r#"
@@ -264,7 +267,7 @@ pub fn test_some_range(a: int) -> bool {
264 let mut cfg = TEST_CONFIG; 267 let mut cfg = TEST_CONFIG;
265 cfg.allowed = Some(vec![AssistKind::Refactor]); 268 cfg.allowed = Some(vec![AssistKind::Refactor]);
266 269
267 let assists = Assist::get(&db, &cfg, AssistResolveStrategy::None, frange); 270 let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange);
268 let expected = labels(&assists); 271 let expected = labels(&assists);
269 272
270 expect![[r#" 273 expect![[r#"
@@ -279,7 +282,7 @@ pub fn test_some_range(a: int) -> bool {
279 { 282 {
280 let mut cfg = TEST_CONFIG; 283 let mut cfg = TEST_CONFIG;
281 cfg.allowed = Some(vec![AssistKind::RefactorExtract]); 284 cfg.allowed = Some(vec![AssistKind::RefactorExtract]);
282 let assists = Assist::get(&db, &cfg, AssistResolveStrategy::None, frange); 285 let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange);
283 let expected = labels(&assists); 286 let expected = labels(&assists);
284 287
285 expect![[r#" 288 expect![[r#"
@@ -292,7 +295,7 @@ pub fn test_some_range(a: int) -> bool {
292 { 295 {
293 let mut cfg = TEST_CONFIG; 296 let mut cfg = TEST_CONFIG;
294 cfg.allowed = Some(vec![AssistKind::QuickFix]); 297 cfg.allowed = Some(vec![AssistKind::QuickFix]);
295 let assists = Assist::get(&db, &cfg, AssistResolveStrategy::None, frange); 298 let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange);
296 let expected = labels(&assists); 299 let expected = labels(&assists);
297 300
298 expect![[r#""#]].assert_eq(&expected); 301 expect![[r#""#]].assert_eq(&expected);
@@ -317,7 +320,7 @@ pub fn test_some_range(a: int) -> bool {
317 cfg.allowed = Some(vec![AssistKind::RefactorExtract]); 320 cfg.allowed = Some(vec![AssistKind::RefactorExtract]);
318 321
319 { 322 {
320 let assists = Assist::get(&db, &cfg, AssistResolveStrategy::None, frange); 323 let assists = assists(&db, &cfg, AssistResolveStrategy::None, frange);
321 assert_eq!(2, assists.len()); 324 assert_eq!(2, assists.len());
322 let mut assists = assists.into_iter(); 325 let mut assists = assists.into_iter();
323 326
@@ -353,7 +356,7 @@ pub fn test_some_range(a: int) -> bool {
353 } 356 }
354 357
355 { 358 {
356 let assists = Assist::get( 359 let assists = assists(
357 &db, 360 &db,
358 &cfg, 361 &cfg,
359 AssistResolveStrategy::Single(SingleResolve { 362 AssistResolveStrategy::Single(SingleResolve {
@@ -397,7 +400,7 @@ pub fn test_some_range(a: int) -> bool {
397 } 400 }
398 401
399 { 402 {
400 let assists = Assist::get( 403 let assists = assists(
401 &db, 404 &db,
402 &cfg, 405 &cfg,
403 AssistResolveStrategy::Single(SingleResolve { 406 AssistResolveStrategy::Single(SingleResolve {
@@ -462,7 +465,7 @@ pub fn test_some_range(a: int) -> bool {
462 } 465 }
463 466
464 { 467 {
465 let assists = Assist::get(&db, &cfg, AssistResolveStrategy::All, frange); 468 let assists = assists(&db, &cfg, AssistResolveStrategy::All, frange);
466 assert_eq!(2, assists.len()); 469 assert_eq!(2, assists.len());
467 let mut assists = assists.into_iter(); 470 let mut assists = assists.into_iter();
468 471
diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs
index de5d9e55a..1509c3c63 100644
--- a/crates/ide_assists/src/tests/generated.rs
+++ b/crates/ide_assists/src/tests/generated.rs
@@ -209,10 +209,7 @@ fn doctest_convert_into_to_from() {
209 check_doc_test( 209 check_doc_test(
210 "convert_into_to_from", 210 "convert_into_to_from",
211 r#####" 211 r#####"
212//- /lib.rs crate:core 212//- minicore: from
213pub mod convert { pub trait Into<T> { pub fn into(self) -> T; } }
214//- /lib.rs crate:main deps:core
215use core::convert::Into;
216impl $0Into<Thing> for usize { 213impl $0Into<Thing> for usize {
217 fn into(self) -> Thing { 214 fn into(self) -> Thing {
218 Thing { 215 Thing {
@@ -223,7 +220,6 @@ impl $0Into<Thing> for usize {
223} 220}
224"#####, 221"#####,
225 r#####" 222 r#####"
226use core::convert::Into;
227impl From<usize> for Thing { 223impl From<usize> for Thing {
228 fn from(val: usize) -> Self { 224 fn from(val: usize) -> Self {
229 Thing { 225 Thing {
@@ -241,23 +237,19 @@ fn doctest_convert_iter_for_each_to_for() {
241 check_doc_test( 237 check_doc_test(
242 "convert_iter_for_each_to_for", 238 "convert_iter_for_each_to_for",
243 r#####" 239 r#####"
244//- /lib.rs crate:core 240//- minicore: iterators
245pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } } 241use core::iter;
246pub struct SomeIter;
247impl self::iter::traits::iterator::Iterator for SomeIter {}
248//- /lib.rs crate:main deps:core
249use core::SomeIter;
250fn main() { 242fn main() {
251 let iter = SomeIter; 243 let iter = iter::repeat((9, 2));
252 iter.for_each$0(|(x, y)| { 244 iter.for_each$0(|(x, y)| {
253 println!("x: {}, y: {}", x, y); 245 println!("x: {}, y: {}", x, y);
254 }); 246 });
255} 247}
256"#####, 248"#####,
257 r#####" 249 r#####"
258use core::SomeIter; 250use core::iter;
259fn main() { 251fn main() {
260 let iter = SomeIter; 252 let iter = iter::repeat((9, 2));
261 for (x, y) in iter { 253 for (x, y) in iter {
262 println!("x: {}, y: {}", x, y); 254 println!("x: {}, y: {}", x, y);
263 } 255 }
@@ -1519,16 +1511,15 @@ fn doctest_replace_unwrap_with_match() {
1519 check_doc_test( 1511 check_doc_test(
1520 "replace_unwrap_with_match", 1512 "replace_unwrap_with_match",
1521 r#####" 1513 r#####"
1522enum Result<T, E> { Ok(T), Err(E) } 1514//- minicore: result
1523fn main() { 1515fn main() {
1524 let x: Result<i32, i32> = Result::Ok(92); 1516 let x: Result<i32, i32> = Ok(92);
1525 let y = x.$0unwrap(); 1517 let y = x.$0unwrap();
1526} 1518}
1527"#####, 1519"#####,
1528 r#####" 1520 r#####"
1529enum Result<T, E> { Ok(T), Err(E) }
1530fn main() { 1521fn main() {
1531 let x: Result<i32, i32> = Result::Ok(92); 1522 let x: Result<i32, i32> = Ok(92);
1532 let y = match x { 1523 let y = match x {
1533 Ok(it) => it, 1524 Ok(it) => it,
1534 $0_ => unreachable!(), 1525 $0_ => unreachable!(),
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs
index 068df005b..0ec236aa0 100644
--- a/crates/ide_assists/src/utils.rs
+++ b/crates/ide_assists/src/utils.rs
@@ -8,6 +8,7 @@ use ast::TypeBoundsOwner;
8use hir::{Adt, HasSource, Semantics}; 8use hir::{Adt, HasSource, Semantics};
9use ide_db::{ 9use ide_db::{
10 helpers::{FamousDefs, SnippetCap}, 10 helpers::{FamousDefs, SnippetCap},
11 path_transform::PathTransform,
11 RootDatabase, 12 RootDatabase,
12}; 13};
13use itertools::Itertools; 14use itertools::Itertools;
@@ -22,10 +23,7 @@ use syntax::{
22 SyntaxNode, TextSize, T, 23 SyntaxNode, TextSize, T,
23}; 24};
24 25
25use crate::{ 26use crate::assist_context::{AssistBuilder, AssistContext};
26 assist_context::{AssistBuilder, AssistContext},
27 path_transform::PathTransform,
28};
29 27
30pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { 28pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
31 extract_trivial_expression(&block) 29 extract_trivial_expression(&block)