diff options
Diffstat (limited to 'crates')
72 files changed, 1194 insertions, 1158 deletions
diff --git a/crates/ra_assists/src/handlers/add_explicit_type.rs b/crates/ra_assists/src/handlers/add_explicit_type.rs index 770049212..ab20c6649 100644 --- a/crates/ra_assists/src/handlers/add_explicit_type.rs +++ b/crates/ra_assists/src/handlers/add_explicit_type.rs | |||
@@ -86,11 +86,7 @@ mod tests { | |||
86 | 86 | ||
87 | #[test] | 87 | #[test] |
88 | fn add_explicit_type_works_for_simple_expr() { | 88 | fn add_explicit_type_works_for_simple_expr() { |
89 | check_assist( | 89 | check_assist(add_explicit_type, "fn f() { let a<|> = 1; }", "fn f() { let a: i32 = 1; }"); |
90 | add_explicit_type, | ||
91 | "fn f() { let a<|> = 1; }", | ||
92 | "fn f() { let a<|>: i32 = 1; }", | ||
93 | ); | ||
94 | } | 90 | } |
95 | 91 | ||
96 | #[test] | 92 | #[test] |
@@ -98,7 +94,7 @@ mod tests { | |||
98 | check_assist( | 94 | check_assist( |
99 | add_explicit_type, | 95 | add_explicit_type, |
100 | "fn f() { let a<|>: _ = 1; }", | 96 | "fn f() { let a<|>: _ = 1; }", |
101 | "fn f() { let a<|>: i32 = 1; }", | 97 | "fn f() { let a: i32 = 1; }", |
102 | ); | 98 | ); |
103 | } | 99 | } |
104 | 100 | ||
@@ -122,7 +118,7 @@ mod tests { | |||
122 | } | 118 | } |
123 | 119 | ||
124 | fn f() { | 120 | fn f() { |
125 | let a<|>: Option<i32> = Option::Some(1); | 121 | let a: Option<i32> = Option::Some(1); |
126 | }"#, | 122 | }"#, |
127 | ); | 123 | ); |
128 | } | 124 | } |
@@ -132,7 +128,7 @@ mod tests { | |||
132 | check_assist( | 128 | check_assist( |
133 | add_explicit_type, | 129 | add_explicit_type, |
134 | r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }", | 130 | r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }", |
135 | r"macro_rules! v { () => {0u64} } fn f() { let a<|>: u64 = v!(); }", | 131 | r"macro_rules! v { () => {0u64} } fn f() { let a: u64 = v!(); }", |
136 | ); | 132 | ); |
137 | } | 133 | } |
138 | 134 | ||
@@ -140,8 +136,8 @@ mod tests { | |||
140 | fn add_explicit_type_works_for_macro_call_recursive() { | 136 | fn add_explicit_type_works_for_macro_call_recursive() { |
141 | check_assist( | 137 | check_assist( |
142 | add_explicit_type, | 138 | add_explicit_type, |
143 | "macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|> = v!(); }", | 139 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|> = v!(); }"#, |
144 | "macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|>: u64 = v!(); }", | 140 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a: u64 = v!(); }"#, |
145 | ); | 141 | ); |
146 | } | 142 | } |
147 | 143 | ||
@@ -208,7 +204,7 @@ struct Test<K, T = u8> { | |||
208 | } | 204 | } |
209 | 205 | ||
210 | fn main() { | 206 | fn main() { |
211 | let test<|>: Test<i32> = Test { t: 23, k: 33 }; | 207 | let test: Test<i32> = Test { t: 23, k: 33 }; |
212 | }"#, | 208 | }"#, |
213 | ); | 209 | ); |
214 | } | 210 | } |
diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs index eb57b7231..6a675e812 100644 --- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs +++ b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_ide_db::RootDatabase; | 1 | use ra_ide_db::RootDatabase; |
2 | use ra_syntax::ast::{self, AstNode, NameOwner}; | 2 | use ra_syntax::ast::{self, AstNode, NameOwner}; |
3 | use test_utils::tested_by; | 3 | use test_utils::mark; |
4 | 4 | ||
5 | use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; | 5 | use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; |
6 | 6 | ||
@@ -39,7 +39,7 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | if existing_from_impl(&ctx.sema, &variant).is_some() { | 41 | if existing_from_impl(&ctx.sema, &variant).is_some() { |
42 | tested_by!(test_add_from_impl_already_exists); | 42 | mark::hit!(test_add_from_impl_already_exists); |
43 | return None; | 43 | return None; |
44 | } | 44 | } |
45 | 45 | ||
@@ -90,7 +90,7 @@ fn existing_from_impl( | |||
90 | 90 | ||
91 | #[cfg(test)] | 91 | #[cfg(test)] |
92 | mod tests { | 92 | mod tests { |
93 | use test_utils::covers; | 93 | use test_utils::mark; |
94 | 94 | ||
95 | use crate::tests::{check_assist, check_assist_not_applicable}; | 95 | use crate::tests::{check_assist, check_assist_not_applicable}; |
96 | 96 | ||
@@ -101,7 +101,7 @@ mod tests { | |||
101 | check_assist( | 101 | check_assist( |
102 | add_from_impl_for_enum, | 102 | add_from_impl_for_enum, |
103 | "enum A { <|>One(u32) }", | 103 | "enum A { <|>One(u32) }", |
104 | r#"enum A { <|>One(u32) } | 104 | r#"enum A { One(u32) } |
105 | 105 | ||
106 | impl From<u32> for A { | 106 | impl From<u32> for A { |
107 | fn from(v: u32) -> Self { | 107 | fn from(v: u32) -> Self { |
@@ -116,7 +116,7 @@ impl From<u32> for A { | |||
116 | check_assist( | 116 | check_assist( |
117 | add_from_impl_for_enum, | 117 | add_from_impl_for_enum, |
118 | r#"enum A { <|>One(foo::bar::baz::Boo) }"#, | 118 | r#"enum A { <|>One(foo::bar::baz::Boo) }"#, |
119 | r#"enum A { <|>One(foo::bar::baz::Boo) } | 119 | r#"enum A { One(foo::bar::baz::Boo) } |
120 | 120 | ||
121 | impl From<foo::bar::baz::Boo> for A { | 121 | impl From<foo::bar::baz::Boo> for A { |
122 | fn from(v: foo::bar::baz::Boo) -> Self { | 122 | fn from(v: foo::bar::baz::Boo) -> Self { |
@@ -149,7 +149,7 @@ impl From<foo::bar::baz::Boo> for A { | |||
149 | 149 | ||
150 | #[test] | 150 | #[test] |
151 | fn test_add_from_impl_already_exists() { | 151 | fn test_add_from_impl_already_exists() { |
152 | covers!(test_add_from_impl_already_exists); | 152 | mark::check!(test_add_from_impl_already_exists); |
153 | check_not_applicable( | 153 | check_not_applicable( |
154 | r#" | 154 | r#" |
155 | enum A { <|>One(u32), } | 155 | enum A { <|>One(u32), } |
@@ -178,7 +178,7 @@ impl From<String> for A { | |||
178 | pub trait From<T> { | 178 | pub trait From<T> { |
179 | fn from(T) -> Self; | 179 | fn from(T) -> Self; |
180 | }"#, | 180 | }"#, |
181 | r#"enum A { <|>One(u32), Two(String), } | 181 | r#"enum A { One(u32), Two(String), } |
182 | 182 | ||
183 | impl From<u32> for A { | 183 | impl From<u32> for A { |
184 | fn from(v: u32) -> Self { | 184 | fn from(v: u32) -> Self { |
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs index fe7451dcf..837aa8377 100644 --- a/crates/ra_assists/src/handlers/add_new.rs +++ b/crates/ra_assists/src/handlers/add_new.rs | |||
@@ -3,7 +3,7 @@ use ra_syntax::{ | |||
3 | ast::{ | 3 | ast::{ |
4 | self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, | 4 | self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, |
5 | }, | 5 | }, |
6 | TextSize, T, | 6 | T, |
7 | }; | 7 | }; |
8 | use stdx::{format_to, SepBy}; | 8 | use stdx::{format_to, SepBy}; |
9 | 9 | ||
@@ -25,7 +25,7 @@ use crate::{AssistContext, AssistId, Assists}; | |||
25 | // } | 25 | // } |
26 | // | 26 | // |
27 | // impl<T: Clone> Ctx<T> { | 27 | // impl<T: Clone> Ctx<T> { |
28 | // fn new(data: T) -> Self { Self { data } } | 28 | // fn $0new(data: T) -> Self { Self { data } } |
29 | // } | 29 | // } |
30 | // | 30 | // |
31 | // ``` | 31 | // ``` |
@@ -42,31 +42,26 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
42 | let impl_def = find_struct_impl(&ctx, &strukt)?; | 42 | let impl_def = find_struct_impl(&ctx, &strukt)?; |
43 | 43 | ||
44 | let target = strukt.syntax().text_range(); | 44 | let target = strukt.syntax().text_range(); |
45 | acc.add(AssistId("add_new"), "Add default constructor", target, |edit| { | 45 | acc.add(AssistId("add_new"), "Add default constructor", target, |builder| { |
46 | let mut buf = String::with_capacity(512); | 46 | let mut buf = String::with_capacity(512); |
47 | 47 | ||
48 | if impl_def.is_some() { | 48 | if impl_def.is_some() { |
49 | buf.push('\n'); | 49 | buf.push('\n'); |
50 | } | 50 | } |
51 | 51 | ||
52 | let vis = strukt.visibility().map(|v| format!("{} ", v)); | 52 | let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); |
53 | let vis = vis.as_deref().unwrap_or(""); | ||
54 | 53 | ||
55 | let params = field_list | 54 | let params = field_list |
56 | .fields() | 55 | .fields() |
57 | .filter_map(|f| { | 56 | .filter_map(|f| { |
58 | Some(format!( | 57 | Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax())) |
59 | "{}: {}", | ||
60 | f.name()?.syntax().text(), | ||
61 | f.ascribed_type()?.syntax().text() | ||
62 | )) | ||
63 | }) | 58 | }) |
64 | .sep_by(", "); | 59 | .sep_by(", "); |
65 | let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); | 60 | let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); |
66 | 61 | ||
67 | format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); | 62 | format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); |
68 | 63 | ||
69 | let (start_offset, end_offset) = impl_def | 64 | let start_offset = impl_def |
70 | .and_then(|impl_def| { | 65 | .and_then(|impl_def| { |
71 | buf.push('\n'); | 66 | buf.push('\n'); |
72 | let start = impl_def | 67 | let start = impl_def |
@@ -76,17 +71,20 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
76 | .text_range() | 71 | .text_range() |
77 | .end(); | 72 | .end(); |
78 | 73 | ||
79 | Some((start, TextSize::of("\n"))) | 74 | Some(start) |
80 | }) | 75 | }) |
81 | .unwrap_or_else(|| { | 76 | .unwrap_or_else(|| { |
82 | buf = generate_impl_text(&strukt, &buf); | 77 | buf = generate_impl_text(&strukt, &buf); |
83 | let start = strukt.syntax().text_range().end(); | 78 | strukt.syntax().text_range().end() |
84 | |||
85 | (start, TextSize::of("\n}\n")) | ||
86 | }); | 79 | }); |
87 | 80 | ||
88 | edit.set_cursor(start_offset + TextSize::of(&buf) - end_offset); | 81 | match ctx.config.snippet_cap { |
89 | edit.insert(start_offset, buf); | 82 | None => builder.insert(start_offset, buf), |
83 | Some(cap) => { | ||
84 | buf = buf.replace("fn new", "fn $0new"); | ||
85 | builder.insert_snippet(cap, start_offset, buf); | ||
86 | } | ||
87 | } | ||
90 | }) | 88 | }) |
91 | } | 89 | } |
92 | 90 | ||
@@ -191,7 +189,7 @@ mod tests { | |||
191 | "struct Foo {} | 189 | "struct Foo {} |
192 | 190 | ||
193 | impl Foo { | 191 | impl Foo { |
194 | fn new() -> Self { Self { } }<|> | 192 | fn $0new() -> Self { Self { } } |
195 | } | 193 | } |
196 | ", | 194 | ", |
197 | ); | 195 | ); |
@@ -201,7 +199,7 @@ impl Foo { | |||
201 | "struct Foo<T: Clone> {} | 199 | "struct Foo<T: Clone> {} |
202 | 200 | ||
203 | impl<T: Clone> Foo<T> { | 201 | impl<T: Clone> Foo<T> { |
204 | fn new() -> Self { Self { } }<|> | 202 | fn $0new() -> Self { Self { } } |
205 | } | 203 | } |
206 | ", | 204 | ", |
207 | ); | 205 | ); |
@@ -211,7 +209,7 @@ impl<T: Clone> Foo<T> { | |||
211 | "struct Foo<'a, T: Foo<'a>> {} | 209 | "struct Foo<'a, T: Foo<'a>> {} |
212 | 210 | ||
213 | impl<'a, T: Foo<'a>> Foo<'a, T> { | 211 | impl<'a, T: Foo<'a>> Foo<'a, T> { |
214 | fn new() -> Self { Self { } }<|> | 212 | fn $0new() -> Self { Self { } } |
215 | } | 213 | } |
216 | ", | 214 | ", |
217 | ); | 215 | ); |
@@ -221,7 +219,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> { | |||
221 | "struct Foo { baz: String } | 219 | "struct Foo { baz: String } |
222 | 220 | ||
223 | impl Foo { | 221 | impl Foo { |
224 | fn new(baz: String) -> Self { Self { baz } }<|> | 222 | fn $0new(baz: String) -> Self { Self { baz } } |
225 | } | 223 | } |
226 | ", | 224 | ", |
227 | ); | 225 | ); |
@@ -231,7 +229,7 @@ impl Foo { | |||
231 | "struct Foo { baz: String, qux: Vec<i32> } | 229 | "struct Foo { baz: String, qux: Vec<i32> } |
232 | 230 | ||
233 | impl Foo { | 231 | impl Foo { |
234 | fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> | 232 | fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } } |
235 | } | 233 | } |
236 | ", | 234 | ", |
237 | ); | 235 | ); |
@@ -243,7 +241,7 @@ impl Foo { | |||
243 | "struct Foo { pub baz: String, pub qux: Vec<i32> } | 241 | "struct Foo { pub baz: String, pub qux: Vec<i32> } |
244 | 242 | ||
245 | impl Foo { | 243 | impl Foo { |
246 | fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> | 244 | fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } } |
247 | } | 245 | } |
248 | ", | 246 | ", |
249 | ); | 247 | ); |
@@ -258,7 +256,7 @@ impl Foo {} | |||
258 | "struct Foo {} | 256 | "struct Foo {} |
259 | 257 | ||
260 | impl Foo { | 258 | impl Foo { |
261 | fn new() -> Self { Self { } }<|> | 259 | fn $0new() -> Self { Self { } } |
262 | } | 260 | } |
263 | ", | 261 | ", |
264 | ); | 262 | ); |
@@ -273,7 +271,7 @@ impl Foo { | |||
273 | "struct Foo {} | 271 | "struct Foo {} |
274 | 272 | ||
275 | impl Foo { | 273 | impl Foo { |
276 | fn new() -> Self { Self { } }<|> | 274 | fn $0new() -> Self { Self { } } |
277 | 275 | ||
278 | fn qux(&self) {} | 276 | fn qux(&self) {} |
279 | } | 277 | } |
@@ -294,7 +292,7 @@ impl Foo { | |||
294 | "struct Foo {} | 292 | "struct Foo {} |
295 | 293 | ||
296 | impl Foo { | 294 | impl Foo { |
297 | fn new() -> Self { Self { } }<|> | 295 | fn $0new() -> Self { Self { } } |
298 | 296 | ||
299 | fn qux(&self) {} | 297 | fn qux(&self) {} |
300 | fn baz() -> i32 { | 298 | fn baz() -> i32 { |
@@ -311,7 +309,7 @@ impl Foo { | |||
311 | "pub struct Foo {} | 309 | "pub struct Foo {} |
312 | 310 | ||
313 | impl Foo { | 311 | impl Foo { |
314 | pub fn new() -> Self { Self { } }<|> | 312 | pub fn $0new() -> Self { Self { } } |
315 | } | 313 | } |
316 | ", | 314 | ", |
317 | ); | 315 | ); |
@@ -321,7 +319,7 @@ impl Foo { | |||
321 | "pub(crate) struct Foo {} | 319 | "pub(crate) struct Foo {} |
322 | 320 | ||
323 | impl Foo { | 321 | impl Foo { |
324 | pub(crate) fn new() -> Self { Self { } }<|> | 322 | pub(crate) fn $0new() -> Self { Self { } } |
325 | } | 323 | } |
326 | ", | 324 | ", |
327 | ); | 325 | ); |
@@ -414,7 +412,7 @@ pub struct Source<T> { | |||
414 | } | 412 | } |
415 | 413 | ||
416 | impl<T> Source<T> { | 414 | impl<T> Source<T> { |
417 | pub fn new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }<|> | 415 | pub fn $0new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } } |
418 | 416 | ||
419 | pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { | 417 | pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { |
420 | Source { file_id: self.file_id, ast: f(self.ast) } | 418 | Source { file_id: self.file_id, ast: f(self.ast) } |
diff --git a/crates/ra_assists/src/handlers/add_turbo_fish.rs b/crates/ra_assists/src/handlers/add_turbo_fish.rs index a0363bc78..26acf81f2 100644 --- a/crates/ra_assists/src/handlers/add_turbo_fish.rs +++ b/crates/ra_assists/src/handlers/add_turbo_fish.rs | |||
@@ -1,11 +1,11 @@ | |||
1 | use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass}; | 1 | use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass}; |
2 | use ra_syntax::{ast, AstNode, SyntaxKind, T}; | 2 | use ra_syntax::{ast, AstNode, SyntaxKind, T}; |
3 | use test_utils::mark; | ||
3 | 4 | ||
4 | use crate::{ | 5 | use crate::{ |
5 | assist_context::{AssistContext, Assists}, | 6 | assist_context::{AssistContext, Assists}, |
6 | AssistId, | 7 | AssistId, |
7 | }; | 8 | }; |
8 | use test_utils::tested_by; | ||
9 | 9 | ||
10 | // Assist: add_turbo_fish | 10 | // Assist: add_turbo_fish |
11 | // | 11 | // |
@@ -28,7 +28,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
28 | let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?; | 28 | let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?; |
29 | let next_token = ident.next_token()?; | 29 | let next_token = ident.next_token()?; |
30 | if next_token.kind() == T![::] { | 30 | if next_token.kind() == T![::] { |
31 | tested_by!(add_turbo_fish_one_fish_is_enough); | 31 | mark::hit!(add_turbo_fish_one_fish_is_enough); |
32 | return None; | 32 | return None; |
33 | } | 33 | } |
34 | let name_ref = ast::NameRef::cast(ident.parent())?; | 34 | let name_ref = ast::NameRef::cast(ident.parent())?; |
@@ -42,7 +42,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
42 | }; | 42 | }; |
43 | let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); | 43 | let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); |
44 | if generics.is_empty() { | 44 | if generics.is_empty() { |
45 | tested_by!(add_turbo_fish_non_generic); | 45 | mark::hit!(add_turbo_fish_non_generic); |
46 | return None; | 46 | return None; |
47 | } | 47 | } |
48 | acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| { | 48 | acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| { |
@@ -58,7 +58,7 @@ mod tests { | |||
58 | use crate::tests::{check_assist, check_assist_not_applicable}; | 58 | use crate::tests::{check_assist, check_assist_not_applicable}; |
59 | 59 | ||
60 | use super::*; | 60 | use super::*; |
61 | use test_utils::covers; | 61 | use test_utils::mark; |
62 | 62 | ||
63 | #[test] | 63 | #[test] |
64 | fn add_turbo_fish_function() { | 64 | fn add_turbo_fish_function() { |
@@ -106,7 +106,7 @@ fn main() { | |||
106 | 106 | ||
107 | #[test] | 107 | #[test] |
108 | fn add_turbo_fish_one_fish_is_enough() { | 108 | fn add_turbo_fish_one_fish_is_enough() { |
109 | covers!(add_turbo_fish_one_fish_is_enough); | 109 | mark::check!(add_turbo_fish_one_fish_is_enough); |
110 | check_assist_not_applicable( | 110 | check_assist_not_applicable( |
111 | add_turbo_fish, | 111 | add_turbo_fish, |
112 | r#" | 112 | r#" |
@@ -120,7 +120,7 @@ fn main() { | |||
120 | 120 | ||
121 | #[test] | 121 | #[test] |
122 | fn add_turbo_fish_non_generic() { | 122 | fn add_turbo_fish_non_generic() { |
123 | covers!(add_turbo_fish_non_generic); | 123 | mark::check!(add_turbo_fish_non_generic); |
124 | check_assist_not_applicable( | 124 | check_assist_not_applicable( |
125 | add_turbo_fish, | 125 | add_turbo_fish, |
126 | r#" | 126 | r#" |
diff --git a/crates/ra_assists/src/handlers/apply_demorgan.rs b/crates/ra_assists/src/handlers/apply_demorgan.rs index 0feba5e11..233e8fb8e 100644 --- a/crates/ra_assists/src/handlers/apply_demorgan.rs +++ b/crates/ra_assists/src/handlers/apply_demorgan.rs | |||
@@ -63,22 +63,22 @@ mod tests { | |||
63 | 63 | ||
64 | #[test] | 64 | #[test] |
65 | fn demorgan_turns_and_into_or() { | 65 | fn demorgan_turns_and_into_or() { |
66 | check_assist(apply_demorgan, "fn f() { !x &&<|> !x }", "fn f() { !(x ||<|> x) }") | 66 | check_assist(apply_demorgan, "fn f() { !x &&<|> !x }", "fn f() { !(x || x) }") |
67 | } | 67 | } |
68 | 68 | ||
69 | #[test] | 69 | #[test] |
70 | fn demorgan_turns_or_into_and() { | 70 | fn demorgan_turns_or_into_and() { |
71 | check_assist(apply_demorgan, "fn f() { !x ||<|> !x }", "fn f() { !(x &&<|> x) }") | 71 | check_assist(apply_demorgan, "fn f() { !x ||<|> !x }", "fn f() { !(x && x) }") |
72 | } | 72 | } |
73 | 73 | ||
74 | #[test] | 74 | #[test] |
75 | fn demorgan_removes_inequality() { | 75 | fn demorgan_removes_inequality() { |
76 | check_assist(apply_demorgan, "fn f() { x != x ||<|> !x }", "fn f() { !(x == x &&<|> x) }") | 76 | check_assist(apply_demorgan, "fn f() { x != x ||<|> !x }", "fn f() { !(x == x && x) }") |
77 | } | 77 | } |
78 | 78 | ||
79 | #[test] | 79 | #[test] |
80 | fn demorgan_general_case() { | 80 | fn demorgan_general_case() { |
81 | check_assist(apply_demorgan, "fn f() { x ||<|> x }", "fn f() { !(!x &&<|> !x) }") | 81 | check_assist(apply_demorgan, "fn f() { x ||<|> x }", "fn f() { !(!x && !x) }") |
82 | } | 82 | } |
83 | 83 | ||
84 | #[test] | 84 | #[test] |
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs index 78d23150d..edf96d50e 100644 --- a/crates/ra_assists/src/handlers/auto_import.rs +++ b/crates/ra_assists/src/handlers/auto_import.rs | |||
@@ -50,7 +50,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
50 | format!("Import `{}`", &import), | 50 | format!("Import `{}`", &import), |
51 | range, | 51 | range, |
52 | |builder| { | 52 | |builder| { |
53 | insert_use_statement(&auto_import_assets.syntax_under_caret, &import, ctx, builder); | 53 | insert_use_statement( |
54 | &auto_import_assets.syntax_under_caret, | ||
55 | &import, | ||
56 | ctx, | ||
57 | builder.text_edit_builder(), | ||
58 | ); | ||
54 | }, | 59 | }, |
55 | ); | 60 | ); |
56 | } | 61 | } |
@@ -293,7 +298,7 @@ mod tests { | |||
293 | } | 298 | } |
294 | ", | 299 | ", |
295 | r" | 300 | r" |
296 | <|>use PubMod::PubStruct; | 301 | use PubMod::PubStruct; |
297 | 302 | ||
298 | PubStruct | 303 | PubStruct |
299 | 304 | ||
@@ -324,7 +329,7 @@ mod tests { | |||
324 | macro_rules! foo { | 329 | macro_rules! foo { |
325 | ($i:ident) => { fn foo(a: $i) {} } | 330 | ($i:ident) => { fn foo(a: $i) {} } |
326 | } | 331 | } |
327 | foo!(Pub<|>Struct); | 332 | foo!(PubStruct); |
328 | 333 | ||
329 | pub mod PubMod { | 334 | pub mod PubMod { |
330 | pub struct PubStruct; | 335 | pub struct PubStruct; |
@@ -355,7 +360,7 @@ mod tests { | |||
355 | use PubMod::{PubStruct2, PubStruct1}; | 360 | use PubMod::{PubStruct2, PubStruct1}; |
356 | 361 | ||
357 | struct Test { | 362 | struct Test { |
358 | test: Pub<|>Struct2<u8>, | 363 | test: PubStruct2<u8>, |
359 | } | 364 | } |
360 | 365 | ||
361 | pub mod PubMod { | 366 | pub mod PubMod { |
@@ -388,7 +393,7 @@ mod tests { | |||
388 | r" | 393 | r" |
389 | use PubMod3::PubStruct; | 394 | use PubMod3::PubStruct; |
390 | 395 | ||
391 | PubSt<|>ruct | 396 | PubStruct |
392 | 397 | ||
393 | pub mod PubMod1 { | 398 | pub mod PubMod1 { |
394 | pub struct PubStruct; | 399 | pub struct PubStruct; |
@@ -469,7 +474,7 @@ mod tests { | |||
469 | r" | 474 | r" |
470 | use PubMod::test_function; | 475 | use PubMod::test_function; |
471 | 476 | ||
472 | test_function<|> | 477 | test_function |
473 | 478 | ||
474 | pub mod PubMod { | 479 | pub mod PubMod { |
475 | pub fn test_function() {}; | 480 | pub fn test_function() {}; |
@@ -496,7 +501,7 @@ mod tests { | |||
496 | r"use crate_with_macro::foo; | 501 | r"use crate_with_macro::foo; |
497 | 502 | ||
498 | fn main() { | 503 | fn main() { |
499 | foo<|> | 504 | foo |
500 | } | 505 | } |
501 | ", | 506 | ", |
502 | ); | 507 | ); |
@@ -582,7 +587,7 @@ fn main() { | |||
582 | } | 587 | } |
583 | 588 | ||
584 | fn main() { | 589 | fn main() { |
585 | TestStruct::test_function<|> | 590 | TestStruct::test_function |
586 | } | 591 | } |
587 | ", | 592 | ", |
588 | ); | 593 | ); |
@@ -615,7 +620,7 @@ fn main() { | |||
615 | } | 620 | } |
616 | 621 | ||
617 | fn main() { | 622 | fn main() { |
618 | TestStruct::TEST_CONST<|> | 623 | TestStruct::TEST_CONST |
619 | } | 624 | } |
620 | ", | 625 | ", |
621 | ); | 626 | ); |
@@ -654,7 +659,7 @@ fn main() { | |||
654 | } | 659 | } |
655 | 660 | ||
656 | fn main() { | 661 | fn main() { |
657 | test_mod::TestStruct::test_function<|> | 662 | test_mod::TestStruct::test_function |
658 | } | 663 | } |
659 | ", | 664 | ", |
660 | ); | 665 | ); |
@@ -725,7 +730,7 @@ fn main() { | |||
725 | } | 730 | } |
726 | 731 | ||
727 | fn main() { | 732 | fn main() { |
728 | test_mod::TestStruct::TEST_CONST<|> | 733 | test_mod::TestStruct::TEST_CONST |
729 | } | 734 | } |
730 | ", | 735 | ", |
731 | ); | 736 | ); |
@@ -798,7 +803,7 @@ fn main() { | |||
798 | 803 | ||
799 | fn main() { | 804 | fn main() { |
800 | let test_struct = test_mod::TestStruct {}; | 805 | let test_struct = test_mod::TestStruct {}; |
801 | test_struct.test_meth<|>od() | 806 | test_struct.test_method() |
802 | } | 807 | } |
803 | ", | 808 | ", |
804 | ); | 809 | ); |
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index 5c907097e..c6baa0a57 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs | |||
@@ -1,8 +1,6 @@ | |||
1 | use ra_syntax::{ | 1 | use ra_syntax::{ |
2 | ast::{self, BlockExpr, Expr, LoopBodyOwner}, | 2 | ast::{self, BlockExpr, Expr, LoopBodyOwner}, |
3 | AstNode, | 3 | AstNode, SyntaxNode, |
4 | SyntaxKind::{COMMENT, WHITESPACE}, | ||
5 | SyntaxNode, TextSize, | ||
6 | }; | 4 | }; |
7 | 5 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 6 | use crate::{AssistContext, AssistId, Assists}; |
@@ -16,39 +14,40 @@ use crate::{AssistContext, AssistId, Assists}; | |||
16 | // ``` | 14 | // ``` |
17 | // -> | 15 | // -> |
18 | // ``` | 16 | // ``` |
19 | // fn foo() -> Result<i32, > { Ok(42i32) } | 17 | // fn foo() -> Result<i32, ${0:_}> { Ok(42i32) } |
20 | // ``` | 18 | // ``` |
21 | pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 19 | pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
22 | let fn_def = ctx.find_node_at_offset::<ast::FnDef>(); | 20 | let ret_type = ctx.find_node_at_offset::<ast::RetType>()?; |
23 | let fn_def = &mut fn_def?; | 21 | // FIXME: extend to lambdas as well |
24 | let ret_type = &fn_def.ret_type()?.type_ref()?; | 22 | let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?; |
25 | if ret_type.syntax().text().to_string().starts_with("Result<") { | 23 | |
24 | let type_ref = &ret_type.type_ref()?; | ||
25 | if type_ref.syntax().text().to_string().starts_with("Result<") { | ||
26 | return None; | 26 | return None; |
27 | } | 27 | } |
28 | 28 | ||
29 | let block_expr = &fn_def.body()?; | 29 | let block_expr = &fn_def.body()?; |
30 | let cursor_in_ret_type = | ||
31 | fn_def.ret_type()?.syntax().text_range().contains_range(ctx.frange.range); | ||
32 | if !cursor_in_ret_type { | ||
33 | return None; | ||
34 | } | ||
35 | 30 | ||
36 | acc.add( | 31 | acc.add( |
37 | AssistId("change_return_type_to_result"), | 32 | AssistId("change_return_type_to_result"), |
38 | "Change return type to Result", | 33 | "Change return type to Result", |
39 | ret_type.syntax().text_range(), | 34 | type_ref.syntax().text_range(), |
40 | |edit| { | 35 | |builder| { |
41 | let mut tail_return_expr_collector = TailReturnCollector::new(); | 36 | let mut tail_return_expr_collector = TailReturnCollector::new(); |
42 | tail_return_expr_collector.collect_jump_exprs(block_expr, false); | 37 | tail_return_expr_collector.collect_jump_exprs(block_expr, false); |
43 | tail_return_expr_collector.collect_tail_exprs(block_expr); | 38 | tail_return_expr_collector.collect_tail_exprs(block_expr); |
44 | 39 | ||
45 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { | 40 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { |
46 | edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); | 41 | builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); |
47 | } | 42 | } |
48 | edit.replace_node_and_indent(ret_type.syntax(), format!("Result<{}, >", ret_type)); | ||
49 | 43 | ||
50 | if let Some(node_start) = result_insertion_offset(&ret_type) { | 44 | match ctx.config.snippet_cap { |
51 | edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", ret_type))); | 45 | Some(cap) => { |
46 | let snippet = format!("Result<{}, ${{0:_}}>", type_ref); | ||
47 | builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet) | ||
48 | } | ||
49 | None => builder | ||
50 | .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)), | ||
52 | } | 51 | } |
53 | }, | 52 | }, |
54 | ) | 53 | ) |
@@ -250,17 +249,8 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> { | |||
250 | } | 249 | } |
251 | } | 250 | } |
252 | 251 | ||
253 | fn result_insertion_offset(ret_type: &ast::TypeRef) -> Option<TextSize> { | ||
254 | let non_ws_child = ret_type | ||
255 | .syntax() | ||
256 | .children_with_tokens() | ||
257 | .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; | ||
258 | Some(non_ws_child.text_range().start()) | ||
259 | } | ||
260 | |||
261 | #[cfg(test)] | 252 | #[cfg(test)] |
262 | mod tests { | 253 | mod tests { |
263 | |||
264 | use crate::tests::{check_assist, check_assist_not_applicable}; | 254 | use crate::tests::{check_assist, check_assist_not_applicable}; |
265 | 255 | ||
266 | use super::*; | 256 | use super::*; |
@@ -273,7 +263,7 @@ mod tests { | |||
273 | let test = "test"; | 263 | let test = "test"; |
274 | return 42i32; | 264 | return 42i32; |
275 | }"#, | 265 | }"#, |
276 | r#"fn foo() -> Result<i32, <|>> { | 266 | r#"fn foo() -> Result<i32, ${0:_}> { |
277 | let test = "test"; | 267 | let test = "test"; |
278 | return Ok(42i32); | 268 | return Ok(42i32); |
279 | }"#, | 269 | }"#, |
@@ -288,7 +278,7 @@ mod tests { | |||
288 | let test = "test"; | 278 | let test = "test"; |
289 | return 42i32; | 279 | return 42i32; |
290 | }"#, | 280 | }"#, |
291 | r#"fn foo() -> Result<i32, <|>> { | 281 | r#"fn foo() -> Result<i32, ${0:_}> { |
292 | let test = "test"; | 282 | let test = "test"; |
293 | return Ok(42i32); | 283 | return Ok(42i32); |
294 | }"#, | 284 | }"#, |
@@ -314,7 +304,7 @@ mod tests { | |||
314 | let test = "test"; | 304 | let test = "test"; |
315 | return 42i32; | 305 | return 42i32; |
316 | }"#, | 306 | }"#, |
317 | r#"fn foo() -> Result<i32, <|>> { | 307 | r#"fn foo() -> Result<i32, ${0:_}> { |
318 | let test = "test"; | 308 | let test = "test"; |
319 | return Ok(42i32); | 309 | return Ok(42i32); |
320 | }"#, | 310 | }"#, |
@@ -329,7 +319,7 @@ mod tests { | |||
329 | let test = "test"; | 319 | let test = "test"; |
330 | 42i32 | 320 | 42i32 |
331 | }"#, | 321 | }"#, |
332 | r#"fn foo() -> Result<i32, <|>> { | 322 | r#"fn foo() -> Result<i32, ${0:_}> { |
333 | let test = "test"; | 323 | let test = "test"; |
334 | Ok(42i32) | 324 | Ok(42i32) |
335 | }"#, | 325 | }"#, |
@@ -343,7 +333,7 @@ mod tests { | |||
343 | r#"fn foo() -> i32<|> { | 333 | r#"fn foo() -> i32<|> { |
344 | 42i32 | 334 | 42i32 |
345 | }"#, | 335 | }"#, |
346 | r#"fn foo() -> Result<i32, <|>> { | 336 | r#"fn foo() -> Result<i32, ${0:_}> { |
347 | Ok(42i32) | 337 | Ok(42i32) |
348 | }"#, | 338 | }"#, |
349 | ); | 339 | ); |
@@ -359,7 +349,7 @@ mod tests { | |||
359 | 24i32 | 349 | 24i32 |
360 | } | 350 | } |
361 | }"#, | 351 | }"#, |
362 | r#"fn foo() -> Result<i32, <|>> { | 352 | r#"fn foo() -> Result<i32, ${0:_}> { |
363 | if true { | 353 | if true { |
364 | Ok(42i32) | 354 | Ok(42i32) |
365 | } else { | 355 | } else { |
@@ -384,7 +374,7 @@ mod tests { | |||
384 | 24i32 | 374 | 24i32 |
385 | } | 375 | } |
386 | }"#, | 376 | }"#, |
387 | r#"fn foo() -> Result<i32, <|>> { | 377 | r#"fn foo() -> Result<i32, ${0:_}> { |
388 | if true { | 378 | if true { |
389 | if false { | 379 | if false { |
390 | Ok(1) | 380 | Ok(1) |
@@ -413,7 +403,7 @@ mod tests { | |||
413 | 24i32.await | 403 | 24i32.await |
414 | } | 404 | } |
415 | }"#, | 405 | }"#, |
416 | r#"async fn foo() -> Result<i32, <|>> { | 406 | r#"async fn foo() -> Result<i32, ${0:_}> { |
417 | if true { | 407 | if true { |
418 | if false { | 408 | if false { |
419 | Ok(1.await) | 409 | Ok(1.await) |
@@ -434,7 +424,7 @@ mod tests { | |||
434 | r#"fn foo() -> [i32;<|> 3] { | 424 | r#"fn foo() -> [i32;<|> 3] { |
435 | [1, 2, 3] | 425 | [1, 2, 3] |
436 | }"#, | 426 | }"#, |
437 | r#"fn foo() -> Result<[i32; 3], <|>> { | 427 | r#"fn foo() -> Result<[i32; 3], ${0:_}> { |
438 | Ok([1, 2, 3]) | 428 | Ok([1, 2, 3]) |
439 | }"#, | 429 | }"#, |
440 | ); | 430 | ); |
@@ -455,7 +445,7 @@ mod tests { | |||
455 | 24 as i32 | 445 | 24 as i32 |
456 | } | 446 | } |
457 | }"#, | 447 | }"#, |
458 | r#"fn foo() -> Result<i32, <|>> { | 448 | r#"fn foo() -> Result<i32, ${0:_}> { |
459 | if true { | 449 | if true { |
460 | if false { | 450 | if false { |
461 | Ok(1 as i32) | 451 | Ok(1 as i32) |
@@ -480,7 +470,7 @@ mod tests { | |||
480 | _ => 24i32, | 470 | _ => 24i32, |
481 | } | 471 | } |
482 | }"#, | 472 | }"#, |
483 | r#"fn foo() -> Result<i32, <|>> { | 473 | r#"fn foo() -> Result<i32, ${0:_}> { |
484 | let my_var = 5; | 474 | let my_var = 5; |
485 | match my_var { | 475 | match my_var { |
486 | 5 => Ok(42i32), | 476 | 5 => Ok(42i32), |
@@ -503,7 +493,7 @@ mod tests { | |||
503 | 493 | ||
504 | my_var | 494 | my_var |
505 | }"#, | 495 | }"#, |
506 | r#"fn foo() -> Result<i32, <|>> { | 496 | r#"fn foo() -> Result<i32, ${0:_}> { |
507 | let my_var = 5; | 497 | let my_var = 5; |
508 | loop { | 498 | loop { |
509 | println!("test"); | 499 | println!("test"); |
@@ -526,7 +516,7 @@ mod tests { | |||
526 | 516 | ||
527 | my_var | 517 | my_var |
528 | }"#, | 518 | }"#, |
529 | r#"fn foo() -> Result<i32, <|>> { | 519 | r#"fn foo() -> Result<i32, ${0:_}> { |
530 | let my_var = let x = loop { | 520 | let my_var = let x = loop { |
531 | break 1; | 521 | break 1; |
532 | }; | 522 | }; |
@@ -549,7 +539,7 @@ mod tests { | |||
549 | 539 | ||
550 | res | 540 | res |
551 | }"#, | 541 | }"#, |
552 | r#"fn foo() -> Result<i32, <|>> { | 542 | r#"fn foo() -> Result<i32, ${0:_}> { |
553 | let my_var = 5; | 543 | let my_var = 5; |
554 | let res = match my_var { | 544 | let res = match my_var { |
555 | 5 => 42i32, | 545 | 5 => 42i32, |
@@ -572,7 +562,7 @@ mod tests { | |||
572 | 562 | ||
573 | res | 563 | res |
574 | }"#, | 564 | }"#, |
575 | r#"fn foo() -> Result<i32, <|>> { | 565 | r#"fn foo() -> Result<i32, ${0:_}> { |
576 | let my_var = 5; | 566 | let my_var = 5; |
577 | let res = if my_var == 5 { | 567 | let res = if my_var == 5 { |
578 | 42i32 | 568 | 42i32 |
@@ -608,7 +598,7 @@ mod tests { | |||
608 | }, | 598 | }, |
609 | } | 599 | } |
610 | }"#, | 600 | }"#, |
611 | r#"fn foo() -> Result<i32, <|>> { | 601 | r#"fn foo() -> Result<i32, ${0:_}> { |
612 | let my_var = 5; | 602 | let my_var = 5; |
613 | match my_var { | 603 | match my_var { |
614 | 5 => { | 604 | 5 => { |
@@ -641,7 +631,7 @@ mod tests { | |||
641 | } | 631 | } |
642 | 53i32 | 632 | 53i32 |
643 | }"#, | 633 | }"#, |
644 | r#"fn foo() -> Result<i32, <|>> { | 634 | r#"fn foo() -> Result<i32, ${0:_}> { |
645 | let test = "test"; | 635 | let test = "test"; |
646 | if test == "test" { | 636 | if test == "test" { |
647 | return Ok(24i32); | 637 | return Ok(24i32); |
@@ -672,7 +662,7 @@ mod tests { | |||
672 | 662 | ||
673 | the_field | 663 | the_field |
674 | }"#, | 664 | }"#, |
675 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 665 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
676 | let true_closure = || { | 666 | let true_closure = || { |
677 | return true; | 667 | return true; |
678 | }; | 668 | }; |
@@ -711,7 +701,7 @@ mod tests { | |||
711 | 701 | ||
712 | t.unwrap_or_else(|| the_field) | 702 | t.unwrap_or_else(|| the_field) |
713 | }"#, | 703 | }"#, |
714 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 704 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
715 | let true_closure = || { | 705 | let true_closure = || { |
716 | return true; | 706 | return true; |
717 | }; | 707 | }; |
@@ -749,7 +739,7 @@ mod tests { | |||
749 | i += 1; | 739 | i += 1; |
750 | } | 740 | } |
751 | }"#, | 741 | }"#, |
752 | r#"fn foo() -> Result<i32, <|>> { | 742 | r#"fn foo() -> Result<i32, ${0:_}> { |
753 | let test = "test"; | 743 | let test = "test"; |
754 | if test == "test" { | 744 | if test == "test" { |
755 | return Ok(24i32); | 745 | return Ok(24i32); |
@@ -781,7 +771,7 @@ mod tests { | |||
781 | } | 771 | } |
782 | } | 772 | } |
783 | }"#, | 773 | }"#, |
784 | r#"fn foo() -> Result<i32, <|>> { | 774 | r#"fn foo() -> Result<i32, ${0:_}> { |
785 | let test = "test"; | 775 | let test = "test"; |
786 | if test == "test" { | 776 | if test == "test" { |
787 | return Ok(24i32); | 777 | return Ok(24i32); |
@@ -819,7 +809,7 @@ mod tests { | |||
819 | } | 809 | } |
820 | } | 810 | } |
821 | }"#, | 811 | }"#, |
822 | r#"fn foo() -> Result<i32, <|>> { | 812 | r#"fn foo() -> Result<i32, ${0:_}> { |
823 | let test = "test"; | 813 | let test = "test"; |
824 | let other = 5; | 814 | let other = 5; |
825 | if test == "test" { | 815 | if test == "test" { |
@@ -860,7 +850,7 @@ mod tests { | |||
860 | 850 | ||
861 | the_field | 851 | the_field |
862 | }"#, | 852 | }"#, |
863 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 853 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
864 | if the_field < 5 { | 854 | if the_field < 5 { |
865 | let mut i = 0; | 855 | let mut i = 0; |
866 | loop { | 856 | loop { |
@@ -894,7 +884,7 @@ mod tests { | |||
894 | 884 | ||
895 | the_field | 885 | the_field |
896 | }"#, | 886 | }"#, |
897 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 887 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
898 | if the_field < 5 { | 888 | if the_field < 5 { |
899 | let mut i = 0; | 889 | let mut i = 0; |
900 | 890 | ||
@@ -923,7 +913,7 @@ mod tests { | |||
923 | 913 | ||
924 | the_field | 914 | the_field |
925 | }"#, | 915 | }"#, |
926 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 916 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
927 | if the_field < 5 { | 917 | if the_field < 5 { |
928 | let mut i = 0; | 918 | let mut i = 0; |
929 | 919 | ||
@@ -953,7 +943,7 @@ mod tests { | |||
953 | 943 | ||
954 | the_field | 944 | the_field |
955 | }"#, | 945 | }"#, |
956 | r#"fn foo(the_field: u32) -> Result<u32, <|>> { | 946 | r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> { |
957 | if the_field < 5 { | 947 | if the_field < 5 { |
958 | let mut i = 0; | 948 | let mut i = 0; |
959 | 949 | ||
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs index 40cf4b422..c21d75be0 100644 --- a/crates/ra_assists/src/handlers/change_visibility.rs +++ b/crates/ra_assists/src/handlers/change_visibility.rs | |||
@@ -5,14 +5,11 @@ use ra_syntax::{ | |||
5 | ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY, | 5 | ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY, |
6 | WHITESPACE, | 6 | WHITESPACE, |
7 | }, | 7 | }, |
8 | SyntaxNode, TextRange, TextSize, T, | 8 | SyntaxNode, TextSize, T, |
9 | }; | 9 | }; |
10 | 10 | use test_utils::mark; | |
11 | use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution}; | ||
12 | use test_utils::tested_by; | ||
13 | 11 | ||
14 | use crate::{AssistContext, AssistId, Assists}; | 12 | use crate::{AssistContext, AssistId, Assists}; |
15 | use ra_db::FileId; | ||
16 | 13 | ||
17 | // Assist: change_visibility | 14 | // Assist: change_visibility |
18 | // | 15 | // |
@@ -30,8 +27,6 @@ pub(crate) fn change_visibility(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
30 | return change_vis(acc, vis); | 27 | return change_vis(acc, vis); |
31 | } | 28 | } |
32 | add_vis(acc, ctx) | 29 | add_vis(acc, ctx) |
33 | .or_else(|| add_vis_to_referenced_module_def(acc, ctx)) | ||
34 | .or_else(|| add_vis_to_referenced_record_field(acc, ctx)) | ||
35 | } | 30 | } |
36 | 31 | ||
37 | fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 32 | fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
@@ -55,7 +50,7 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
55 | } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() { | 50 | } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() { |
56 | let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?; | 51 | let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?; |
57 | if field.name()? != field_name { | 52 | if field.name()? != field_name { |
58 | tested_by!(change_visibility_field_false_positive); | 53 | mark::hit!(change_visibility_field_false_positive); |
59 | return None; | 54 | return None; |
60 | } | 55 | } |
61 | if field.visibility().is_some() { | 56 | if field.visibility().is_some() { |
@@ -73,147 +68,9 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
73 | 68 | ||
74 | acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| { | 69 | acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| { |
75 | edit.insert(offset, "pub(crate) "); | 70 | edit.insert(offset, "pub(crate) "); |
76 | edit.set_cursor(offset); | ||
77 | }) | ||
78 | } | ||
79 | |||
80 | fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
81 | let path: ast::Path = ctx.find_node_at_offset()?; | ||
82 | let path_res = ctx.sema.resolve_path(&path)?; | ||
83 | let def = match path_res { | ||
84 | PathResolution::Def(def) => def, | ||
85 | _ => return None, | ||
86 | }; | ||
87 | |||
88 | let current_module = ctx.sema.scope(&path.syntax()).module()?; | ||
89 | let target_module = def.module(ctx.db)?; | ||
90 | |||
91 | let vis = target_module.visibility_of(ctx.db, &def)?; | ||
92 | if vis.is_visible_from(ctx.db, current_module.into()) { | ||
93 | return None; | ||
94 | }; | ||
95 | |||
96 | let (offset, target, target_file, target_name) = target_data_for_def(ctx.db, def)?; | ||
97 | |||
98 | let missing_visibility = | ||
99 | if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" }; | ||
100 | |||
101 | let assist_label = match target_name { | ||
102 | None => format!("Change visibility to {}", missing_visibility), | ||
103 | Some(name) => format!("Change visibility of {} to {}", name, missing_visibility), | ||
104 | }; | ||
105 | |||
106 | acc.add(AssistId("change_visibility"), assist_label, target, |edit| { | ||
107 | edit.set_file(target_file); | ||
108 | edit.insert(offset, format!("{} ", missing_visibility)); | ||
109 | edit.set_cursor(offset); | ||
110 | }) | ||
111 | } | ||
112 | |||
113 | fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
114 | let record_field: ast::RecordField = ctx.find_node_at_offset()?; | ||
115 | let (record_field_def, _) = ctx.sema.resolve_record_field(&record_field)?; | ||
116 | |||
117 | let current_module = ctx.sema.scope(record_field.syntax()).module()?; | ||
118 | let visibility = record_field_def.visibility(ctx.db); | ||
119 | if visibility.is_visible_from(ctx.db, current_module.into()) { | ||
120 | return None; | ||
121 | } | ||
122 | |||
123 | let parent = record_field_def.parent_def(ctx.db); | ||
124 | let parent_name = parent.name(ctx.db); | ||
125 | let target_module = parent.module(ctx.db); | ||
126 | |||
127 | let in_file_source = record_field_def.source(ctx.db); | ||
128 | let (offset, target) = match in_file_source.value { | ||
129 | hir::FieldSource::Named(it) => { | ||
130 | let s = it.syntax(); | ||
131 | (vis_offset(s), s.text_range()) | ||
132 | } | ||
133 | hir::FieldSource::Pos(it) => { | ||
134 | let s = it.syntax(); | ||
135 | (vis_offset(s), s.text_range()) | ||
136 | } | ||
137 | }; | ||
138 | |||
139 | let missing_visibility = | ||
140 | if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" }; | ||
141 | let target_file = in_file_source.file_id.original_file(ctx.db); | ||
142 | |||
143 | let target_name = record_field_def.name(ctx.db); | ||
144 | let assist_label = | ||
145 | format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility); | ||
146 | |||
147 | acc.add(AssistId("change_visibility"), assist_label, target, |edit| { | ||
148 | edit.set_file(target_file); | ||
149 | edit.insert(offset, format!("{} ", missing_visibility)); | ||
150 | edit.set_cursor(offset) | ||
151 | }) | 71 | }) |
152 | } | 72 | } |
153 | 73 | ||
154 | fn target_data_for_def( | ||
155 | db: &dyn HirDatabase, | ||
156 | def: hir::ModuleDef, | ||
157 | ) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> { | ||
158 | fn offset_target_and_file_id<S, Ast>( | ||
159 | db: &dyn HirDatabase, | ||
160 | x: S, | ||
161 | ) -> (TextSize, TextRange, FileId) | ||
162 | where | ||
163 | S: HasSource<Ast = Ast>, | ||
164 | Ast: AstNode, | ||
165 | { | ||
166 | let source = x.source(db); | ||
167 | let in_file_syntax = source.syntax(); | ||
168 | let file_id = in_file_syntax.file_id; | ||
169 | let syntax = in_file_syntax.value; | ||
170 | (vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast())) | ||
171 | } | ||
172 | |||
173 | let target_name; | ||
174 | let (offset, target, target_file) = match def { | ||
175 | hir::ModuleDef::Function(f) => { | ||
176 | target_name = Some(f.name(db)); | ||
177 | offset_target_and_file_id(db, f) | ||
178 | } | ||
179 | hir::ModuleDef::Adt(adt) => { | ||
180 | target_name = Some(adt.name(db)); | ||
181 | match adt { | ||
182 | hir::Adt::Struct(s) => offset_target_and_file_id(db, s), | ||
183 | hir::Adt::Union(u) => offset_target_and_file_id(db, u), | ||
184 | hir::Adt::Enum(e) => offset_target_and_file_id(db, e), | ||
185 | } | ||
186 | } | ||
187 | hir::ModuleDef::Const(c) => { | ||
188 | target_name = c.name(db); | ||
189 | offset_target_and_file_id(db, c) | ||
190 | } | ||
191 | hir::ModuleDef::Static(s) => { | ||
192 | target_name = s.name(db); | ||
193 | offset_target_and_file_id(db, s) | ||
194 | } | ||
195 | hir::ModuleDef::Trait(t) => { | ||
196 | target_name = Some(t.name(db)); | ||
197 | offset_target_and_file_id(db, t) | ||
198 | } | ||
199 | hir::ModuleDef::TypeAlias(t) => { | ||
200 | target_name = Some(t.name(db)); | ||
201 | offset_target_and_file_id(db, t) | ||
202 | } | ||
203 | hir::ModuleDef::Module(m) => { | ||
204 | target_name = m.name(db); | ||
205 | let in_file_source = m.declaration_source(db)?; | ||
206 | let file_id = in_file_source.file_id.original_file(db.upcast()); | ||
207 | let syntax = in_file_source.value.syntax(); | ||
208 | (vis_offset(syntax), syntax.text_range(), file_id) | ||
209 | } | ||
210 | // Enum variants can't be private, we can't modify builtin types | ||
211 | hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, | ||
212 | }; | ||
213 | |||
214 | Some((offset, target, target_file, target_name)) | ||
215 | } | ||
216 | |||
217 | fn vis_offset(node: &SyntaxNode) -> TextSize { | 74 | fn vis_offset(node: &SyntaxNode) -> TextSize { |
218 | node.children_with_tokens() | 75 | node.children_with_tokens() |
219 | .skip_while(|it| match it.kind() { | 76 | .skip_while(|it| match it.kind() { |
@@ -234,7 +91,6 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> { | |||
234 | target, | 91 | target, |
235 | |edit| { | 92 | |edit| { |
236 | edit.replace(vis.syntax().text_range(), "pub(crate)"); | 93 | edit.replace(vis.syntax().text_range(), "pub(crate)"); |
237 | edit.set_cursor(vis.syntax().text_range().start()) | ||
238 | }, | 94 | }, |
239 | ); | 95 | ); |
240 | } | 96 | } |
@@ -246,7 +102,6 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> { | |||
246 | target, | 102 | target, |
247 | |edit| { | 103 | |edit| { |
248 | edit.replace(vis.syntax().text_range(), "pub"); | 104 | edit.replace(vis.syntax().text_range(), "pub"); |
249 | edit.set_cursor(vis.syntax().text_range().start()); | ||
250 | }, | 105 | }, |
251 | ); | 106 | ); |
252 | } | 107 | } |
@@ -255,7 +110,7 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> { | |||
255 | 110 | ||
256 | #[cfg(test)] | 111 | #[cfg(test)] |
257 | mod tests { | 112 | mod tests { |
258 | use test_utils::covers; | 113 | use test_utils::mark; |
259 | 114 | ||
260 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 115 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; |
261 | 116 | ||
@@ -263,17 +118,13 @@ mod tests { | |||
263 | 118 | ||
264 | #[test] | 119 | #[test] |
265 | fn change_visibility_adds_pub_crate_to_items() { | 120 | fn change_visibility_adds_pub_crate_to_items() { |
266 | check_assist(change_visibility, "<|>fn foo() {}", "<|>pub(crate) fn foo() {}"); | 121 | check_assist(change_visibility, "<|>fn foo() {}", "pub(crate) fn foo() {}"); |
267 | check_assist(change_visibility, "f<|>n foo() {}", "<|>pub(crate) fn foo() {}"); | 122 | check_assist(change_visibility, "f<|>n foo() {}", "pub(crate) fn foo() {}"); |
268 | check_assist(change_visibility, "<|>struct Foo {}", "<|>pub(crate) struct Foo {}"); | 123 | check_assist(change_visibility, "<|>struct Foo {}", "pub(crate) struct Foo {}"); |
269 | check_assist(change_visibility, "<|>mod foo {}", "<|>pub(crate) mod foo {}"); | 124 | check_assist(change_visibility, "<|>mod foo {}", "pub(crate) mod foo {}"); |
270 | check_assist(change_visibility, "<|>trait Foo {}", "<|>pub(crate) trait Foo {}"); | 125 | check_assist(change_visibility, "<|>trait Foo {}", "pub(crate) trait Foo {}"); |
271 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); | 126 | check_assist(change_visibility, "m<|>od {}", "pub(crate) mod {}"); |
272 | check_assist( | 127 | check_assist(change_visibility, "unsafe f<|>n foo() {}", "pub(crate) unsafe fn foo() {}"); |
273 | change_visibility, | ||
274 | "unsafe f<|>n foo() {}", | ||
275 | "<|>pub(crate) unsafe fn foo() {}", | ||
276 | ); | ||
277 | } | 128 | } |
278 | 129 | ||
279 | #[test] | 130 | #[test] |
@@ -281,14 +132,14 @@ mod tests { | |||
281 | check_assist( | 132 | check_assist( |
282 | change_visibility, | 133 | change_visibility, |
283 | r"struct S { <|>field: u32 }", | 134 | r"struct S { <|>field: u32 }", |
284 | r"struct S { <|>pub(crate) field: u32 }", | 135 | r"struct S { pub(crate) field: u32 }", |
285 | ); | 136 | ); |
286 | check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( <|>pub(crate) u32 )"); | 137 | check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( pub(crate) u32 )"); |
287 | } | 138 | } |
288 | 139 | ||
289 | #[test] | 140 | #[test] |
290 | fn change_visibility_field_false_positive() { | 141 | fn change_visibility_field_false_positive() { |
291 | covers!(change_visibility_field_false_positive); | 142 | mark::check!(change_visibility_field_false_positive); |
292 | check_assist_not_applicable( | 143 | check_assist_not_applicable( |
293 | change_visibility, | 144 | change_visibility, |
294 | r"struct S { field: [(); { let <|>x = ();}] }", | 145 | r"struct S { field: [(); { let <|>x = ();}] }", |
@@ -297,17 +148,17 @@ mod tests { | |||
297 | 148 | ||
298 | #[test] | 149 | #[test] |
299 | fn change_visibility_pub_to_pub_crate() { | 150 | fn change_visibility_pub_to_pub_crate() { |
300 | check_assist(change_visibility, "<|>pub fn foo() {}", "<|>pub(crate) fn foo() {}") | 151 | check_assist(change_visibility, "<|>pub fn foo() {}", "pub(crate) fn foo() {}") |
301 | } | 152 | } |
302 | 153 | ||
303 | #[test] | 154 | #[test] |
304 | fn change_visibility_pub_crate_to_pub() { | 155 | fn change_visibility_pub_crate_to_pub() { |
305 | check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "<|>pub fn foo() {}") | 156 | check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "pub fn foo() {}") |
306 | } | 157 | } |
307 | 158 | ||
308 | #[test] | 159 | #[test] |
309 | fn change_visibility_const() { | 160 | fn change_visibility_const() { |
310 | check_assist(change_visibility, "<|>const FOO = 3u8;", "<|>pub(crate) const FOO = 3u8;"); | 161 | check_assist(change_visibility, "<|>const FOO = 3u8;", "pub(crate) const FOO = 3u8;"); |
311 | } | 162 | } |
312 | 163 | ||
313 | #[test] | 164 | #[test] |
@@ -328,199 +179,12 @@ mod tests { | |||
328 | // comments | 179 | // comments |
329 | 180 | ||
330 | #[derive(Debug)] | 181 | #[derive(Debug)] |
331 | <|>pub(crate) struct Foo; | 182 | pub(crate) struct Foo; |
332 | ", | 183 | ", |
333 | ) | 184 | ) |
334 | } | 185 | } |
335 | 186 | ||
336 | #[test] | 187 | #[test] |
337 | fn change_visibility_of_fn_via_path() { | ||
338 | check_assist( | ||
339 | change_visibility, | ||
340 | r"mod foo { fn foo() {} } | ||
341 | fn main() { foo::foo<|>() } ", | ||
342 | r"mod foo { <|>pub(crate) fn foo() {} } | ||
343 | fn main() { foo::foo() } ", | ||
344 | ); | ||
345 | check_assist_not_applicable( | ||
346 | change_visibility, | ||
347 | r"mod foo { pub fn foo() {} } | ||
348 | fn main() { foo::foo<|>() } ", | ||
349 | ) | ||
350 | } | ||
351 | |||
352 | #[test] | ||
353 | fn change_visibility_of_adt_in_submodule_via_path() { | ||
354 | check_assist( | ||
355 | change_visibility, | ||
356 | r"mod foo { struct Foo; } | ||
357 | fn main() { foo::Foo<|> } ", | ||
358 | r"mod foo { <|>pub(crate) struct Foo; } | ||
359 | fn main() { foo::Foo } ", | ||
360 | ); | ||
361 | check_assist_not_applicable( | ||
362 | change_visibility, | ||
363 | r"mod foo { pub struct Foo; } | ||
364 | fn main() { foo::Foo<|> } ", | ||
365 | ); | ||
366 | check_assist( | ||
367 | change_visibility, | ||
368 | r"mod foo { enum Foo; } | ||
369 | fn main() { foo::Foo<|> } ", | ||
370 | r"mod foo { <|>pub(crate) enum Foo; } | ||
371 | fn main() { foo::Foo } ", | ||
372 | ); | ||
373 | check_assist_not_applicable( | ||
374 | change_visibility, | ||
375 | r"mod foo { pub enum Foo; } | ||
376 | fn main() { foo::Foo<|> } ", | ||
377 | ); | ||
378 | check_assist( | ||
379 | change_visibility, | ||
380 | r"mod foo { union Foo; } | ||
381 | fn main() { foo::Foo<|> } ", | ||
382 | r"mod foo { <|>pub(crate) union Foo; } | ||
383 | fn main() { foo::Foo } ", | ||
384 | ); | ||
385 | check_assist_not_applicable( | ||
386 | change_visibility, | ||
387 | r"mod foo { pub union Foo; } | ||
388 | fn main() { foo::Foo<|> } ", | ||
389 | ); | ||
390 | } | ||
391 | |||
392 | #[test] | ||
393 | fn change_visibility_of_adt_in_other_file_via_path() { | ||
394 | check_assist( | ||
395 | change_visibility, | ||
396 | r" | ||
397 | //- /main.rs | ||
398 | mod foo; | ||
399 | fn main() { foo::Foo<|> } | ||
400 | |||
401 | //- /foo.rs | ||
402 | struct Foo; | ||
403 | ", | ||
404 | r"<|>pub(crate) struct Foo; | ||
405 | |||
406 | ", | ||
407 | ); | ||
408 | } | ||
409 | |||
410 | #[test] | ||
411 | fn change_visibility_of_struct_field_via_path() { | ||
412 | check_assist( | ||
413 | change_visibility, | ||
414 | r"mod foo { pub struct Foo { bar: (), } } | ||
415 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
416 | r"mod foo { pub struct Foo { <|>pub(crate) bar: (), } } | ||
417 | fn main() { foo::Foo { bar: () }; } ", | ||
418 | ); | ||
419 | check_assist( | ||
420 | change_visibility, | ||
421 | r"//- /lib.rs | ||
422 | mod foo; | ||
423 | fn main() { foo::Foo { <|>bar: () }; } | ||
424 | //- /foo.rs | ||
425 | pub struct Foo { bar: () } | ||
426 | ", | ||
427 | r"pub struct Foo { <|>pub(crate) bar: () } | ||
428 | |||
429 | ", | ||
430 | ); | ||
431 | check_assist_not_applicable( | ||
432 | change_visibility, | ||
433 | r"mod foo { pub struct Foo { pub bar: (), } } | ||
434 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
435 | ); | ||
436 | check_assist_not_applicable( | ||
437 | change_visibility, | ||
438 | r"//- /lib.rs | ||
439 | mod foo; | ||
440 | fn main() { foo::Foo { <|>bar: () }; } | ||
441 | //- /foo.rs | ||
442 | pub struct Foo { pub bar: () } | ||
443 | ", | ||
444 | ); | ||
445 | } | ||
446 | |||
447 | #[test] | ||
448 | fn change_visibility_of_enum_variant_field_via_path() { | ||
449 | check_assist( | ||
450 | change_visibility, | ||
451 | r"mod foo { pub enum Foo { Bar { bar: () } } } | ||
452 | fn main() { foo::Foo::Bar { <|>bar: () }; } ", | ||
453 | r"mod foo { pub enum Foo { Bar { <|>pub(crate) bar: () } } } | ||
454 | fn main() { foo::Foo::Bar { bar: () }; } ", | ||
455 | ); | ||
456 | check_assist( | ||
457 | change_visibility, | ||
458 | r"//- /lib.rs | ||
459 | mod foo; | ||
460 | fn main() { foo::Foo::Bar { <|>bar: () }; } | ||
461 | //- /foo.rs | ||
462 | pub enum Foo { Bar { bar: () } } | ||
463 | ", | ||
464 | r"pub enum Foo { Bar { <|>pub(crate) bar: () } } | ||
465 | |||
466 | ", | ||
467 | ); | ||
468 | check_assist_not_applicable( | ||
469 | change_visibility, | ||
470 | r"mod foo { pub struct Foo { pub bar: (), } } | ||
471 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
472 | ); | ||
473 | check_assist_not_applicable( | ||
474 | change_visibility, | ||
475 | r"//- /lib.rs | ||
476 | mod foo; | ||
477 | fn main() { foo::Foo { <|>bar: () }; } | ||
478 | //- /foo.rs | ||
479 | pub struct Foo { pub bar: () } | ||
480 | ", | ||
481 | ); | ||
482 | } | ||
483 | |||
484 | #[test] | ||
485 | #[ignore] | ||
486 | // FIXME reenable this test when `Semantics::resolve_record_field` works with union fields | ||
487 | fn change_visibility_of_union_field_via_path() { | ||
488 | check_assist( | ||
489 | change_visibility, | ||
490 | r"mod foo { pub union Foo { bar: (), } } | ||
491 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
492 | r"mod foo { pub union Foo { <|>pub(crate) bar: (), } } | ||
493 | fn main() { foo::Foo { bar: () }; } ", | ||
494 | ); | ||
495 | check_assist( | ||
496 | change_visibility, | ||
497 | r"//- /lib.rs | ||
498 | mod foo; | ||
499 | fn main() { foo::Foo { <|>bar: () }; } | ||
500 | //- /foo.rs | ||
501 | pub union Foo { bar: () } | ||
502 | ", | ||
503 | r"pub union Foo { <|>pub(crate) bar: () } | ||
504 | |||
505 | ", | ||
506 | ); | ||
507 | check_assist_not_applicable( | ||
508 | change_visibility, | ||
509 | r"mod foo { pub union Foo { pub bar: (), } } | ||
510 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
511 | ); | ||
512 | check_assist_not_applicable( | ||
513 | change_visibility, | ||
514 | r"//- /lib.rs | ||
515 | mod foo; | ||
516 | fn main() { foo::Foo { <|>bar: () }; } | ||
517 | //- /foo.rs | ||
518 | pub union Foo { pub bar: () } | ||
519 | ", | ||
520 | ); | ||
521 | } | ||
522 | |||
523 | #[test] | ||
524 | fn not_applicable_for_enum_variants() { | 188 | fn not_applicable_for_enum_variants() { |
525 | check_assist_not_applicable( | 189 | check_assist_not_applicable( |
526 | change_visibility, | 190 | change_visibility, |
@@ -530,182 +194,6 @@ mod tests { | |||
530 | } | 194 | } |
531 | 195 | ||
532 | #[test] | 196 | #[test] |
533 | fn change_visibility_of_const_via_path() { | ||
534 | check_assist( | ||
535 | change_visibility, | ||
536 | r"mod foo { const FOO: () = (); } | ||
537 | fn main() { foo::FOO<|> } ", | ||
538 | r"mod foo { <|>pub(crate) const FOO: () = (); } | ||
539 | fn main() { foo::FOO } ", | ||
540 | ); | ||
541 | check_assist_not_applicable( | ||
542 | change_visibility, | ||
543 | r"mod foo { pub const FOO: () = (); } | ||
544 | fn main() { foo::FOO<|> } ", | ||
545 | ); | ||
546 | } | ||
547 | |||
548 | #[test] | ||
549 | fn change_visibility_of_static_via_path() { | ||
550 | check_assist( | ||
551 | change_visibility, | ||
552 | r"mod foo { static FOO: () = (); } | ||
553 | fn main() { foo::FOO<|> } ", | ||
554 | r"mod foo { <|>pub(crate) static FOO: () = (); } | ||
555 | fn main() { foo::FOO } ", | ||
556 | ); | ||
557 | check_assist_not_applicable( | ||
558 | change_visibility, | ||
559 | r"mod foo { pub static FOO: () = (); } | ||
560 | fn main() { foo::FOO<|> } ", | ||
561 | ); | ||
562 | } | ||
563 | |||
564 | #[test] | ||
565 | fn change_visibility_of_trait_via_path() { | ||
566 | check_assist( | ||
567 | change_visibility, | ||
568 | r"mod foo { trait Foo { fn foo(&self) {} } } | ||
569 | fn main() { let x: &dyn foo::<|>Foo; } ", | ||
570 | r"mod foo { <|>pub(crate) trait Foo { fn foo(&self) {} } } | ||
571 | fn main() { let x: &dyn foo::Foo; } ", | ||
572 | ); | ||
573 | check_assist_not_applicable( | ||
574 | change_visibility, | ||
575 | r"mod foo { pub trait Foo { fn foo(&self) {} } } | ||
576 | fn main() { let x: &dyn foo::Foo<|>; } ", | ||
577 | ); | ||
578 | } | ||
579 | |||
580 | #[test] | ||
581 | fn change_visibility_of_type_alias_via_path() { | ||
582 | check_assist( | ||
583 | change_visibility, | ||
584 | r"mod foo { type Foo = (); } | ||
585 | fn main() { let x: foo::Foo<|>; } ", | ||
586 | r"mod foo { <|>pub(crate) type Foo = (); } | ||
587 | fn main() { let x: foo::Foo; } ", | ||
588 | ); | ||
589 | check_assist_not_applicable( | ||
590 | change_visibility, | ||
591 | r"mod foo { pub type Foo = (); } | ||
592 | fn main() { let x: foo::Foo<|>; } ", | ||
593 | ); | ||
594 | } | ||
595 | |||
596 | #[test] | ||
597 | fn change_visibility_of_module_via_path() { | ||
598 | check_assist( | ||
599 | change_visibility, | ||
600 | r"mod foo { mod bar { fn bar() {} } } | ||
601 | fn main() { foo::bar<|>::bar(); } ", | ||
602 | r"mod foo { <|>pub(crate) mod bar { fn bar() {} } } | ||
603 | fn main() { foo::bar::bar(); } ", | ||
604 | ); | ||
605 | |||
606 | check_assist( | ||
607 | change_visibility, | ||
608 | r" | ||
609 | //- /main.rs | ||
610 | mod foo; | ||
611 | fn main() { foo::bar<|>::baz(); } | ||
612 | |||
613 | //- /foo.rs | ||
614 | mod bar { | ||
615 | pub fn baz() {} | ||
616 | } | ||
617 | ", | ||
618 | r"<|>pub(crate) mod bar { | ||
619 | pub fn baz() {} | ||
620 | } | ||
621 | |||
622 | ", | ||
623 | ); | ||
624 | |||
625 | check_assist_not_applicable( | ||
626 | change_visibility, | ||
627 | r"mod foo { pub mod bar { pub fn bar() {} } } | ||
628 | fn main() { foo::bar<|>::bar(); } ", | ||
629 | ); | ||
630 | } | ||
631 | |||
632 | #[test] | ||
633 | fn change_visibility_of_inline_module_in_other_file_via_path() { | ||
634 | check_assist( | ||
635 | change_visibility, | ||
636 | r" | ||
637 | //- /main.rs | ||
638 | mod foo; | ||
639 | fn main() { foo::bar<|>::baz(); } | ||
640 | |||
641 | //- /foo.rs | ||
642 | mod bar; | ||
643 | |||
644 | //- /foo/bar.rs | ||
645 | pub fn baz() {} | ||
646 | } | ||
647 | ", | ||
648 | r"<|>pub(crate) mod bar; | ||
649 | ", | ||
650 | ); | ||
651 | } | ||
652 | |||
653 | #[test] | ||
654 | fn change_visibility_of_module_declaration_in_other_file_via_path() { | ||
655 | check_assist( | ||
656 | change_visibility, | ||
657 | r"//- /main.rs | ||
658 | mod foo; | ||
659 | fn main() { foo::bar<|>>::baz(); } | ||
660 | |||
661 | //- /foo.rs | ||
662 | mod bar { | ||
663 | pub fn baz() {} | ||
664 | }", | ||
665 | r"<|>pub(crate) mod bar { | ||
666 | pub fn baz() {} | ||
667 | } | ||
668 | ", | ||
669 | ); | ||
670 | } | ||
671 | |||
672 | #[test] | ||
673 | #[ignore] | ||
674 | // FIXME handle reexports properly | ||
675 | fn change_visibility_of_reexport() { | ||
676 | check_assist( | ||
677 | change_visibility, | ||
678 | r" | ||
679 | mod foo { | ||
680 | use bar::Baz; | ||
681 | mod bar { pub(super) struct Baz; } | ||
682 | } | ||
683 | foo::Baz<|> | ||
684 | ", | ||
685 | r" | ||
686 | mod foo { | ||
687 | <|>pub(crate) use bar::Baz; | ||
688 | mod bar { pub(super) struct Baz; } | ||
689 | } | ||
690 | foo::Baz | ||
691 | ", | ||
692 | ) | ||
693 | } | ||
694 | |||
695 | #[test] | ||
696 | fn adds_pub_when_target_is_in_another_crate() { | ||
697 | check_assist( | ||
698 | change_visibility, | ||
699 | r"//- /main.rs crate:a deps:foo | ||
700 | foo::Bar<|> | ||
701 | //- /lib.rs crate:foo | ||
702 | struct Bar;", | ||
703 | r"<|>pub struct Bar; | ||
704 | ", | ||
705 | ) | ||
706 | } | ||
707 | |||
708 | #[test] | ||
709 | fn change_visibility_target() { | 197 | fn change_visibility_target() { |
710 | check_assist_target(change_visibility, "<|>fn foo() {}", "fn"); | 198 | check_assist_target(change_visibility, "<|>fn foo() {}", "fn"); |
711 | check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)"); | 199 | check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)"); |
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs index 13c1e7e80..cc303285b 100644 --- a/crates/ra_assists/src/handlers/fill_match_arms.rs +++ b/crates/ra_assists/src/handlers/fill_match_arms.rs | |||
@@ -4,8 +4,12 @@ use hir::{Adt, HasSource, ModuleDef, Semantics}; | |||
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; | 6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; |
7 | use test_utils::mark; | ||
7 | 8 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 9 | use crate::{ |
10 | utils::{render_snippet, Cursor, FamousDefs}, | ||
11 | AssistContext, AssistId, Assists, | ||
12 | }; | ||
9 | 13 | ||
10 | // Assist: fill_match_arms | 14 | // Assist: fill_match_arms |
11 | // | 15 | // |
@@ -26,7 +30,7 @@ use crate::{AssistContext, AssistId, Assists}; | |||
26 | // | 30 | // |
27 | // fn handle(action: Action) { | 31 | // fn handle(action: Action) { |
28 | // match action { | 32 | // match action { |
29 | // Action::Move { distance } => {} | 33 | // $0Action::Move { distance } => {} |
30 | // Action::Stop => {} | 34 | // Action::Stop => {} |
31 | // } | 35 | // } |
32 | // } | 36 | // } |
@@ -49,12 +53,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
49 | let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) { | 53 | let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) { |
50 | let variants = enum_def.variants(ctx.db); | 54 | let variants = enum_def.variants(ctx.db); |
51 | 55 | ||
52 | variants | 56 | let mut variants = variants |
53 | .into_iter() | 57 | .into_iter() |
54 | .filter_map(|variant| build_pat(ctx.db, module, variant)) | 58 | .filter_map(|variant| build_pat(ctx.db, module, variant)) |
55 | .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) | 59 | .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) |
56 | .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) | 60 | .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) |
57 | .collect() | 61 | .collect::<Vec<_>>(); |
62 | if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() { | ||
63 | // Match `Some` variant first. | ||
64 | mark::hit!(option_order); | ||
65 | variants.reverse() | ||
66 | } | ||
67 | variants | ||
58 | } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { | 68 | } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { |
59 | // Partial fill not currently supported for tuple of enums. | 69 | // Partial fill not currently supported for tuple of enums. |
60 | if !arms.is_empty() { | 70 | if !arms.is_empty() { |
@@ -93,10 +103,23 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
93 | } | 103 | } |
94 | 104 | ||
95 | let target = match_expr.syntax().text_range(); | 105 | let target = match_expr.syntax().text_range(); |
96 | acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |edit| { | 106 | acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |builder| { |
97 | let new_arm_list = match_arm_list.remove_placeholder().append_arms(missing_arms); | 107 | let new_arm_list = match_arm_list.remove_placeholder(); |
98 | edit.set_cursor(expr.syntax().text_range().start()); | 108 | let n_old_arms = new_arm_list.arms().count(); |
99 | edit.replace_ast(match_arm_list, new_arm_list); | 109 | let new_arm_list = new_arm_list.append_arms(missing_arms); |
110 | let first_new_arm = new_arm_list.arms().nth(n_old_arms); | ||
111 | let old_range = match_arm_list.syntax().text_range(); | ||
112 | match (first_new_arm, ctx.config.snippet_cap) { | ||
113 | (Some(first_new_arm), Some(cap)) => { | ||
114 | let snippet = render_snippet( | ||
115 | cap, | ||
116 | new_arm_list.syntax(), | ||
117 | Cursor::Before(first_new_arm.syntax()), | ||
118 | ); | ||
119 | builder.replace_snippet(cap, old_range, snippet); | ||
120 | } | ||
121 | _ => builder.replace(old_range, new_arm_list.to_string()), | ||
122 | } | ||
100 | }) | 123 | }) |
101 | } | 124 | } |
102 | 125 | ||
@@ -167,7 +190,12 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O | |||
167 | 190 | ||
168 | #[cfg(test)] | 191 | #[cfg(test)] |
169 | mod tests { | 192 | mod tests { |
170 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 193 | use test_utils::mark; |
194 | |||
195 | use crate::{ | ||
196 | tests::{check_assist, check_assist_not_applicable, check_assist_target}, | ||
197 | utils::FamousDefs, | ||
198 | }; | ||
171 | 199 | ||
172 | use super::fill_match_arms; | 200 | use super::fill_match_arms; |
173 | 201 | ||
@@ -214,12 +242,12 @@ mod tests { | |||
214 | r#" | 242 | r#" |
215 | enum A { | 243 | enum A { |
216 | As, | 244 | As, |
217 | Bs{x:i32, y:Option<i32>}, | 245 | Bs { x: i32, y: Option<i32> }, |
218 | Cs(i32, Option<i32>), | 246 | Cs(i32, Option<i32>), |
219 | } | 247 | } |
220 | fn main() { | 248 | fn main() { |
221 | match A::As<|> { | 249 | match A::As<|> { |
222 | A::Bs{x,y:Some(_)} => {} | 250 | A::Bs { x, y: Some(_) } => {} |
223 | A::Cs(_, Some(_)) => {} | 251 | A::Cs(_, Some(_)) => {} |
224 | } | 252 | } |
225 | } | 253 | } |
@@ -227,14 +255,14 @@ mod tests { | |||
227 | r#" | 255 | r#" |
228 | enum A { | 256 | enum A { |
229 | As, | 257 | As, |
230 | Bs{x:i32, y:Option<i32>}, | 258 | Bs { x: i32, y: Option<i32> }, |
231 | Cs(i32, Option<i32>), | 259 | Cs(i32, Option<i32>), |
232 | } | 260 | } |
233 | fn main() { | 261 | fn main() { |
234 | match <|>A::As { | 262 | match A::As { |
235 | A::Bs{x,y:Some(_)} => {} | 263 | A::Bs { x, y: Some(_) } => {} |
236 | A::Cs(_, Some(_)) => {} | 264 | A::Cs(_, Some(_)) => {} |
237 | A::As => {} | 265 | $0A::As => {} |
238 | } | 266 | } |
239 | } | 267 | } |
240 | "#, | 268 | "#, |
@@ -264,9 +292,9 @@ mod tests { | |||
264 | Cs(Option<i32>), | 292 | Cs(Option<i32>), |
265 | } | 293 | } |
266 | fn main() { | 294 | fn main() { |
267 | match <|>A::As { | 295 | match A::As { |
268 | A::Cs(_) | A::Bs => {} | 296 | A::Cs(_) | A::Bs => {} |
269 | A::As => {} | 297 | $0A::As => {} |
270 | } | 298 | } |
271 | } | 299 | } |
272 | "#, | 300 | "#, |
@@ -310,11 +338,11 @@ mod tests { | |||
310 | Ys, | 338 | Ys, |
311 | } | 339 | } |
312 | fn main() { | 340 | fn main() { |
313 | match <|>A::As { | 341 | match A::As { |
314 | A::Bs if 0 < 1 => {} | 342 | A::Bs if 0 < 1 => {} |
315 | A::Ds(_value) => { let x = 1; } | 343 | A::Ds(_value) => { let x = 1; } |
316 | A::Es(B::Xs) => (), | 344 | A::Es(B::Xs) => (), |
317 | A::As => {} | 345 | $0A::As => {} |
318 | A::Cs => {} | 346 | A::Cs => {} |
319 | } | 347 | } |
320 | } | 348 | } |
@@ -332,7 +360,7 @@ mod tests { | |||
332 | Bs, | 360 | Bs, |
333 | Cs(String), | 361 | Cs(String), |
334 | Ds(String, String), | 362 | Ds(String, String), |
335 | Es{ x: usize, y: usize } | 363 | Es { x: usize, y: usize } |
336 | } | 364 | } |
337 | 365 | ||
338 | fn main() { | 366 | fn main() { |
@@ -346,13 +374,13 @@ mod tests { | |||
346 | Bs, | 374 | Bs, |
347 | Cs(String), | 375 | Cs(String), |
348 | Ds(String, String), | 376 | Ds(String, String), |
349 | Es{ x: usize, y: usize } | 377 | Es { x: usize, y: usize } |
350 | } | 378 | } |
351 | 379 | ||
352 | fn main() { | 380 | fn main() { |
353 | let a = A::As; | 381 | let a = A::As; |
354 | match <|>a { | 382 | match a { |
355 | A::As => {} | 383 | $0A::As => {} |
356 | A::Bs => {} | 384 | A::Bs => {} |
357 | A::Cs(_) => {} | 385 | A::Cs(_) => {} |
358 | A::Ds(_, _) => {} | 386 | A::Ds(_, _) => {} |
@@ -368,14 +396,8 @@ mod tests { | |||
368 | check_assist( | 396 | check_assist( |
369 | fill_match_arms, | 397 | fill_match_arms, |
370 | r#" | 398 | r#" |
371 | enum A { | 399 | enum A { One, Two } |
372 | One, | 400 | enum B { One, Two } |
373 | Two, | ||
374 | } | ||
375 | enum B { | ||
376 | One, | ||
377 | Two, | ||
378 | } | ||
379 | 401 | ||
380 | fn main() { | 402 | fn main() { |
381 | let a = A::One; | 403 | let a = A::One; |
@@ -384,20 +406,14 @@ mod tests { | |||
384 | } | 406 | } |
385 | "#, | 407 | "#, |
386 | r#" | 408 | r#" |
387 | enum A { | 409 | enum A { One, Two } |
388 | One, | 410 | enum B { One, Two } |
389 | Two, | ||
390 | } | ||
391 | enum B { | ||
392 | One, | ||
393 | Two, | ||
394 | } | ||
395 | 411 | ||
396 | fn main() { | 412 | fn main() { |
397 | let a = A::One; | 413 | let a = A::One; |
398 | let b = B::One; | 414 | let b = B::One; |
399 | match <|>(a, b) { | 415 | match (a, b) { |
400 | (A::One, B::One) => {} | 416 | $0(A::One, B::One) => {} |
401 | (A::One, B::Two) => {} | 417 | (A::One, B::Two) => {} |
402 | (A::Two, B::One) => {} | 418 | (A::Two, B::One) => {} |
403 | (A::Two, B::Two) => {} | 419 | (A::Two, B::Two) => {} |
@@ -412,14 +428,8 @@ mod tests { | |||
412 | check_assist( | 428 | check_assist( |
413 | fill_match_arms, | 429 | fill_match_arms, |
414 | r#" | 430 | r#" |
415 | enum A { | 431 | enum A { One, Two } |
416 | One, | 432 | enum B { One, Two } |
417 | Two, | ||
418 | } | ||
419 | enum B { | ||
420 | One, | ||
421 | Two, | ||
422 | } | ||
423 | 433 | ||
424 | fn main() { | 434 | fn main() { |
425 | let a = A::One; | 435 | let a = A::One; |
@@ -428,20 +438,14 @@ mod tests { | |||
428 | } | 438 | } |
429 | "#, | 439 | "#, |
430 | r#" | 440 | r#" |
431 | enum A { | 441 | enum A { One, Two } |
432 | One, | 442 | enum B { One, Two } |
433 | Two, | ||
434 | } | ||
435 | enum B { | ||
436 | One, | ||
437 | Two, | ||
438 | } | ||
439 | 443 | ||
440 | fn main() { | 444 | fn main() { |
441 | let a = A::One; | 445 | let a = A::One; |
442 | let b = B::One; | 446 | let b = B::One; |
443 | match <|>(&a, &b) { | 447 | match (&a, &b) { |
444 | (A::One, B::One) => {} | 448 | $0(A::One, B::One) => {} |
445 | (A::One, B::Two) => {} | 449 | (A::One, B::Two) => {} |
446 | (A::Two, B::One) => {} | 450 | (A::Two, B::One) => {} |
447 | (A::Two, B::Two) => {} | 451 | (A::Two, B::Two) => {} |
@@ -456,14 +460,8 @@ mod tests { | |||
456 | check_assist_not_applicable( | 460 | check_assist_not_applicable( |
457 | fill_match_arms, | 461 | fill_match_arms, |
458 | r#" | 462 | r#" |
459 | enum A { | 463 | enum A { One, Two } |
460 | One, | 464 | enum B { One, Two } |
461 | Two, | ||
462 | } | ||
463 | enum B { | ||
464 | One, | ||
465 | Two, | ||
466 | } | ||
467 | 465 | ||
468 | fn main() { | 466 | fn main() { |
469 | let a = A::One; | 467 | let a = A::One; |
@@ -481,14 +479,8 @@ mod tests { | |||
481 | check_assist_not_applicable( | 479 | check_assist_not_applicable( |
482 | fill_match_arms, | 480 | fill_match_arms, |
483 | r#" | 481 | r#" |
484 | enum A { | 482 | enum A { One, Two } |
485 | One, | 483 | enum B { One, Two } |
486 | Two, | ||
487 | } | ||
488 | enum B { | ||
489 | One, | ||
490 | Two, | ||
491 | } | ||
492 | 484 | ||
493 | fn main() { | 485 | fn main() { |
494 | let a = A::One; | 486 | let a = A::One; |
@@ -512,10 +504,7 @@ mod tests { | |||
512 | check_assist_not_applicable( | 504 | check_assist_not_applicable( |
513 | fill_match_arms, | 505 | fill_match_arms, |
514 | r#" | 506 | r#" |
515 | enum A { | 507 | enum A { One, Two } |
516 | One, | ||
517 | Two, | ||
518 | } | ||
519 | 508 | ||
520 | fn main() { | 509 | fn main() { |
521 | let a = A::One; | 510 | let a = A::One; |
@@ -531,9 +520,7 @@ mod tests { | |||
531 | check_assist( | 520 | check_assist( |
532 | fill_match_arms, | 521 | fill_match_arms, |
533 | r#" | 522 | r#" |
534 | enum A { | 523 | enum A { As } |
535 | As, | ||
536 | } | ||
537 | 524 | ||
538 | fn foo(a: &A) { | 525 | fn foo(a: &A) { |
539 | match a<|> { | 526 | match a<|> { |
@@ -541,13 +528,11 @@ mod tests { | |||
541 | } | 528 | } |
542 | "#, | 529 | "#, |
543 | r#" | 530 | r#" |
544 | enum A { | 531 | enum A { As } |
545 | As, | ||
546 | } | ||
547 | 532 | ||
548 | fn foo(a: &A) { | 533 | fn foo(a: &A) { |
549 | match <|>a { | 534 | match a { |
550 | A::As => {} | 535 | $0A::As => {} |
551 | } | 536 | } |
552 | } | 537 | } |
553 | "#, | 538 | "#, |
@@ -557,7 +542,7 @@ mod tests { | |||
557 | fill_match_arms, | 542 | fill_match_arms, |
558 | r#" | 543 | r#" |
559 | enum A { | 544 | enum A { |
560 | Es{ x: usize, y: usize } | 545 | Es { x: usize, y: usize } |
561 | } | 546 | } |
562 | 547 | ||
563 | fn foo(a: &mut A) { | 548 | fn foo(a: &mut A) { |
@@ -567,12 +552,12 @@ mod tests { | |||
567 | "#, | 552 | "#, |
568 | r#" | 553 | r#" |
569 | enum A { | 554 | enum A { |
570 | Es{ x: usize, y: usize } | 555 | Es { x: usize, y: usize } |
571 | } | 556 | } |
572 | 557 | ||
573 | fn foo(a: &mut A) { | 558 | fn foo(a: &mut A) { |
574 | match <|>a { | 559 | match a { |
575 | A::Es { x, y } => {} | 560 | $0A::Es { x, y } => {} |
576 | } | 561 | } |
577 | } | 562 | } |
578 | "#, | 563 | "#, |
@@ -611,8 +596,8 @@ mod tests { | |||
611 | enum E { X, Y } | 596 | enum E { X, Y } |
612 | 597 | ||
613 | fn main() { | 598 | fn main() { |
614 | match <|>E::X { | 599 | match E::X { |
615 | E::X => {} | 600 | $0E::X => {} |
616 | E::Y => {} | 601 | E::Y => {} |
617 | } | 602 | } |
618 | } | 603 | } |
@@ -639,8 +624,8 @@ mod tests { | |||
639 | use foo::E::X; | 624 | use foo::E::X; |
640 | 625 | ||
641 | fn main() { | 626 | fn main() { |
642 | match <|>X { | 627 | match X { |
643 | X => {} | 628 | $0X => {} |
644 | foo::E::Y => {} | 629 | foo::E::Y => {} |
645 | } | 630 | } |
646 | } | 631 | } |
@@ -653,10 +638,7 @@ mod tests { | |||
653 | check_assist( | 638 | check_assist( |
654 | fill_match_arms, | 639 | fill_match_arms, |
655 | r#" | 640 | r#" |
656 | enum A { | 641 | enum A { One, Two } |
657 | One, | ||
658 | Two, | ||
659 | } | ||
660 | fn foo(a: A) { | 642 | fn foo(a: A) { |
661 | match a { | 643 | match a { |
662 | // foo bar baz<|> | 644 | // foo bar baz<|> |
@@ -666,16 +648,13 @@ mod tests { | |||
666 | } | 648 | } |
667 | "#, | 649 | "#, |
668 | r#" | 650 | r#" |
669 | enum A { | 651 | enum A { One, Two } |
670 | One, | ||
671 | Two, | ||
672 | } | ||
673 | fn foo(a: A) { | 652 | fn foo(a: A) { |
674 | match <|>a { | 653 | match a { |
675 | // foo bar baz | 654 | // foo bar baz |
676 | A::One => {} | 655 | A::One => {} |
677 | // This is where the rest should be | 656 | // This is where the rest should be |
678 | A::Two => {} | 657 | $0A::Two => {} |
679 | } | 658 | } |
680 | } | 659 | } |
681 | "#, | 660 | "#, |
@@ -687,10 +666,7 @@ mod tests { | |||
687 | check_assist( | 666 | check_assist( |
688 | fill_match_arms, | 667 | fill_match_arms, |
689 | r#" | 668 | r#" |
690 | enum A { | 669 | enum A { One, Two } |
691 | One, | ||
692 | Two, | ||
693 | } | ||
694 | fn foo(a: A) { | 670 | fn foo(a: A) { |
695 | match a { | 671 | match a { |
696 | // foo bar baz<|> | 672 | // foo bar baz<|> |
@@ -698,14 +674,11 @@ mod tests { | |||
698 | } | 674 | } |
699 | "#, | 675 | "#, |
700 | r#" | 676 | r#" |
701 | enum A { | 677 | enum A { One, Two } |
702 | One, | ||
703 | Two, | ||
704 | } | ||
705 | fn foo(a: A) { | 678 | fn foo(a: A) { |
706 | match <|>a { | 679 | match a { |
707 | // foo bar baz | 680 | // foo bar baz |
708 | A::One => {} | 681 | $0A::One => {} |
709 | A::Two => {} | 682 | A::Two => {} |
710 | } | 683 | } |
711 | } | 684 | } |
@@ -728,12 +701,37 @@ mod tests { | |||
728 | r#" | 701 | r#" |
729 | enum A { One, Two, } | 702 | enum A { One, Two, } |
730 | fn foo(a: A) { | 703 | fn foo(a: A) { |
731 | match <|>a { | 704 | match a { |
732 | A::One => {} | 705 | $0A::One => {} |
733 | A::Two => {} | 706 | A::Two => {} |
734 | } | 707 | } |
735 | } | 708 | } |
736 | "#, | 709 | "#, |
737 | ); | 710 | ); |
738 | } | 711 | } |
712 | |||
713 | #[test] | ||
714 | fn option_order() { | ||
715 | mark::check!(option_order); | ||
716 | let before = r#" | ||
717 | fn foo(opt: Option<i32>) { | ||
718 | match opt<|> { | ||
719 | } | ||
720 | }"#; | ||
721 | let before = | ||
722 | &format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE); | ||
723 | |||
724 | check_assist( | ||
725 | fill_match_arms, | ||
726 | before, | ||
727 | r#" | ||
728 | fn foo(opt: Option<i32>) { | ||
729 | match opt { | ||
730 | $0Some(_) => {} | ||
731 | None => {} | ||
732 | } | ||
733 | } | ||
734 | "#, | ||
735 | ); | ||
736 | } | ||
739 | } | 737 | } |
diff --git a/crates/ra_assists/src/handlers/fix_visibility.rs b/crates/ra_assists/src/handlers/fix_visibility.rs new file mode 100644 index 000000000..9ec42f568 --- /dev/null +++ b/crates/ra_assists/src/handlers/fix_visibility.rs | |||
@@ -0,0 +1,559 @@ | |||
1 | use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution}; | ||
2 | use ra_db::FileId; | ||
3 | use ra_syntax::{ | ||
4 | ast, AstNode, | ||
5 | SyntaxKind::{ATTR, COMMENT, WHITESPACE}, | ||
6 | SyntaxNode, TextRange, TextSize, | ||
7 | }; | ||
8 | |||
9 | use crate::{AssistContext, AssistId, Assists}; | ||
10 | |||
11 | // FIXME: this really should be a fix for diagnostic, rather than an assist. | ||
12 | |||
13 | // Assist: fix_visibility | ||
14 | // | ||
15 | // Makes inaccessible item public. | ||
16 | // | ||
17 | // ``` | ||
18 | // mod m { | ||
19 | // fn frobnicate() {} | ||
20 | // } | ||
21 | // fn main() { | ||
22 | // m::frobnicate<|>() {} | ||
23 | // } | ||
24 | // ``` | ||
25 | // -> | ||
26 | // ``` | ||
27 | // mod m { | ||
28 | // $0pub(crate) fn frobnicate() {} | ||
29 | // } | ||
30 | // fn main() { | ||
31 | // m::frobnicate() {} | ||
32 | // } | ||
33 | // ``` | ||
34 | pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
35 | add_vis_to_referenced_module_def(acc, ctx) | ||
36 | .or_else(|| add_vis_to_referenced_record_field(acc, ctx)) | ||
37 | } | ||
38 | |||
39 | fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
40 | let path: ast::Path = ctx.find_node_at_offset()?; | ||
41 | let path_res = ctx.sema.resolve_path(&path)?; | ||
42 | let def = match path_res { | ||
43 | PathResolution::Def(def) => def, | ||
44 | _ => return None, | ||
45 | }; | ||
46 | |||
47 | let current_module = ctx.sema.scope(&path.syntax()).module()?; | ||
48 | let target_module = def.module(ctx.db)?; | ||
49 | |||
50 | let vis = target_module.visibility_of(ctx.db, &def)?; | ||
51 | if vis.is_visible_from(ctx.db, current_module.into()) { | ||
52 | return None; | ||
53 | }; | ||
54 | |||
55 | let (offset, target, target_file, target_name) = target_data_for_def(ctx.db, def)?; | ||
56 | |||
57 | let missing_visibility = | ||
58 | if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" }; | ||
59 | |||
60 | let assist_label = match target_name { | ||
61 | None => format!("Change visibility to {}", missing_visibility), | ||
62 | Some(name) => format!("Change visibility of {} to {}", name, missing_visibility), | ||
63 | }; | ||
64 | |||
65 | acc.add(AssistId("fix_visibility"), assist_label, target, |builder| { | ||
66 | builder.set_file(target_file); | ||
67 | match ctx.config.snippet_cap { | ||
68 | Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)), | ||
69 | None => builder.insert(offset, format!("{} ", missing_visibility)), | ||
70 | } | ||
71 | }) | ||
72 | } | ||
73 | |||
74 | fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
75 | let record_field: ast::RecordField = ctx.find_node_at_offset()?; | ||
76 | let (record_field_def, _) = ctx.sema.resolve_record_field(&record_field)?; | ||
77 | |||
78 | let current_module = ctx.sema.scope(record_field.syntax()).module()?; | ||
79 | let visibility = record_field_def.visibility(ctx.db); | ||
80 | if visibility.is_visible_from(ctx.db, current_module.into()) { | ||
81 | return None; | ||
82 | } | ||
83 | |||
84 | let parent = record_field_def.parent_def(ctx.db); | ||
85 | let parent_name = parent.name(ctx.db); | ||
86 | let target_module = parent.module(ctx.db); | ||
87 | |||
88 | let in_file_source = record_field_def.source(ctx.db); | ||
89 | let (offset, target) = match in_file_source.value { | ||
90 | hir::FieldSource::Named(it) => { | ||
91 | let s = it.syntax(); | ||
92 | (vis_offset(s), s.text_range()) | ||
93 | } | ||
94 | hir::FieldSource::Pos(it) => { | ||
95 | let s = it.syntax(); | ||
96 | (vis_offset(s), s.text_range()) | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | let missing_visibility = | ||
101 | if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" }; | ||
102 | let target_file = in_file_source.file_id.original_file(ctx.db); | ||
103 | |||
104 | let target_name = record_field_def.name(ctx.db); | ||
105 | let assist_label = | ||
106 | format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility); | ||
107 | |||
108 | acc.add(AssistId("fix_visibility"), assist_label, target, |builder| { | ||
109 | builder.set_file(target_file); | ||
110 | match ctx.config.snippet_cap { | ||
111 | Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)), | ||
112 | None => builder.insert(offset, format!("{} ", missing_visibility)), | ||
113 | } | ||
114 | }) | ||
115 | } | ||
116 | |||
117 | fn target_data_for_def( | ||
118 | db: &dyn HirDatabase, | ||
119 | def: hir::ModuleDef, | ||
120 | ) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> { | ||
121 | fn offset_target_and_file_id<S, Ast>( | ||
122 | db: &dyn HirDatabase, | ||
123 | x: S, | ||
124 | ) -> (TextSize, TextRange, FileId) | ||
125 | where | ||
126 | S: HasSource<Ast = Ast>, | ||
127 | Ast: AstNode, | ||
128 | { | ||
129 | let source = x.source(db); | ||
130 | let in_file_syntax = source.syntax(); | ||
131 | let file_id = in_file_syntax.file_id; | ||
132 | let syntax = in_file_syntax.value; | ||
133 | (vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast())) | ||
134 | } | ||
135 | |||
136 | let target_name; | ||
137 | let (offset, target, target_file) = match def { | ||
138 | hir::ModuleDef::Function(f) => { | ||
139 | target_name = Some(f.name(db)); | ||
140 | offset_target_and_file_id(db, f) | ||
141 | } | ||
142 | hir::ModuleDef::Adt(adt) => { | ||
143 | target_name = Some(adt.name(db)); | ||
144 | match adt { | ||
145 | hir::Adt::Struct(s) => offset_target_and_file_id(db, s), | ||
146 | hir::Adt::Union(u) => offset_target_and_file_id(db, u), | ||
147 | hir::Adt::Enum(e) => offset_target_and_file_id(db, e), | ||
148 | } | ||
149 | } | ||
150 | hir::ModuleDef::Const(c) => { | ||
151 | target_name = c.name(db); | ||
152 | offset_target_and_file_id(db, c) | ||
153 | } | ||
154 | hir::ModuleDef::Static(s) => { | ||
155 | target_name = s.name(db); | ||
156 | offset_target_and_file_id(db, s) | ||
157 | } | ||
158 | hir::ModuleDef::Trait(t) => { | ||
159 | target_name = Some(t.name(db)); | ||
160 | offset_target_and_file_id(db, t) | ||
161 | } | ||
162 | hir::ModuleDef::TypeAlias(t) => { | ||
163 | target_name = Some(t.name(db)); | ||
164 | offset_target_and_file_id(db, t) | ||
165 | } | ||
166 | hir::ModuleDef::Module(m) => { | ||
167 | target_name = m.name(db); | ||
168 | let in_file_source = m.declaration_source(db)?; | ||
169 | let file_id = in_file_source.file_id.original_file(db.upcast()); | ||
170 | let syntax = in_file_source.value.syntax(); | ||
171 | (vis_offset(syntax), syntax.text_range(), file_id) | ||
172 | } | ||
173 | // Enum variants can't be private, we can't modify builtin types | ||
174 | hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, | ||
175 | }; | ||
176 | |||
177 | Some((offset, target, target_file, target_name)) | ||
178 | } | ||
179 | |||
180 | fn vis_offset(node: &SyntaxNode) -> TextSize { | ||
181 | node.children_with_tokens() | ||
182 | .skip_while(|it| match it.kind() { | ||
183 | WHITESPACE | COMMENT | ATTR => true, | ||
184 | _ => false, | ||
185 | }) | ||
186 | .next() | ||
187 | .map(|it| it.text_range().start()) | ||
188 | .unwrap_or_else(|| node.text_range().start()) | ||
189 | } | ||
190 | |||
191 | #[cfg(test)] | ||
192 | mod tests { | ||
193 | use crate::tests::{check_assist, check_assist_not_applicable}; | ||
194 | |||
195 | use super::*; | ||
196 | |||
197 | #[test] | ||
198 | fn fix_visibility_of_fn() { | ||
199 | check_assist( | ||
200 | fix_visibility, | ||
201 | r"mod foo { fn foo() {} } | ||
202 | fn main() { foo::foo<|>() } ", | ||
203 | r"mod foo { $0pub(crate) fn foo() {} } | ||
204 | fn main() { foo::foo() } ", | ||
205 | ); | ||
206 | check_assist_not_applicable( | ||
207 | fix_visibility, | ||
208 | r"mod foo { pub fn foo() {} } | ||
209 | fn main() { foo::foo<|>() } ", | ||
210 | ) | ||
211 | } | ||
212 | |||
213 | #[test] | ||
214 | fn fix_visibility_of_adt_in_submodule() { | ||
215 | check_assist( | ||
216 | fix_visibility, | ||
217 | r"mod foo { struct Foo; } | ||
218 | fn main() { foo::Foo<|> } ", | ||
219 | r"mod foo { $0pub(crate) struct Foo; } | ||
220 | fn main() { foo::Foo } ", | ||
221 | ); | ||
222 | check_assist_not_applicable( | ||
223 | fix_visibility, | ||
224 | r"mod foo { pub struct Foo; } | ||
225 | fn main() { foo::Foo<|> } ", | ||
226 | ); | ||
227 | check_assist( | ||
228 | fix_visibility, | ||
229 | r"mod foo { enum Foo; } | ||
230 | fn main() { foo::Foo<|> } ", | ||
231 | r"mod foo { $0pub(crate) enum Foo; } | ||
232 | fn main() { foo::Foo } ", | ||
233 | ); | ||
234 | check_assist_not_applicable( | ||
235 | fix_visibility, | ||
236 | r"mod foo { pub enum Foo; } | ||
237 | fn main() { foo::Foo<|> } ", | ||
238 | ); | ||
239 | check_assist( | ||
240 | fix_visibility, | ||
241 | r"mod foo { union Foo; } | ||
242 | fn main() { foo::Foo<|> } ", | ||
243 | r"mod foo { $0pub(crate) union Foo; } | ||
244 | fn main() { foo::Foo } ", | ||
245 | ); | ||
246 | check_assist_not_applicable( | ||
247 | fix_visibility, | ||
248 | r"mod foo { pub union Foo; } | ||
249 | fn main() { foo::Foo<|> } ", | ||
250 | ); | ||
251 | } | ||
252 | |||
253 | #[test] | ||
254 | fn fix_visibility_of_adt_in_other_file() { | ||
255 | check_assist( | ||
256 | fix_visibility, | ||
257 | r" | ||
258 | //- /main.rs | ||
259 | mod foo; | ||
260 | fn main() { foo::Foo<|> } | ||
261 | |||
262 | //- /foo.rs | ||
263 | struct Foo; | ||
264 | ", | ||
265 | r"$0pub(crate) struct Foo; | ||
266 | |||
267 | ", | ||
268 | ); | ||
269 | } | ||
270 | |||
271 | #[test] | ||
272 | fn fix_visibility_of_struct_field() { | ||
273 | check_assist( | ||
274 | fix_visibility, | ||
275 | r"mod foo { pub struct Foo { bar: (), } } | ||
276 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
277 | r"mod foo { pub struct Foo { $0pub(crate) bar: (), } } | ||
278 | fn main() { foo::Foo { bar: () }; } ", | ||
279 | ); | ||
280 | check_assist( | ||
281 | fix_visibility, | ||
282 | r"//- /lib.rs | ||
283 | mod foo; | ||
284 | fn main() { foo::Foo { <|>bar: () }; } | ||
285 | //- /foo.rs | ||
286 | pub struct Foo { bar: () } | ||
287 | ", | ||
288 | r"pub struct Foo { $0pub(crate) bar: () } | ||
289 | |||
290 | ", | ||
291 | ); | ||
292 | check_assist_not_applicable( | ||
293 | fix_visibility, | ||
294 | r"mod foo { pub struct Foo { pub bar: (), } } | ||
295 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
296 | ); | ||
297 | check_assist_not_applicable( | ||
298 | fix_visibility, | ||
299 | r"//- /lib.rs | ||
300 | mod foo; | ||
301 | fn main() { foo::Foo { <|>bar: () }; } | ||
302 | //- /foo.rs | ||
303 | pub struct Foo { pub bar: () } | ||
304 | ", | ||
305 | ); | ||
306 | } | ||
307 | |||
308 | #[test] | ||
309 | fn fix_visibility_of_enum_variant_field() { | ||
310 | check_assist( | ||
311 | fix_visibility, | ||
312 | r"mod foo { pub enum Foo { Bar { bar: () } } } | ||
313 | fn main() { foo::Foo::Bar { <|>bar: () }; } ", | ||
314 | r"mod foo { pub enum Foo { Bar { $0pub(crate) bar: () } } } | ||
315 | fn main() { foo::Foo::Bar { bar: () }; } ", | ||
316 | ); | ||
317 | check_assist( | ||
318 | fix_visibility, | ||
319 | r"//- /lib.rs | ||
320 | mod foo; | ||
321 | fn main() { foo::Foo::Bar { <|>bar: () }; } | ||
322 | //- /foo.rs | ||
323 | pub enum Foo { Bar { bar: () } } | ||
324 | ", | ||
325 | r"pub enum Foo { Bar { $0pub(crate) bar: () } } | ||
326 | |||
327 | ", | ||
328 | ); | ||
329 | check_assist_not_applicable( | ||
330 | fix_visibility, | ||
331 | r"mod foo { pub struct Foo { pub bar: (), } } | ||
332 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
333 | ); | ||
334 | check_assist_not_applicable( | ||
335 | fix_visibility, | ||
336 | r"//- /lib.rs | ||
337 | mod foo; | ||
338 | fn main() { foo::Foo { <|>bar: () }; } | ||
339 | //- /foo.rs | ||
340 | pub struct Foo { pub bar: () } | ||
341 | ", | ||
342 | ); | ||
343 | } | ||
344 | |||
345 | #[test] | ||
346 | #[ignore] | ||
347 | // FIXME reenable this test when `Semantics::resolve_record_field` works with union fields | ||
348 | fn fix_visibility_of_union_field() { | ||
349 | check_assist( | ||
350 | fix_visibility, | ||
351 | r"mod foo { pub union Foo { bar: (), } } | ||
352 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
353 | r"mod foo { pub union Foo { $0pub(crate) bar: (), } } | ||
354 | fn main() { foo::Foo { bar: () }; } ", | ||
355 | ); | ||
356 | check_assist( | ||
357 | fix_visibility, | ||
358 | r"//- /lib.rs | ||
359 | mod foo; | ||
360 | fn main() { foo::Foo { <|>bar: () }; } | ||
361 | //- /foo.rs | ||
362 | pub union Foo { bar: () } | ||
363 | ", | ||
364 | r"pub union Foo { $0pub(crate) bar: () } | ||
365 | |||
366 | ", | ||
367 | ); | ||
368 | check_assist_not_applicable( | ||
369 | fix_visibility, | ||
370 | r"mod foo { pub union Foo { pub bar: (), } } | ||
371 | fn main() { foo::Foo { <|>bar: () }; } ", | ||
372 | ); | ||
373 | check_assist_not_applicable( | ||
374 | fix_visibility, | ||
375 | r"//- /lib.rs | ||
376 | mod foo; | ||
377 | fn main() { foo::Foo { <|>bar: () }; } | ||
378 | //- /foo.rs | ||
379 | pub union Foo { pub bar: () } | ||
380 | ", | ||
381 | ); | ||
382 | } | ||
383 | |||
384 | #[test] | ||
385 | fn fix_visibility_of_const() { | ||
386 | check_assist( | ||
387 | fix_visibility, | ||
388 | r"mod foo { const FOO: () = (); } | ||
389 | fn main() { foo::FOO<|> } ", | ||
390 | r"mod foo { $0pub(crate) const FOO: () = (); } | ||
391 | fn main() { foo::FOO } ", | ||
392 | ); | ||
393 | check_assist_not_applicable( | ||
394 | fix_visibility, | ||
395 | r"mod foo { pub const FOO: () = (); } | ||
396 | fn main() { foo::FOO<|> } ", | ||
397 | ); | ||
398 | } | ||
399 | |||
400 | #[test] | ||
401 | fn fix_visibility_of_static() { | ||
402 | check_assist( | ||
403 | fix_visibility, | ||
404 | r"mod foo { static FOO: () = (); } | ||
405 | fn main() { foo::FOO<|> } ", | ||
406 | r"mod foo { $0pub(crate) static FOO: () = (); } | ||
407 | fn main() { foo::FOO } ", | ||
408 | ); | ||
409 | check_assist_not_applicable( | ||
410 | fix_visibility, | ||
411 | r"mod foo { pub static FOO: () = (); } | ||
412 | fn main() { foo::FOO<|> } ", | ||
413 | ); | ||
414 | } | ||
415 | |||
416 | #[test] | ||
417 | fn fix_visibility_of_trait() { | ||
418 | check_assist( | ||
419 | fix_visibility, | ||
420 | r"mod foo { trait Foo { fn foo(&self) {} } } | ||
421 | fn main() { let x: &dyn foo::<|>Foo; } ", | ||
422 | r"mod foo { $0pub(crate) trait Foo { fn foo(&self) {} } } | ||
423 | fn main() { let x: &dyn foo::Foo; } ", | ||
424 | ); | ||
425 | check_assist_not_applicable( | ||
426 | fix_visibility, | ||
427 | r"mod foo { pub trait Foo { fn foo(&self) {} } } | ||
428 | fn main() { let x: &dyn foo::Foo<|>; } ", | ||
429 | ); | ||
430 | } | ||
431 | |||
432 | #[test] | ||
433 | fn fix_visibility_of_type_alias() { | ||
434 | check_assist( | ||
435 | fix_visibility, | ||
436 | r"mod foo { type Foo = (); } | ||
437 | fn main() { let x: foo::Foo<|>; } ", | ||
438 | r"mod foo { $0pub(crate) type Foo = (); } | ||
439 | fn main() { let x: foo::Foo; } ", | ||
440 | ); | ||
441 | check_assist_not_applicable( | ||
442 | fix_visibility, | ||
443 | r"mod foo { pub type Foo = (); } | ||
444 | fn main() { let x: foo::Foo<|>; } ", | ||
445 | ); | ||
446 | } | ||
447 | |||
448 | #[test] | ||
449 | fn fix_visibility_of_module() { | ||
450 | check_assist( | ||
451 | fix_visibility, | ||
452 | r"mod foo { mod bar { fn bar() {} } } | ||
453 | fn main() { foo::bar<|>::bar(); } ", | ||
454 | r"mod foo { $0pub(crate) mod bar { fn bar() {} } } | ||
455 | fn main() { foo::bar::bar(); } ", | ||
456 | ); | ||
457 | |||
458 | check_assist( | ||
459 | fix_visibility, | ||
460 | r" | ||
461 | //- /main.rs | ||
462 | mod foo; | ||
463 | fn main() { foo::bar<|>::baz(); } | ||
464 | |||
465 | //- /foo.rs | ||
466 | mod bar { | ||
467 | pub fn baz() {} | ||
468 | } | ||
469 | ", | ||
470 | r"$0pub(crate) mod bar { | ||
471 | pub fn baz() {} | ||
472 | } | ||
473 | |||
474 | ", | ||
475 | ); | ||
476 | |||
477 | check_assist_not_applicable( | ||
478 | fix_visibility, | ||
479 | r"mod foo { pub mod bar { pub fn bar() {} } } | ||
480 | fn main() { foo::bar<|>::bar(); } ", | ||
481 | ); | ||
482 | } | ||
483 | |||
484 | #[test] | ||
485 | fn fix_visibility_of_inline_module_in_other_file() { | ||
486 | check_assist( | ||
487 | fix_visibility, | ||
488 | r" | ||
489 | //- /main.rs | ||
490 | mod foo; | ||
491 | fn main() { foo::bar<|>::baz(); } | ||
492 | |||
493 | //- /foo.rs | ||
494 | mod bar; | ||
495 | |||
496 | //- /foo/bar.rs | ||
497 | pub fn baz() {} | ||
498 | } | ||
499 | ", | ||
500 | r"$0pub(crate) mod bar; | ||
501 | ", | ||
502 | ); | ||
503 | } | ||
504 | |||
505 | #[test] | ||
506 | fn fix_visibility_of_module_declaration_in_other_file() { | ||
507 | check_assist( | ||
508 | fix_visibility, | ||
509 | r"//- /main.rs | ||
510 | mod foo; | ||
511 | fn main() { foo::bar<|>>::baz(); } | ||
512 | |||
513 | //- /foo.rs | ||
514 | mod bar { | ||
515 | pub fn baz() {} | ||
516 | }", | ||
517 | r"$0pub(crate) mod bar { | ||
518 | pub fn baz() {} | ||
519 | } | ||
520 | ", | ||
521 | ); | ||
522 | } | ||
523 | |||
524 | #[test] | ||
525 | fn adds_pub_when_target_is_in_another_crate() { | ||
526 | check_assist( | ||
527 | fix_visibility, | ||
528 | r"//- /main.rs crate:a deps:foo | ||
529 | foo::Bar<|> | ||
530 | //- /lib.rs crate:foo | ||
531 | struct Bar;", | ||
532 | r"$0pub struct Bar; | ||
533 | ", | ||
534 | ) | ||
535 | } | ||
536 | |||
537 | #[test] | ||
538 | #[ignore] | ||
539 | // FIXME handle reexports properly | ||
540 | fn fix_visibility_of_reexport() { | ||
541 | check_assist( | ||
542 | fix_visibility, | ||
543 | r" | ||
544 | mod foo { | ||
545 | use bar::Baz; | ||
546 | mod bar { pub(super) struct Baz; } | ||
547 | } | ||
548 | foo::Baz<|> | ||
549 | ", | ||
550 | r" | ||
551 | mod foo { | ||
552 | $0pub(crate) use bar::Baz; | ||
553 | mod bar { pub(super) struct Baz; } | ||
554 | } | ||
555 | foo::Baz | ||
556 | ", | ||
557 | ) | ||
558 | } | ||
559 | } | ||
diff --git a/crates/ra_assists/src/handlers/flip_binexpr.rs b/crates/ra_assists/src/handlers/flip_binexpr.rs index 692ba4895..573196576 100644 --- a/crates/ra_assists/src/handlers/flip_binexpr.rs +++ b/crates/ra_assists/src/handlers/flip_binexpr.rs | |||
@@ -85,17 +85,13 @@ mod tests { | |||
85 | check_assist( | 85 | check_assist( |
86 | flip_binexpr, | 86 | flip_binexpr, |
87 | "fn f() { let res = 1 ==<|> 2; }", | 87 | "fn f() { let res = 1 ==<|> 2; }", |
88 | "fn f() { let res = 2 ==<|> 1; }", | 88 | "fn f() { let res = 2 == 1; }", |
89 | ) | 89 | ) |
90 | } | 90 | } |
91 | 91 | ||
92 | #[test] | 92 | #[test] |
93 | fn flip_binexpr_works_for_gt() { | 93 | fn flip_binexpr_works_for_gt() { |
94 | check_assist( | 94 | check_assist(flip_binexpr, "fn f() { let res = 1 ><|> 2; }", "fn f() { let res = 2 < 1; }") |
95 | flip_binexpr, | ||
96 | "fn f() { let res = 1 ><|> 2; }", | ||
97 | "fn f() { let res = 2 <<|> 1; }", | ||
98 | ) | ||
99 | } | 95 | } |
100 | 96 | ||
101 | #[test] | 97 | #[test] |
@@ -103,7 +99,7 @@ mod tests { | |||
103 | check_assist( | 99 | check_assist( |
104 | flip_binexpr, | 100 | flip_binexpr, |
105 | "fn f() { let res = 1 <=<|> 2; }", | 101 | "fn f() { let res = 1 <=<|> 2; }", |
106 | "fn f() { let res = 2 >=<|> 1; }", | 102 | "fn f() { let res = 2 >= 1; }", |
107 | ) | 103 | ) |
108 | } | 104 | } |
109 | 105 | ||
@@ -112,7 +108,7 @@ mod tests { | |||
112 | check_assist( | 108 | check_assist( |
113 | flip_binexpr, | 109 | flip_binexpr, |
114 | "fn f() { let res = (1 + 1) ==<|> (2 + 2); }", | 110 | "fn f() { let res = (1 + 1) ==<|> (2 + 2); }", |
115 | "fn f() { let res = (2 + 2) ==<|> (1 + 1); }", | 111 | "fn f() { let res = (2 + 2) == (1 + 1); }", |
116 | ) | 112 | ) |
117 | } | 113 | } |
118 | 114 | ||
@@ -132,7 +128,7 @@ mod tests { | |||
132 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { | 128 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { |
133 | match other.downcast_ref::<Self>() { | 129 | match other.downcast_ref::<Self>() { |
134 | None => false, | 130 | None => false, |
135 | Some(it) => self ==<|> it, | 131 | Some(it) => self == it, |
136 | } | 132 | } |
137 | } | 133 | } |
138 | "#, | 134 | "#, |
diff --git a/crates/ra_assists/src/handlers/flip_comma.rs b/crates/ra_assists/src/handlers/flip_comma.rs index dfe2a7fed..a57a1c463 100644 --- a/crates/ra_assists/src/handlers/flip_comma.rs +++ b/crates/ra_assists/src/handlers/flip_comma.rs | |||
@@ -45,7 +45,7 @@ mod tests { | |||
45 | check_assist( | 45 | check_assist( |
46 | flip_comma, | 46 | flip_comma, |
47 | "fn foo(x: i32,<|> y: Result<(), ()>) {}", | 47 | "fn foo(x: i32,<|> y: Result<(), ()>) {}", |
48 | "fn foo(y: Result<(), ()>,<|> x: i32) {}", | 48 | "fn foo(y: Result<(), ()>, x: i32) {}", |
49 | ) | 49 | ) |
50 | } | 50 | } |
51 | 51 | ||
diff --git a/crates/ra_assists/src/handlers/flip_trait_bound.rs b/crates/ra_assists/src/handlers/flip_trait_bound.rs index 8a08702ab..0115adc8b 100644 --- a/crates/ra_assists/src/handlers/flip_trait_bound.rs +++ b/crates/ra_assists/src/handlers/flip_trait_bound.rs | |||
@@ -60,7 +60,7 @@ mod tests { | |||
60 | check_assist( | 60 | check_assist( |
61 | flip_trait_bound, | 61 | flip_trait_bound, |
62 | "struct S<T> where T: A <|>+ B { }", | 62 | "struct S<T> where T: A <|>+ B { }", |
63 | "struct S<T> where T: B <|>+ A { }", | 63 | "struct S<T> where T: B + A { }", |
64 | ) | 64 | ) |
65 | } | 65 | } |
66 | 66 | ||
@@ -69,13 +69,13 @@ mod tests { | |||
69 | check_assist( | 69 | check_assist( |
70 | flip_trait_bound, | 70 | flip_trait_bound, |
71 | "impl X for S<T> where T: A +<|> B { }", | 71 | "impl X for S<T> where T: A +<|> B { }", |
72 | "impl X for S<T> where T: B +<|> A { }", | 72 | "impl X for S<T> where T: B + A { }", |
73 | ) | 73 | ) |
74 | } | 74 | } |
75 | 75 | ||
76 | #[test] | 76 | #[test] |
77 | fn flip_trait_bound_works_for_fn() { | 77 | fn flip_trait_bound_works_for_fn() { |
78 | check_assist(flip_trait_bound, "fn f<T: A <|>+ B>(t: T) { }", "fn f<T: B <|>+ A>(t: T) { }") | 78 | check_assist(flip_trait_bound, "fn f<T: A <|>+ B>(t: T) { }", "fn f<T: B + A>(t: T) { }") |
79 | } | 79 | } |
80 | 80 | ||
81 | #[test] | 81 | #[test] |
@@ -83,7 +83,7 @@ mod tests { | |||
83 | check_assist( | 83 | check_assist( |
84 | flip_trait_bound, | 84 | flip_trait_bound, |
85 | "fn f<T>(t: T) where T: A +<|> B { }", | 85 | "fn f<T>(t: T) where T: A +<|> B { }", |
86 | "fn f<T>(t: T) where T: B +<|> A { }", | 86 | "fn f<T>(t: T) where T: B + A { }", |
87 | ) | 87 | ) |
88 | } | 88 | } |
89 | 89 | ||
@@ -92,7 +92,7 @@ mod tests { | |||
92 | check_assist( | 92 | check_assist( |
93 | flip_trait_bound, | 93 | flip_trait_bound, |
94 | "fn f<T>(t: T) where T: A <|>+ 'static { }", | 94 | "fn f<T>(t: T) where T: A <|>+ 'static { }", |
95 | "fn f<T>(t: T) where T: 'static <|>+ A { }", | 95 | "fn f<T>(t: T) where T: 'static + A { }", |
96 | ) | 96 | ) |
97 | } | 97 | } |
98 | 98 | ||
@@ -101,7 +101,7 @@ mod tests { | |||
101 | check_assist( | 101 | check_assist( |
102 | flip_trait_bound, | 102 | flip_trait_bound, |
103 | "struct S<T> where T: A<T> <|>+ b_mod::B<T> + C<T> { }", | 103 | "struct S<T> where T: A<T> <|>+ b_mod::B<T> + C<T> { }", |
104 | "struct S<T> where T: b_mod::B<T> <|>+ A<T> + C<T> { }", | 104 | "struct S<T> where T: b_mod::B<T> + A<T> + C<T> { }", |
105 | ) | 105 | ) |
106 | } | 106 | } |
107 | 107 | ||
@@ -110,7 +110,7 @@ mod tests { | |||
110 | check_assist( | 110 | check_assist( |
111 | flip_trait_bound, | 111 | flip_trait_bound, |
112 | "struct S<T> where T: A + B + C + D + E + F +<|> G + H + I + J { }", | 112 | "struct S<T> where T: A + B + C + D + E + F +<|> G + H + I + J { }", |
113 | "struct S<T> where T: A + B + C + D + E + G +<|> F + H + I + J { }", | 113 | "struct S<T> where T: A + B + C + D + E + G + F + H + I + J { }", |
114 | ) | 114 | ) |
115 | } | 115 | } |
116 | } | 116 | } |
diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs index 5b26814d3..46d675a4e 100644 --- a/crates/ra_assists/src/handlers/inline_local_variable.rs +++ b/crates/ra_assists/src/handlers/inline_local_variable.rs | |||
@@ -3,7 +3,7 @@ use ra_syntax::{ | |||
3 | ast::{self, AstNode, AstToken}, | 3 | ast::{self, AstNode, AstToken}, |
4 | TextRange, | 4 | TextRange, |
5 | }; | 5 | }; |
6 | use test_utils::tested_by; | 6 | use test_utils::mark; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | assist_context::{AssistContext, Assists}, | 9 | assist_context::{AssistContext, Assists}, |
@@ -33,11 +33,11 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O | |||
33 | _ => return None, | 33 | _ => return None, |
34 | }; | 34 | }; |
35 | if bind_pat.mut_token().is_some() { | 35 | if bind_pat.mut_token().is_some() { |
36 | tested_by!(test_not_inline_mut_variable); | 36 | mark::hit!(test_not_inline_mut_variable); |
37 | return None; | 37 | return None; |
38 | } | 38 | } |
39 | if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) { | 39 | if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) { |
40 | tested_by!(not_applicable_outside_of_bind_pat); | 40 | mark::hit!(not_applicable_outside_of_bind_pat); |
41 | return None; | 41 | return None; |
42 | } | 42 | } |
43 | let initializer_expr = let_stmt.initializer()?; | 43 | let initializer_expr = let_stmt.initializer()?; |
@@ -46,7 +46,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O | |||
46 | let def = Definition::Local(def); | 46 | let def = Definition::Local(def); |
47 | let refs = def.find_usages(ctx.db, None); | 47 | let refs = def.find_usages(ctx.db, None); |
48 | if refs.is_empty() { | 48 | if refs.is_empty() { |
49 | tested_by!(test_not_applicable_if_variable_unused); | 49 | mark::hit!(test_not_applicable_if_variable_unused); |
50 | return None; | 50 | return None; |
51 | }; | 51 | }; |
52 | 52 | ||
@@ -122,7 +122,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O | |||
122 | 122 | ||
123 | #[cfg(test)] | 123 | #[cfg(test)] |
124 | mod tests { | 124 | mod tests { |
125 | use test_utils::covers; | 125 | use test_utils::mark; |
126 | 126 | ||
127 | use crate::tests::{check_assist, check_assist_not_applicable}; | 127 | use crate::tests::{check_assist, check_assist_not_applicable}; |
128 | 128 | ||
@@ -330,7 +330,7 @@ fn foo() { | |||
330 | 330 | ||
331 | #[test] | 331 | #[test] |
332 | fn test_not_inline_mut_variable() { | 332 | fn test_not_inline_mut_variable() { |
333 | covers!(test_not_inline_mut_variable); | 333 | mark::check!(test_not_inline_mut_variable); |
334 | check_assist_not_applicable( | 334 | check_assist_not_applicable( |
335 | inline_local_variable, | 335 | inline_local_variable, |
336 | r" | 336 | r" |
@@ -663,7 +663,7 @@ fn foo() { | |||
663 | 663 | ||
664 | #[test] | 664 | #[test] |
665 | fn test_not_applicable_if_variable_unused() { | 665 | fn test_not_applicable_if_variable_unused() { |
666 | covers!(test_not_applicable_if_variable_unused); | 666 | mark::check!(test_not_applicable_if_variable_unused); |
667 | check_assist_not_applicable( | 667 | check_assist_not_applicable( |
668 | inline_local_variable, | 668 | inline_local_variable, |
669 | r" | 669 | r" |
@@ -676,7 +676,7 @@ fn foo() { | |||
676 | 676 | ||
677 | #[test] | 677 | #[test] |
678 | fn not_applicable_outside_of_bind_pat() { | 678 | fn not_applicable_outside_of_bind_pat() { |
679 | covers!(not_applicable_outside_of_bind_pat); | 679 | mark::check!(not_applicable_outside_of_bind_pat); |
680 | check_assist_not_applicable( | 680 | check_assist_not_applicable( |
681 | inline_local_variable, | 681 | inline_local_variable, |
682 | r" | 682 | r" |
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index fdf3ada0d..56c610fed 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs | |||
@@ -7,7 +7,7 @@ use ra_syntax::{ | |||
7 | SyntaxNode, TextSize, | 7 | SyntaxNode, TextSize, |
8 | }; | 8 | }; |
9 | use stdx::format_to; | 9 | use stdx::format_to; |
10 | use test_utils::tested_by; | 10 | use test_utils::mark; |
11 | 11 | ||
12 | use crate::{AssistContext, AssistId, Assists}; | 12 | use crate::{AssistContext, AssistId, Assists}; |
13 | 13 | ||
@@ -33,7 +33,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
33 | } | 33 | } |
34 | let node = ctx.covering_element(); | 34 | let node = ctx.covering_element(); |
35 | if node.kind() == COMMENT { | 35 | if node.kind() == COMMENT { |
36 | tested_by!(introduce_var_in_comment_is_not_applicable); | 36 | mark::hit!(introduce_var_in_comment_is_not_applicable); |
37 | return None; | 37 | return None; |
38 | } | 38 | } |
39 | let expr = node.ancestors().find_map(valid_target_expr)?; | 39 | let expr = node.ancestors().find_map(valid_target_expr)?; |
@@ -61,7 +61,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
61 | false | 61 | false |
62 | }; | 62 | }; |
63 | if is_full_stmt { | 63 | if is_full_stmt { |
64 | tested_by!(test_introduce_var_expr_stmt); | 64 | mark::hit!(test_introduce_var_expr_stmt); |
65 | if full_stmt.unwrap().semicolon_token().is_none() { | 65 | if full_stmt.unwrap().semicolon_token().is_none() { |
66 | buf.push_str(";"); | 66 | buf.push_str(";"); |
67 | } | 67 | } |
@@ -113,7 +113,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { | |||
113 | expr.syntax().ancestors().find_map(|node| { | 113 | expr.syntax().ancestors().find_map(|node| { |
114 | if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { | 114 | if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { |
115 | if expr.syntax() == &node { | 115 | if expr.syntax() == &node { |
116 | tested_by!(test_introduce_var_last_expr); | 116 | mark::hit!(test_introduce_var_last_expr); |
117 | return Some((node, false)); | 117 | return Some((node, false)); |
118 | } | 118 | } |
119 | } | 119 | } |
@@ -134,7 +134,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { | |||
134 | 134 | ||
135 | #[cfg(test)] | 135 | #[cfg(test)] |
136 | mod tests { | 136 | mod tests { |
137 | use test_utils::covers; | 137 | use test_utils::mark; |
138 | 138 | ||
139 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 139 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; |
140 | 140 | ||
@@ -158,13 +158,13 @@ fn foo() { | |||
158 | 158 | ||
159 | #[test] | 159 | #[test] |
160 | fn introduce_var_in_comment_is_not_applicable() { | 160 | fn introduce_var_in_comment_is_not_applicable() { |
161 | covers!(introduce_var_in_comment_is_not_applicable); | 161 | mark::check!(introduce_var_in_comment_is_not_applicable); |
162 | check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); | 162 | check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); |
163 | } | 163 | } |
164 | 164 | ||
165 | #[test] | 165 | #[test] |
166 | fn test_introduce_var_expr_stmt() { | 166 | fn test_introduce_var_expr_stmt() { |
167 | covers!(test_introduce_var_expr_stmt); | 167 | mark::check!(test_introduce_var_expr_stmt); |
168 | check_assist( | 168 | check_assist( |
169 | introduce_variable, | 169 | introduce_variable, |
170 | " | 170 | " |
@@ -209,7 +209,7 @@ fn foo() { | |||
209 | 209 | ||
210 | #[test] | 210 | #[test] |
211 | fn test_introduce_var_last_expr() { | 211 | fn test_introduce_var_last_expr() { |
212 | covers!(test_introduce_var_last_expr); | 212 | mark::check!(test_introduce_var_last_expr); |
213 | check_assist( | 213 | check_assist( |
214 | introduce_variable, | 214 | introduce_variable, |
215 | " | 215 | " |
diff --git a/crates/ra_assists/src/handlers/invert_if.rs b/crates/ra_assists/src/handlers/invert_if.rs index 527c7caef..59d278eb9 100644 --- a/crates/ra_assists/src/handlers/invert_if.rs +++ b/crates/ra_assists/src/handlers/invert_if.rs | |||
@@ -72,7 +72,7 @@ mod tests { | |||
72 | check_assist( | 72 | check_assist( |
73 | invert_if, | 73 | invert_if, |
74 | "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }", | 74 | "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }", |
75 | "fn f() { i<|>f x == 3 { 3 + 2 } else { 1 } }", | 75 | "fn f() { if x == 3 { 3 + 2 } else { 1 } }", |
76 | ) | 76 | ) |
77 | } | 77 | } |
78 | 78 | ||
@@ -81,7 +81,7 @@ mod tests { | |||
81 | check_assist( | 81 | check_assist( |
82 | invert_if, | 82 | invert_if, |
83 | "fn f() { <|>if !cond { 3 * 2 } else { 1 } }", | 83 | "fn f() { <|>if !cond { 3 * 2 } else { 1 } }", |
84 | "fn f() { <|>if cond { 1 } else { 3 * 2 } }", | 84 | "fn f() { if cond { 1 } else { 3 * 2 } }", |
85 | ) | 85 | ) |
86 | } | 86 | } |
87 | 87 | ||
@@ -90,7 +90,7 @@ mod tests { | |||
90 | check_assist( | 90 | check_assist( |
91 | invert_if, | 91 | invert_if, |
92 | "fn f() { i<|>f cond { 3 * 2 } else { 1 } }", | 92 | "fn f() { i<|>f cond { 3 * 2 } else { 1 } }", |
93 | "fn f() { i<|>f !cond { 1 } else { 3 * 2 } }", | 93 | "fn f() { if !cond { 1 } else { 3 * 2 } }", |
94 | ) | 94 | ) |
95 | } | 95 | } |
96 | 96 | ||
diff --git a/crates/ra_assists/src/handlers/move_bounds.rs b/crates/ra_assists/src/handlers/move_bounds.rs index a41aacfc3..be2a7eddc 100644 --- a/crates/ra_assists/src/handlers/move_bounds.rs +++ b/crates/ra_assists/src/handlers/move_bounds.rs | |||
@@ -99,7 +99,7 @@ mod tests { | |||
99 | fn foo<T: u32, <|>F: FnOnce(T) -> T>() {} | 99 | fn foo<T: u32, <|>F: FnOnce(T) -> T>() {} |
100 | "#, | 100 | "#, |
101 | r#" | 101 | r#" |
102 | fn foo<T, <|>F>() where T: u32, F: FnOnce(T) -> T {} | 102 | fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {} |
103 | "#, | 103 | "#, |
104 | ); | 104 | ); |
105 | } | 105 | } |
@@ -112,7 +112,7 @@ mod tests { | |||
112 | impl<U: u32, <|>T> A<U, T> {} | 112 | impl<U: u32, <|>T> A<U, T> {} |
113 | "#, | 113 | "#, |
114 | r#" | 114 | r#" |
115 | impl<U, <|>T> A<U, T> where U: u32 {} | 115 | impl<U, T> A<U, T> where U: u32 {} |
116 | "#, | 116 | "#, |
117 | ); | 117 | ); |
118 | } | 118 | } |
@@ -125,7 +125,7 @@ mod tests { | |||
125 | struct A<<|>T: Iterator<Item = u32>> {} | 125 | struct A<<|>T: Iterator<Item = u32>> {} |
126 | "#, | 126 | "#, |
127 | r#" | 127 | r#" |
128 | struct A<<|>T> where T: Iterator<Item = u32> {} | 128 | struct A<T> where T: Iterator<Item = u32> {} |
129 | "#, | 129 | "#, |
130 | ); | 130 | ); |
131 | } | 131 | } |
@@ -138,7 +138,7 @@ mod tests { | |||
138 | struct Pair<<|>T: u32>(T, T); | 138 | struct Pair<<|>T: u32>(T, T); |
139 | "#, | 139 | "#, |
140 | r#" | 140 | r#" |
141 | struct Pair<<|>T>(T, T) where T: u32; | 141 | struct Pair<T>(T, T) where T: u32; |
142 | "#, | 142 | "#, |
143 | ); | 143 | ); |
144 | } | 144 | } |
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs index c20ffe0b3..16002d2ac 100644 --- a/crates/ra_assists/src/handlers/raw_string.rs +++ b/crates/ra_assists/src/handlers/raw_string.rs | |||
@@ -164,7 +164,7 @@ mod test { | |||
164 | "#, | 164 | "#, |
165 | r##" | 165 | r##" |
166 | fn f() { | 166 | fn f() { |
167 | let s = <|>r#"random | 167 | let s = r#"random |
168 | string"#; | 168 | string"#; |
169 | } | 169 | } |
170 | "##, | 170 | "##, |
@@ -182,7 +182,7 @@ string"#; | |||
182 | "#, | 182 | "#, |
183 | r##" | 183 | r##" |
184 | fn f() { | 184 | fn f() { |
185 | format!(<|>r#"x = {}"#, 92) | 185 | format!(r#"x = {}"#, 92) |
186 | } | 186 | } |
187 | "##, | 187 | "##, |
188 | ) | 188 | ) |
@@ -199,7 +199,7 @@ string"#; | |||
199 | "###, | 199 | "###, |
200 | r####" | 200 | r####" |
201 | fn f() { | 201 | fn f() { |
202 | let s = <|>r#"#random## | 202 | let s = r#"#random## |
203 | string"#; | 203 | string"#; |
204 | } | 204 | } |
205 | "####, | 205 | "####, |
@@ -217,7 +217,7 @@ string"#; | |||
217 | "###, | 217 | "###, |
218 | r####" | 218 | r####" |
219 | fn f() { | 219 | fn f() { |
220 | let s = <|>r###"#random"## | 220 | let s = r###"#random"## |
221 | string"###; | 221 | string"###; |
222 | } | 222 | } |
223 | "####, | 223 | "####, |
@@ -235,7 +235,7 @@ string"###; | |||
235 | "#, | 235 | "#, |
236 | r##" | 236 | r##" |
237 | fn f() { | 237 | fn f() { |
238 | let s = <|>r#"random string"#; | 238 | let s = r#"random string"#; |
239 | } | 239 | } |
240 | "##, | 240 | "##, |
241 | ) | 241 | ) |
@@ -289,7 +289,7 @@ string"###; | |||
289 | "#, | 289 | "#, |
290 | r##" | 290 | r##" |
291 | fn f() { | 291 | fn f() { |
292 | let s = <|>r#"random string"#; | 292 | let s = r#"random string"#; |
293 | } | 293 | } |
294 | "##, | 294 | "##, |
295 | ) | 295 | ) |
@@ -306,7 +306,7 @@ string"###; | |||
306 | "##, | 306 | "##, |
307 | r###" | 307 | r###" |
308 | fn f() { | 308 | fn f() { |
309 | let s = <|>r##"random"string"##; | 309 | let s = r##"random"string"##; |
310 | } | 310 | } |
311 | "###, | 311 | "###, |
312 | ) | 312 | ) |
@@ -348,7 +348,7 @@ string"###; | |||
348 | "##, | 348 | "##, |
349 | r#" | 349 | r#" |
350 | fn f() { | 350 | fn f() { |
351 | let s = <|>r"random string"; | 351 | let s = r"random string"; |
352 | } | 352 | } |
353 | "#, | 353 | "#, |
354 | ) | 354 | ) |
@@ -365,7 +365,7 @@ string"###; | |||
365 | "##, | 365 | "##, |
366 | r#" | 366 | r#" |
367 | fn f() { | 367 | fn f() { |
368 | let s = <|>r"random\"str\"ing"; | 368 | let s = r"random\"str\"ing"; |
369 | } | 369 | } |
370 | "#, | 370 | "#, |
371 | ) | 371 | ) |
@@ -382,7 +382,7 @@ string"###; | |||
382 | "###, | 382 | "###, |
383 | r##" | 383 | r##" |
384 | fn f() { | 384 | fn f() { |
385 | let s = <|>r#"random string"#; | 385 | let s = r#"random string"#; |
386 | } | 386 | } |
387 | "##, | 387 | "##, |
388 | ) | 388 | ) |
@@ -436,7 +436,7 @@ string"###; | |||
436 | "##, | 436 | "##, |
437 | r#" | 437 | r#" |
438 | fn f() { | 438 | fn f() { |
439 | let s = <|>"random string"; | 439 | let s = "random string"; |
440 | } | 440 | } |
441 | "#, | 441 | "#, |
442 | ) | 442 | ) |
@@ -453,7 +453,7 @@ string"###; | |||
453 | "##, | 453 | "##, |
454 | r#" | 454 | r#" |
455 | fn f() { | 455 | fn f() { |
456 | let s = <|>"random\"str\"ing"; | 456 | let s = "random\"str\"ing"; |
457 | } | 457 | } |
458 | "#, | 458 | "#, |
459 | ) | 459 | ) |
@@ -470,7 +470,7 @@ string"###; | |||
470 | "###, | 470 | "###, |
471 | r##" | 471 | r##" |
472 | fn f() { | 472 | fn f() { |
473 | let s = <|>"random string"; | 473 | let s = "random string"; |
474 | } | 474 | } |
475 | "##, | 475 | "##, |
476 | ) | 476 | ) |
diff --git a/crates/ra_assists/src/handlers/reorder_fields.rs b/crates/ra_assists/src/handlers/reorder_fields.rs index 757f6406e..30229edc2 100644 --- a/crates/ra_assists/src/handlers/reorder_fields.rs +++ b/crates/ra_assists/src/handlers/reorder_fields.rs | |||
@@ -140,7 +140,7 @@ mod tests { | |||
140 | "#, | 140 | "#, |
141 | r#" | 141 | r#" |
142 | struct Foo {foo: i32, bar: i32}; | 142 | struct Foo {foo: i32, bar: i32}; |
143 | const test: Foo = <|>Foo {foo: 1, bar: 0} | 143 | const test: Foo = Foo {foo: 1, bar: 0} |
144 | "#, | 144 | "#, |
145 | ) | 145 | ) |
146 | } | 146 | } |
@@ -164,7 +164,7 @@ mod tests { | |||
164 | 164 | ||
165 | fn f(f: Foo) -> { | 165 | fn f(f: Foo) -> { |
166 | match f { | 166 | match f { |
167 | <|>Foo { ref mut bar, baz: 0, .. } => (), | 167 | Foo { ref mut bar, baz: 0, .. } => (), |
168 | _ => () | 168 | _ => () |
169 | } | 169 | } |
170 | } | 170 | } |
@@ -202,7 +202,7 @@ mod tests { | |||
202 | impl Foo { | 202 | impl Foo { |
203 | fn new() -> Foo { | 203 | fn new() -> Foo { |
204 | let foo = String::new(); | 204 | let foo = String::new(); |
205 | <|>Foo { | 205 | Foo { |
206 | foo, | 206 | foo, |
207 | bar: foo.clone(), | 207 | bar: foo.clone(), |
208 | extra: "Extra field", | 208 | extra: "Extra field", |
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs index 1a81d8a0e..0197a8cf0 100644 --- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs | |||
@@ -39,7 +39,7 @@ pub(crate) fn replace_qualified_name_with_use( | |||
39 | target, | 39 | target, |
40 | |builder| { | 40 | |builder| { |
41 | let path_to_import = hir_path.mod_path().clone(); | 41 | let path_to_import = hir_path.mod_path().clone(); |
42 | insert_use_statement(path.syntax(), &path_to_import, ctx, builder); | 42 | insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder()); |
43 | 43 | ||
44 | if let Some(last) = path.segment() { | 44 | if let Some(last) = path.segment() { |
45 | // Here we are assuming the assist will provide a correct use statement | 45 | // Here we are assuming the assist will provide a correct use statement |
@@ -89,7 +89,7 @@ std::fmt::Debug<|> | |||
89 | " | 89 | " |
90 | use std::fmt::Debug; | 90 | use std::fmt::Debug; |
91 | 91 | ||
92 | Debug<|> | 92 | Debug |
93 | ", | 93 | ", |
94 | ); | 94 | ); |
95 | } | 95 | } |
@@ -106,7 +106,7 @@ fn main() { | |||
106 | " | 106 | " |
107 | use std::fmt::Debug; | 107 | use std::fmt::Debug; |
108 | 108 | ||
109 | Debug<|> | 109 | Debug |
110 | 110 | ||
111 | fn main() { | 111 | fn main() { |
112 | } | 112 | } |
@@ -130,7 +130,7 @@ use std::fmt::Debug; | |||
130 | fn main() { | 130 | fn main() { |
131 | } | 131 | } |
132 | 132 | ||
133 | Debug<|> | 133 | Debug |
134 | ", | 134 | ", |
135 | ); | 135 | ); |
136 | } | 136 | } |
@@ -145,7 +145,7 @@ std::fmt<|>::Debug | |||
145 | " | 145 | " |
146 | use std::fmt; | 146 | use std::fmt; |
147 | 147 | ||
148 | fmt<|>::Debug | 148 | fmt::Debug |
149 | ", | 149 | ", |
150 | ); | 150 | ); |
151 | } | 151 | } |
@@ -164,7 +164,7 @@ impl std::fmt::Debug<|> for Foo { | |||
164 | use stdx; | 164 | use stdx; |
165 | use std::fmt::Debug; | 165 | use std::fmt::Debug; |
166 | 166 | ||
167 | impl Debug<|> for Foo { | 167 | impl Debug for Foo { |
168 | } | 168 | } |
169 | ", | 169 | ", |
170 | ); | 170 | ); |
@@ -181,7 +181,7 @@ impl std::fmt::Debug<|> for Foo { | |||
181 | " | 181 | " |
182 | use std::fmt::Debug; | 182 | use std::fmt::Debug; |
183 | 183 | ||
184 | impl Debug<|> for Foo { | 184 | impl Debug for Foo { |
185 | } | 185 | } |
186 | ", | 186 | ", |
187 | ); | 187 | ); |
@@ -198,7 +198,7 @@ impl Debug<|> for Foo { | |||
198 | " | 198 | " |
199 | use std::fmt::Debug; | 199 | use std::fmt::Debug; |
200 | 200 | ||
201 | impl Debug<|> for Foo { | 201 | impl Debug for Foo { |
202 | } | 202 | } |
203 | ", | 203 | ", |
204 | ); | 204 | ); |
@@ -217,7 +217,7 @@ impl std::io<|> for Foo { | |||
217 | " | 217 | " |
218 | use std::{io, fmt}; | 218 | use std::{io, fmt}; |
219 | 219 | ||
220 | impl io<|> for Foo { | 220 | impl io for Foo { |
221 | } | 221 | } |
222 | ", | 222 | ", |
223 | ); | 223 | ); |
@@ -236,7 +236,7 @@ impl std::fmt::Debug<|> for Foo { | |||
236 | " | 236 | " |
237 | use std::fmt::{self, Debug, }; | 237 | use std::fmt::{self, Debug, }; |
238 | 238 | ||
239 | impl Debug<|> for Foo { | 239 | impl Debug for Foo { |
240 | } | 240 | } |
241 | ", | 241 | ", |
242 | ); | 242 | ); |
@@ -255,7 +255,7 @@ impl std::fmt<|> for Foo { | |||
255 | " | 255 | " |
256 | use std::fmt::{self, Debug}; | 256 | use std::fmt::{self, Debug}; |
257 | 257 | ||
258 | impl fmt<|> for Foo { | 258 | impl fmt for Foo { |
259 | } | 259 | } |
260 | ", | 260 | ", |
261 | ); | 261 | ); |
@@ -274,7 +274,7 @@ impl std::fmt::nested<|> for Foo { | |||
274 | " | 274 | " |
275 | use std::fmt::{Debug, nested::{Display, self}}; | 275 | use std::fmt::{Debug, nested::{Display, self}}; |
276 | 276 | ||
277 | impl nested<|> for Foo { | 277 | impl nested for Foo { |
278 | } | 278 | } |
279 | ", | 279 | ", |
280 | ); | 280 | ); |
@@ -293,7 +293,7 @@ impl std::fmt::nested<|> for Foo { | |||
293 | " | 293 | " |
294 | use std::fmt::{Debug, nested::{self, Display}}; | 294 | use std::fmt::{Debug, nested::{self, Display}}; |
295 | 295 | ||
296 | impl nested<|> for Foo { | 296 | impl nested for Foo { |
297 | } | 297 | } |
298 | ", | 298 | ", |
299 | ); | 299 | ); |
@@ -312,7 +312,7 @@ impl std::fmt::nested::Debug<|> for Foo { | |||
312 | " | 312 | " |
313 | use std::fmt::{Debug, nested::{Display, Debug}}; | 313 | use std::fmt::{Debug, nested::{Display, Debug}}; |
314 | 314 | ||
315 | impl Debug<|> for Foo { | 315 | impl Debug for Foo { |
316 | } | 316 | } |
317 | ", | 317 | ", |
318 | ); | 318 | ); |
@@ -331,7 +331,7 @@ impl std::fmt::nested::Display<|> for Foo { | |||
331 | " | 331 | " |
332 | use std::fmt::{nested::Display, Debug}; | 332 | use std::fmt::{nested::Display, Debug}; |
333 | 333 | ||
334 | impl Display<|> for Foo { | 334 | impl Display for Foo { |
335 | } | 335 | } |
336 | ", | 336 | ", |
337 | ); | 337 | ); |
@@ -350,7 +350,7 @@ impl std::fmt::Display<|> for Foo { | |||
350 | " | 350 | " |
351 | use std::fmt::{Display, nested::Debug}; | 351 | use std::fmt::{Display, nested::Debug}; |
352 | 352 | ||
353 | impl Display<|> for Foo { | 353 | impl Display for Foo { |
354 | } | 354 | } |
355 | ", | 355 | ", |
356 | ); | 356 | ); |
@@ -374,7 +374,7 @@ use crate::{ | |||
374 | AssocItem, | 374 | AssocItem, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | fn foo() { lower<|>::trait_env() } | 377 | fn foo() { lower::trait_env() } |
378 | ", | 378 | ", |
379 | ); | 379 | ); |
380 | } | 380 | } |
@@ -392,7 +392,7 @@ impl foo::Debug<|> for Foo { | |||
392 | " | 392 | " |
393 | use std::fmt as foo; | 393 | use std::fmt as foo; |
394 | 394 | ||
395 | impl Debug<|> for Foo { | 395 | impl Debug for Foo { |
396 | } | 396 | } |
397 | ", | 397 | ", |
398 | ); | 398 | ); |
@@ -435,7 +435,7 @@ mod foo { | |||
435 | mod bar { | 435 | mod bar { |
436 | use std::fmt::Debug; | 436 | use std::fmt::Debug; |
437 | 437 | ||
438 | Debug<|> | 438 | Debug |
439 | } | 439 | } |
440 | } | 440 | } |
441 | ", | 441 | ", |
@@ -458,7 +458,7 @@ fn main() { | |||
458 | use std::fmt::Debug; | 458 | use std::fmt::Debug; |
459 | 459 | ||
460 | fn main() { | 460 | fn main() { |
461 | Debug<|> | 461 | Debug |
462 | } | 462 | } |
463 | ", | 463 | ", |
464 | ); | 464 | ); |
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs index e52ec557e..b76182d79 100644 --- a/crates/ra_assists/src/handlers/unwrap_block.rs +++ b/crates/ra_assists/src/handlers/unwrap_block.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | use crate::{AssistContext, AssistId, Assists}; | ||
2 | |||
3 | use ast::{ElseBranch, Expr, LoopBodyOwner}; | ||
4 | use ra_fmt::unwrap_trivial_block; | 1 | use ra_fmt::unwrap_trivial_block; |
5 | use ra_syntax::{ast, match_ast, AstNode, TextRange, T}; | 2 | use ra_syntax::{ |
3 | ast::{self, ElseBranch, Expr, LoopBodyOwner}, | ||
4 | match_ast, AstNode, TextRange, T, | ||
5 | }; | ||
6 | |||
7 | use crate::{AssistContext, AssistId, Assists}; | ||
6 | 8 | ||
7 | // Assist: unwrap_block | 9 | // Assist: unwrap_block |
8 | // | 10 | // |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 339f24100..464bc03dd 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -12,7 +12,6 @@ macro_rules! eprintln { | |||
12 | 12 | ||
13 | mod assist_config; | 13 | mod assist_config; |
14 | mod assist_context; | 14 | mod assist_context; |
15 | mod marks; | ||
16 | #[cfg(test)] | 15 | #[cfg(test)] |
17 | mod tests; | 16 | mod tests; |
18 | pub mod utils; | 17 | pub mod utils; |
@@ -117,6 +116,7 @@ mod handlers { | |||
117 | mod change_visibility; | 116 | mod change_visibility; |
118 | mod early_return; | 117 | mod early_return; |
119 | mod fill_match_arms; | 118 | mod fill_match_arms; |
119 | mod fix_visibility; | ||
120 | mod flip_binexpr; | 120 | mod flip_binexpr; |
121 | mod flip_comma; | 121 | mod flip_comma; |
122 | mod flip_trait_bound; | 122 | mod flip_trait_bound; |
@@ -155,6 +155,7 @@ mod handlers { | |||
155 | change_visibility::change_visibility, | 155 | change_visibility::change_visibility, |
156 | early_return::convert_to_guarded_return, | 156 | early_return::convert_to_guarded_return, |
157 | fill_match_arms::fill_match_arms, | 157 | fill_match_arms::fill_match_arms, |
158 | fix_visibility::fix_visibility, | ||
158 | flip_binexpr::flip_binexpr, | 159 | flip_binexpr::flip_binexpr, |
159 | flip_comma::flip_comma, | 160 | flip_comma::flip_comma, |
160 | flip_trait_bound::flip_trait_bound, | 161 | flip_trait_bound::flip_trait_bound, |
diff --git a/crates/ra_assists/src/marks.rs b/crates/ra_assists/src/marks.rs deleted file mode 100644 index d579e627f..000000000 --- a/crates/ra_assists/src/marks.rs +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | //! See test_utils/src/marks.rs | ||
2 | |||
3 | test_utils::marks![ | ||
4 | introduce_var_in_comment_is_not_applicable | ||
5 | test_introduce_var_expr_stmt | ||
6 | test_introduce_var_last_expr | ||
7 | not_applicable_outside_of_bind_pat | ||
8 | test_not_inline_mut_variable | ||
9 | test_not_applicable_if_variable_unused | ||
10 | change_visibility_field_false_positive | ||
11 | test_add_from_impl_already_exists | ||
12 | add_turbo_fish_one_fish_is_enough | ||
13 | add_turbo_fish_non_generic | ||
14 | ]; | ||
diff --git a/crates/ra_assists/src/tests.rs b/crates/ra_assists/src/tests.rs index 9ba3da786..373a7f7cc 100644 --- a/crates/ra_assists/src/tests.rs +++ b/crates/ra_assists/src/tests.rs | |||
@@ -105,18 +105,9 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult) { | |||
105 | change.edit.apply(&mut actual); | 105 | change.edit.apply(&mut actual); |
106 | 106 | ||
107 | if !source_change.is_snippet { | 107 | if !source_change.is_snippet { |
108 | match source_change.cursor_position { | 108 | if let Some(off) = source_change.cursor_position { |
109 | None => { | 109 | actual = add_cursor(&actual, off.offset) |
110 | if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { | 110 | } |
111 | let off = change | ||
112 | .edit | ||
113 | .apply_to_offset(before_cursor_pos) | ||
114 | .expect("cursor position is affected by the edit"); | ||
115 | actual = add_cursor(&actual, off) | ||
116 | } | ||
117 | } | ||
118 | Some(off) => actual = add_cursor(&actual, off.offset), | ||
119 | }; | ||
120 | } | 111 | } |
121 | assert_eq_text!(after, &actual); | 112 | assert_eq_text!(after, &actual); |
122 | } | 113 | } |
diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs index 3808aded1..3e6654c17 100644 --- a/crates/ra_assists/src/tests/generated.rs +++ b/crates/ra_assists/src/tests/generated.rs | |||
@@ -204,7 +204,7 @@ struct Ctx<T: Clone> { | |||
204 | } | 204 | } |
205 | 205 | ||
206 | impl<T: Clone> Ctx<T> { | 206 | impl<T: Clone> Ctx<T> { |
207 | fn new(data: T) -> Self { Self { data } } | 207 | fn $0new(data: T) -> Self { Self { data } } |
208 | } | 208 | } |
209 | 209 | ||
210 | "#####, | 210 | "#####, |
@@ -276,7 +276,7 @@ fn doctest_change_return_type_to_result() { | |||
276 | fn foo() -> i32<|> { 42i32 } | 276 | fn foo() -> i32<|> { 42i32 } |
277 | "#####, | 277 | "#####, |
278 | r#####" | 278 | r#####" |
279 | fn foo() -> Result<i32, > { Ok(42i32) } | 279 | fn foo() -> Result<i32, ${0:_}> { Ok(42i32) } |
280 | "#####, | 280 | "#####, |
281 | ) | 281 | ) |
282 | } | 282 | } |
@@ -336,7 +336,7 @@ enum Action { Move { distance: u32 }, Stop } | |||
336 | 336 | ||
337 | fn handle(action: Action) { | 337 | fn handle(action: Action) { |
338 | match action { | 338 | match action { |
339 | Action::Move { distance } => {} | 339 | $0Action::Move { distance } => {} |
340 | Action::Stop => {} | 340 | Action::Stop => {} |
341 | } | 341 | } |
342 | } | 342 | } |
@@ -345,6 +345,29 @@ fn handle(action: Action) { | |||
345 | } | 345 | } |
346 | 346 | ||
347 | #[test] | 347 | #[test] |
348 | fn doctest_fix_visibility() { | ||
349 | check_doc_test( | ||
350 | "fix_visibility", | ||
351 | r#####" | ||
352 | mod m { | ||
353 | fn frobnicate() {} | ||
354 | } | ||
355 | fn main() { | ||
356 | m::frobnicate<|>() {} | ||
357 | } | ||
358 | "#####, | ||
359 | r#####" | ||
360 | mod m { | ||
361 | $0pub(crate) fn frobnicate() {} | ||
362 | } | ||
363 | fn main() { | ||
364 | m::frobnicate() {} | ||
365 | } | ||
366 | "#####, | ||
367 | ) | ||
368 | } | ||
369 | |||
370 | #[test] | ||
348 | fn doctest_flip_binexpr() { | 371 | fn doctest_flip_binexpr() { |
349 | check_doc_test( | 372 | check_doc_test( |
350 | "flip_binexpr", | 373 | "flip_binexpr", |
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs index 9af27180b..0038a9764 100644 --- a/crates/ra_assists/src/utils.rs +++ b/crates/ra_assists/src/utils.rs | |||
@@ -3,7 +3,7 @@ pub(crate) mod insert_use; | |||
3 | 3 | ||
4 | use std::{iter, ops}; | 4 | use std::{iter, ops}; |
5 | 5 | ||
6 | use hir::{Adt, Crate, Semantics, Trait, Type}; | 6 | use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type}; |
7 | use ra_ide_db::RootDatabase; | 7 | use ra_ide_db::RootDatabase; |
8 | use ra_syntax::{ | 8 | use ra_syntax::{ |
9 | ast::{self, make, NameOwner}, | 9 | ast::{self, make, NameOwner}, |
@@ -200,13 +200,19 @@ impl FamousDefs<'_, '_> { | |||
200 | #[cfg(test)] | 200 | #[cfg(test)] |
201 | pub(crate) const FIXTURE: &'static str = r#" | 201 | pub(crate) const FIXTURE: &'static str = r#" |
202 | //- /libcore.rs crate:core | 202 | //- /libcore.rs crate:core |
203 | pub mod convert{ | 203 | pub mod convert { |
204 | pub trait From<T> { | 204 | pub trait From<T> { |
205 | fn from(T) -> Self; | 205 | fn from(T) -> Self; |
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | pub mod prelude { pub use crate::convert::From } | 209 | pub mod option { |
210 | pub enum Option<T> { None, Some(T)} | ||
211 | } | ||
212 | |||
213 | pub mod prelude { | ||
214 | pub use crate::{convert::From, option::Option::{self, *}}; | ||
215 | } | ||
210 | #[prelude_import] | 216 | #[prelude_import] |
211 | pub use prelude::*; | 217 | pub use prelude::*; |
212 | "#; | 218 | "#; |
@@ -215,7 +221,25 @@ pub use prelude::*; | |||
215 | self.find_trait("core:convert:From") | 221 | self.find_trait("core:convert:From") |
216 | } | 222 | } |
217 | 223 | ||
224 | pub(crate) fn core_option_Option(&self) -> Option<Enum> { | ||
225 | self.find_enum("core:option:Option") | ||
226 | } | ||
227 | |||
218 | fn find_trait(&self, path: &str) -> Option<Trait> { | 228 | fn find_trait(&self, path: &str) -> Option<Trait> { |
229 | match self.find_def(path)? { | ||
230 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), | ||
231 | _ => None, | ||
232 | } | ||
233 | } | ||
234 | |||
235 | fn find_enum(&self, path: &str) -> Option<Enum> { | ||
236 | match self.find_def(path)? { | ||
237 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it), | ||
238 | _ => None, | ||
239 | } | ||
240 | } | ||
241 | |||
242 | fn find_def(&self, path: &str) -> Option<ScopeDef> { | ||
219 | let db = self.0.db; | 243 | let db = self.0.db; |
220 | let mut path = path.split(':'); | 244 | let mut path = path.split(':'); |
221 | let trait_ = path.next_back()?; | 245 | let trait_ = path.next_back()?; |
@@ -240,9 +264,6 @@ pub use prelude::*; | |||
240 | } | 264 | } |
241 | let def = | 265 | let def = |
242 | module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1; | 266 | module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1; |
243 | match def { | 267 | Some(def) |
244 | hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it), | ||
245 | _ => None, | ||
246 | } | ||
247 | } | 268 | } |
248 | } | 269 | } |
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs index 1214e3cd4..0ee43482f 100644 --- a/crates/ra_assists/src/utils/insert_use.rs +++ b/crates/ra_assists/src/utils/insert_use.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | }; | 11 | }; |
12 | use ra_text_edit::TextEditBuilder; | 12 | use ra_text_edit::TextEditBuilder; |
13 | 13 | ||
14 | use crate::assist_context::{AssistBuilder, AssistContext}; | 14 | use crate::assist_context::AssistContext; |
15 | 15 | ||
16 | /// Creates and inserts a use statement for the given path to import. | 16 | /// Creates and inserts a use statement for the given path to import. |
17 | /// The use statement is inserted in the scope most appropriate to the | 17 | /// The use statement is inserted in the scope most appropriate to the |
@@ -21,7 +21,7 @@ pub(crate) fn insert_use_statement( | |||
21 | position: &SyntaxNode, | 21 | position: &SyntaxNode, |
22 | path_to_import: &ModPath, | 22 | path_to_import: &ModPath, |
23 | ctx: &AssistContext, | 23 | ctx: &AssistContext, |
24 | builder: &mut AssistBuilder, | 24 | builder: &mut TextEditBuilder, |
25 | ) { | 25 | ) { |
26 | let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); | 26 | let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); |
27 | let container = ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { | 27 | let container = ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { |
@@ -33,7 +33,7 @@ pub(crate) fn insert_use_statement( | |||
33 | 33 | ||
34 | if let Some(container) = container { | 34 | if let Some(container) = container { |
35 | let action = best_action_for_target(container, position.clone(), &target); | 35 | let action = best_action_for_target(container, position.clone(), &target); |
36 | make_assist(&action, &target, builder.text_edit_builder()); | 36 | make_assist(&action, &target, builder); |
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index c69e0efea..e08d62dd6 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -15,7 +15,7 @@ use ra_syntax::{ | |||
15 | }, | 15 | }, |
16 | AstNode, AstPtr, | 16 | AstNode, AstPtr, |
17 | }; | 17 | }; |
18 | use test_utils::tested_by; | 18 | use test_utils::mark; |
19 | 19 | ||
20 | use crate::{ | 20 | use crate::{ |
21 | adt::StructKind, | 21 | adt::StructKind, |
@@ -226,7 +226,7 @@ impl ExprCollector<'_> { | |||
226 | None => self.collect_expr_opt(condition.expr()), | 226 | None => self.collect_expr_opt(condition.expr()), |
227 | // if let -- desugar to match | 227 | // if let -- desugar to match |
228 | Some(pat) => { | 228 | Some(pat) => { |
229 | tested_by!(infer_resolve_while_let); | 229 | mark::hit!(infer_resolve_while_let); |
230 | let pat = self.collect_pat(pat); | 230 | let pat = self.collect_pat(pat); |
231 | let match_expr = self.collect_expr_opt(condition.expr()); | 231 | let match_expr = self.collect_expr_opt(condition.expr()); |
232 | let placeholder_pat = self.missing_pat(); | 232 | let placeholder_pat = self.missing_pat(); |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 86f953c80..09e92b74e 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -174,7 +174,7 @@ mod tests { | |||
174 | use hir_expand::{name::AsName, InFile}; | 174 | use hir_expand::{name::AsName, InFile}; |
175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; | 175 | use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; |
176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 176 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
177 | use test_utils::{assert_eq_text, covers, extract_offset}; | 177 | use test_utils::{assert_eq_text, extract_offset, mark}; |
178 | 178 | ||
179 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; | 179 | use crate::{db::DefDatabase, test_db::TestDB, FunctionId, ModuleDefId}; |
180 | 180 | ||
@@ -388,7 +388,7 @@ mod tests { | |||
388 | 388 | ||
389 | #[test] | 389 | #[test] |
390 | fn while_let_desugaring() { | 390 | fn while_let_desugaring() { |
391 | covers!(infer_resolve_while_let); | 391 | mark::check!(infer_resolve_while_let); |
392 | do_check_local_name( | 392 | do_check_local_name( |
393 | r#" | 393 | r#" |
394 | fn test() { | 394 | fn test() { |
diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs index 2eb12ec8f..68d3cde08 100644 --- a/crates/ra_hir_def/src/find_path.rs +++ b/crates/ra_hir_def/src/find_path.rs | |||
@@ -4,7 +4,7 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use hir_expand::name::{known, AsName, Name}; | 5 | use hir_expand::name::{known, AsName, Name}; |
6 | use ra_prof::profile; | 6 | use ra_prof::profile; |
7 | use test_utils::tested_by; | 7 | use test_utils::mark; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | db::DefDatabase, | 10 | db::DefDatabase, |
@@ -164,17 +164,19 @@ fn find_path_inner( | |||
164 | 164 | ||
165 | fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath { | 165 | fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath { |
166 | if old_path.starts_with_std() && new_path.can_start_with_std() { | 166 | if old_path.starts_with_std() && new_path.can_start_with_std() { |
167 | tested_by!(prefer_std_paths); | ||
168 | if prefer_no_std { | 167 | if prefer_no_std { |
168 | mark::hit!(prefer_no_std_paths); | ||
169 | new_path | 169 | new_path |
170 | } else { | 170 | } else { |
171 | mark::hit!(prefer_std_paths); | ||
171 | old_path | 172 | old_path |
172 | } | 173 | } |
173 | } else if new_path.starts_with_std() && old_path.can_start_with_std() { | 174 | } else if new_path.starts_with_std() && old_path.can_start_with_std() { |
174 | tested_by!(prefer_std_paths); | ||
175 | if prefer_no_std { | 175 | if prefer_no_std { |
176 | mark::hit!(prefer_no_std_paths); | ||
176 | old_path | 177 | old_path |
177 | } else { | 178 | } else { |
179 | mark::hit!(prefer_std_paths); | ||
178 | new_path | 180 | new_path |
179 | } | 181 | } |
180 | } else if new_path.len() < old_path.len() { | 182 | } else if new_path.len() < old_path.len() { |
@@ -251,12 +253,14 @@ pub(crate) fn importable_locations_of_query( | |||
251 | 253 | ||
252 | #[cfg(test)] | 254 | #[cfg(test)] |
253 | mod tests { | 255 | mod tests { |
254 | use super::*; | ||
255 | use crate::test_db::TestDB; | ||
256 | use hir_expand::hygiene::Hygiene; | 256 | use hir_expand::hygiene::Hygiene; |
257 | use ra_db::fixture::WithFixture; | 257 | use ra_db::fixture::WithFixture; |
258 | use ra_syntax::ast::AstNode; | 258 | use ra_syntax::ast::AstNode; |
259 | use test_utils::covers; | 259 | use test_utils::mark; |
260 | |||
261 | use crate::test_db::TestDB; | ||
262 | |||
263 | use super::*; | ||
260 | 264 | ||
261 | /// `code` needs to contain a cursor marker; checks that `find_path` for the | 265 | /// `code` needs to contain a cursor marker; checks that `find_path` for the |
262 | /// item the `path` refers to returns that same path when called from the | 266 | /// item the `path` refers to returns that same path when called from the |
@@ -511,7 +515,7 @@ mod tests { | |||
511 | 515 | ||
512 | #[test] | 516 | #[test] |
513 | fn prefer_std_paths_over_alloc() { | 517 | fn prefer_std_paths_over_alloc() { |
514 | covers!(prefer_std_paths); | 518 | mark::check!(prefer_std_paths); |
515 | let code = r#" | 519 | let code = r#" |
516 | //- /main.rs crate:main deps:alloc,std | 520 | //- /main.rs crate:main deps:alloc,std |
517 | <|> | 521 | <|> |
@@ -530,51 +534,50 @@ mod tests { | |||
530 | } | 534 | } |
531 | 535 | ||
532 | #[test] | 536 | #[test] |
533 | fn prefer_alloc_paths_over_std() { | 537 | fn prefer_core_paths_over_std() { |
534 | covers!(prefer_std_paths); | 538 | mark::check!(prefer_no_std_paths); |
535 | let code = r#" | 539 | let code = r#" |
536 | //- /main.rs crate:main deps:alloc,std | 540 | //- /main.rs crate:main deps:core,std |
537 | #![no_std] | 541 | #![no_std] |
538 | 542 | ||
539 | <|> | 543 | <|> |
540 | 544 | ||
541 | //- /std.rs crate:std deps:alloc | 545 | //- /std.rs crate:std deps:core |
542 | 546 | ||
543 | pub mod sync { | 547 | pub mod fmt { |
544 | pub use alloc::sync::Arc; | 548 | pub use core::fmt::Error; |
545 | } | 549 | } |
546 | 550 | ||
547 | //- /zzz.rs crate:alloc | 551 | //- /zzz.rs crate:core |
548 | 552 | ||
549 | pub mod sync { | 553 | pub mod fmt { |
550 | pub struct Arc; | 554 | pub struct Error; |
551 | } | 555 | } |
552 | "#; | 556 | "#; |
553 | check_found_path(code, "alloc::sync::Arc"); | 557 | check_found_path(code, "core::fmt::Error"); |
554 | } | 558 | } |
555 | 559 | ||
556 | #[test] | 560 | #[test] |
557 | fn prefer_core_paths_over_std() { | 561 | fn prefer_alloc_paths_over_std() { |
558 | covers!(prefer_std_paths); | ||
559 | let code = r#" | 562 | let code = r#" |
560 | //- /main.rs crate:main deps:core,std | 563 | //- /main.rs crate:main deps:alloc,std |
561 | #![no_std] | 564 | #![no_std] |
562 | 565 | ||
563 | <|> | 566 | <|> |
564 | 567 | ||
565 | //- /std.rs crate:std deps:core | 568 | //- /std.rs crate:std deps:alloc |
566 | 569 | ||
567 | pub mod fmt { | 570 | pub mod sync { |
568 | pub use core::fmt::Error; | 571 | pub use alloc::sync::Arc; |
569 | } | 572 | } |
570 | 573 | ||
571 | //- /zzz.rs crate:core | 574 | //- /zzz.rs crate:alloc |
572 | 575 | ||
573 | pub mod fmt { | 576 | pub mod sync { |
574 | pub struct Error; | 577 | pub struct Arc; |
575 | } | 578 | } |
576 | "#; | 579 | "#; |
577 | check_found_path(code, "core::fmt::Error"); | 580 | check_found_path(code, "alloc::sync::Arc"); |
578 | } | 581 | } |
579 | 582 | ||
580 | #[test] | 583 | #[test] |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 518772e8a..5325a2760 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -46,8 +46,6 @@ pub mod find_path; | |||
46 | 46 | ||
47 | #[cfg(test)] | 47 | #[cfg(test)] |
48 | mod test_db; | 48 | mod test_db; |
49 | #[cfg(test)] | ||
50 | mod marks; | ||
51 | 49 | ||
52 | use std::hash::Hash; | 50 | use std::hash::Hash; |
53 | 51 | ||
diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs deleted file mode 100644 index daa49d5f1..000000000 --- a/crates/ra_hir_def/src/marks.rs +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | //! See test_utils/src/marks.rs | ||
2 | |||
3 | test_utils::marks!( | ||
4 | bogus_paths | ||
5 | name_res_works_for_broken_modules | ||
6 | can_import_enum_variant | ||
7 | glob_enum | ||
8 | glob_enum_group | ||
9 | glob_across_crates | ||
10 | std_prelude | ||
11 | macro_rules_from_other_crates_are_visible_with_macro_use | ||
12 | prelude_is_macro_use | ||
13 | macro_dollar_crate_self | ||
14 | macro_dollar_crate_other | ||
15 | infer_resolve_while_let | ||
16 | prefer_std_paths | ||
17 | ); | ||
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index db994122a..353a31ad4 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -14,7 +14,7 @@ use ra_cfg::CfgOptions; | |||
14 | use ra_db::{CrateId, FileId, ProcMacroId}; | 14 | use ra_db::{CrateId, FileId, ProcMacroId}; |
15 | use ra_syntax::ast; | 15 | use ra_syntax::ast; |
16 | use rustc_hash::FxHashMap; | 16 | use rustc_hash::FxHashMap; |
17 | use test_utils::tested_by; | 17 | use test_utils::mark; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | attr::Attrs, | 20 | attr::Attrs, |
@@ -302,7 +302,7 @@ impl DefCollector<'_> { | |||
302 | ); | 302 | ); |
303 | 303 | ||
304 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { | 304 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { |
305 | tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); | 305 | mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); |
306 | self.import_all_macros_exported(current_module_id, m.krate); | 306 | self.import_all_macros_exported(current_module_id, m.krate); |
307 | } | 307 | } |
308 | } | 308 | } |
@@ -412,10 +412,10 @@ impl DefCollector<'_> { | |||
412 | match def.take_types() { | 412 | match def.take_types() { |
413 | Some(ModuleDefId::ModuleId(m)) => { | 413 | Some(ModuleDefId::ModuleId(m)) => { |
414 | if import.is_prelude { | 414 | if import.is_prelude { |
415 | tested_by!(std_prelude); | 415 | mark::hit!(std_prelude); |
416 | self.def_map.prelude = Some(m); | 416 | self.def_map.prelude = Some(m); |
417 | } else if m.krate != self.def_map.krate { | 417 | } else if m.krate != self.def_map.krate { |
418 | tested_by!(glob_across_crates); | 418 | mark::hit!(glob_across_crates); |
419 | // glob import from other crate => we can just import everything once | 419 | // glob import from other crate => we can just import everything once |
420 | let item_map = self.db.crate_def_map(m.krate); | 420 | let item_map = self.db.crate_def_map(m.krate); |
421 | let scope = &item_map[m.local_id].scope; | 421 | let scope = &item_map[m.local_id].scope; |
@@ -461,7 +461,7 @@ impl DefCollector<'_> { | |||
461 | } | 461 | } |
462 | } | 462 | } |
463 | Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => { | 463 | Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => { |
464 | tested_by!(glob_enum); | 464 | mark::hit!(glob_enum); |
465 | // glob import from enum => just import all the variants | 465 | // glob import from enum => just import all the variants |
466 | 466 | ||
467 | // XXX: urgh, so this works by accident! Here, we look at | 467 | // XXX: urgh, so this works by accident! Here, we look at |
@@ -510,7 +510,7 @@ impl DefCollector<'_> { | |||
510 | 510 | ||
511 | self.update(module_id, &[(name, def)], vis); | 511 | self.update(module_id, &[(name, def)], vis); |
512 | } | 512 | } |
513 | None => tested_by!(bogus_paths), | 513 | None => mark::hit!(bogus_paths), |
514 | } | 514 | } |
515 | } | 515 | } |
516 | } | 516 | } |
@@ -683,7 +683,7 @@ impl ModCollector<'_, '_> { | |||
683 | // Prelude module is always considered to be `#[macro_use]`. | 683 | // Prelude module is always considered to be `#[macro_use]`. |
684 | if let Some(prelude_module) = self.def_collector.def_map.prelude { | 684 | if let Some(prelude_module) = self.def_collector.def_map.prelude { |
685 | if prelude_module.krate != self.def_collector.def_map.krate { | 685 | if prelude_module.krate != self.def_collector.def_map.krate { |
686 | tested_by!(prelude_is_macro_use); | 686 | mark::hit!(prelude_is_macro_use); |
687 | self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate); | 687 | self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate); |
688 | } | 688 | } |
689 | } | 689 | } |
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 35a0a0c98..19692e70c 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs | |||
@@ -14,7 +14,7 @@ use std::iter::successors; | |||
14 | 14 | ||
15 | use hir_expand::name::Name; | 15 | use hir_expand::name::Name; |
16 | use ra_db::Edition; | 16 | use ra_db::Edition; |
17 | use test_utils::tested_by; | 17 | use test_utils::mark; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | db::DefDatabase, | 20 | db::DefDatabase, |
@@ -108,7 +108,7 @@ impl CrateDefMap { | |||
108 | let mut curr_per_ns: PerNs = match path.kind { | 108 | let mut curr_per_ns: PerNs = match path.kind { |
109 | PathKind::DollarCrate(krate) => { | 109 | PathKind::DollarCrate(krate) => { |
110 | if krate == self.krate { | 110 | if krate == self.krate { |
111 | tested_by!(macro_dollar_crate_self); | 111 | mark::hit!(macro_dollar_crate_self); |
112 | PerNs::types( | 112 | PerNs::types( |
113 | ModuleId { krate: self.krate, local_id: self.root }.into(), | 113 | ModuleId { krate: self.krate, local_id: self.root }.into(), |
114 | Visibility::Public, | 114 | Visibility::Public, |
@@ -116,7 +116,7 @@ impl CrateDefMap { | |||
116 | } else { | 116 | } else { |
117 | let def_map = db.crate_def_map(krate); | 117 | let def_map = db.crate_def_map(krate); |
118 | let module = ModuleId { krate, local_id: def_map.root }; | 118 | let module = ModuleId { krate, local_id: def_map.root }; |
119 | tested_by!(macro_dollar_crate_other); | 119 | mark::hit!(macro_dollar_crate_other); |
120 | PerNs::types(module.into(), Visibility::Public) | 120 | PerNs::types(module.into(), Visibility::Public) |
121 | } | 121 | } |
122 | } | 122 | } |
@@ -221,7 +221,7 @@ impl CrateDefMap { | |||
221 | } | 221 | } |
222 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { | 222 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { |
223 | // enum variant | 223 | // enum variant |
224 | tested_by!(can_import_enum_variant); | 224 | mark::hit!(can_import_enum_variant); |
225 | let enum_data = db.enum_data(e); | 225 | let enum_data = db.enum_data(e); |
226 | match enum_data.variant(&segment) { | 226 | match enum_data.variant(&segment) { |
227 | Some(local_id) => { | 227 | Some(local_id) => { |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index f2716a295..4e628b14d 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -18,7 +18,7 @@ use ra_syntax::{ | |||
18 | ast::{self, AttrsOwner, NameOwner, VisibilityOwner}, | 18 | ast::{self, AttrsOwner, NameOwner, VisibilityOwner}, |
19 | AstNode, | 19 | AstNode, |
20 | }; | 20 | }; |
21 | use test_utils::tested_by; | 21 | use test_utils::mark; |
22 | 22 | ||
23 | use crate::{ | 23 | use crate::{ |
24 | attr::Attrs, | 24 | attr::Attrs, |
@@ -346,7 +346,7 @@ impl RawItemsCollector { | |||
346 | self.push_item(current_module, attrs, RawItemKind::Module(item)); | 346 | self.push_item(current_module, attrs, RawItemKind::Module(item)); |
347 | return; | 347 | return; |
348 | } | 348 | } |
349 | tested_by!(name_res_works_for_broken_modules); | 349 | mark::hit!(name_res_works_for_broken_modules); |
350 | } | 350 | } |
351 | 351 | ||
352 | fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) { | 352 | fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) { |
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 1b66c1aac..05cd0297d 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs | |||
@@ -8,7 +8,7 @@ use std::sync::Arc; | |||
8 | 8 | ||
9 | use insta::assert_snapshot; | 9 | use insta::assert_snapshot; |
10 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 10 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
11 | use test_utils::covers; | 11 | use test_utils::mark; |
12 | 12 | ||
13 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; | 13 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; |
14 | 14 | ||
@@ -132,7 +132,7 @@ fn crate_def_map_fn_mod_same_name() { | |||
132 | 132 | ||
133 | #[test] | 133 | #[test] |
134 | fn bogus_paths() { | 134 | fn bogus_paths() { |
135 | covers!(bogus_paths); | 135 | mark::check!(bogus_paths); |
136 | let map = def_map( | 136 | let map = def_map( |
137 | " | 137 | " |
138 | //- /lib.rs | 138 | //- /lib.rs |
@@ -247,7 +247,7 @@ fn re_exports() { | |||
247 | 247 | ||
248 | #[test] | 248 | #[test] |
249 | fn std_prelude() { | 249 | fn std_prelude() { |
250 | covers!(std_prelude); | 250 | mark::check!(std_prelude); |
251 | let map = def_map( | 251 | let map = def_map( |
252 | " | 252 | " |
253 | //- /main.rs crate:main deps:test_crate | 253 | //- /main.rs crate:main deps:test_crate |
@@ -271,7 +271,7 @@ fn std_prelude() { | |||
271 | 271 | ||
272 | #[test] | 272 | #[test] |
273 | fn can_import_enum_variant() { | 273 | fn can_import_enum_variant() { |
274 | covers!(can_import_enum_variant); | 274 | mark::check!(can_import_enum_variant); |
275 | let map = def_map( | 275 | let map = def_map( |
276 | " | 276 | " |
277 | //- /lib.rs | 277 | //- /lib.rs |
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs index ee8df3a26..2b12c0daa 100644 --- a/crates/ra_hir_def/src/nameres/tests/globs.rs +++ b/crates/ra_hir_def/src/nameres/tests/globs.rs | |||
@@ -152,7 +152,7 @@ fn glob_privacy_2() { | |||
152 | 152 | ||
153 | #[test] | 153 | #[test] |
154 | fn glob_across_crates() { | 154 | fn glob_across_crates() { |
155 | covers!(glob_across_crates); | 155 | mark::check!(glob_across_crates); |
156 | let map = def_map( | 156 | let map = def_map( |
157 | r" | 157 | r" |
158 | //- /main.rs crate:main deps:test_crate | 158 | //- /main.rs crate:main deps:test_crate |
@@ -171,7 +171,6 @@ fn glob_across_crates() { | |||
171 | 171 | ||
172 | #[test] | 172 | #[test] |
173 | fn glob_privacy_across_crates() { | 173 | fn glob_privacy_across_crates() { |
174 | covers!(glob_across_crates); | ||
175 | let map = def_map( | 174 | let map = def_map( |
176 | r" | 175 | r" |
177 | //- /main.rs crate:main deps:test_crate | 176 | //- /main.rs crate:main deps:test_crate |
@@ -191,7 +190,7 @@ fn glob_privacy_across_crates() { | |||
191 | 190 | ||
192 | #[test] | 191 | #[test] |
193 | fn glob_enum() { | 192 | fn glob_enum() { |
194 | covers!(glob_enum); | 193 | mark::check!(glob_enum); |
195 | let map = def_map( | 194 | let map = def_map( |
196 | " | 195 | " |
197 | //- /lib.rs | 196 | //- /lib.rs |
@@ -212,7 +211,7 @@ fn glob_enum() { | |||
212 | 211 | ||
213 | #[test] | 212 | #[test] |
214 | fn glob_enum_group() { | 213 | fn glob_enum_group() { |
215 | covers!(glob_enum_group); | 214 | mark::check!(glob_enum_group); |
216 | let map = def_map( | 215 | let map = def_map( |
217 | r" | 216 | r" |
218 | //- /lib.rs | 217 | //- /lib.rs |
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index 40289e3ca..84480d9f6 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs | |||
@@ -212,7 +212,7 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() { | |||
212 | 212 | ||
213 | #[test] | 213 | #[test] |
214 | fn macro_rules_from_other_crates_are_visible_with_macro_use() { | 214 | fn macro_rules_from_other_crates_are_visible_with_macro_use() { |
215 | covers!(macro_rules_from_other_crates_are_visible_with_macro_use); | 215 | mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use); |
216 | let map = def_map( | 216 | let map = def_map( |
217 | " | 217 | " |
218 | //- /main.rs crate:main deps:foo | 218 | //- /main.rs crate:main deps:foo |
@@ -262,7 +262,7 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() { | |||
262 | 262 | ||
263 | #[test] | 263 | #[test] |
264 | fn prelude_is_macro_use() { | 264 | fn prelude_is_macro_use() { |
265 | covers!(prelude_is_macro_use); | 265 | mark::check!(prelude_is_macro_use); |
266 | let map = def_map( | 266 | let map = def_map( |
267 | " | 267 | " |
268 | //- /main.rs crate:main deps:foo | 268 | //- /main.rs crate:main deps:foo |
@@ -544,8 +544,7 @@ fn path_qualified_macros() { | |||
544 | 544 | ||
545 | #[test] | 545 | #[test] |
546 | fn macro_dollar_crate_is_correct_in_item() { | 546 | fn macro_dollar_crate_is_correct_in_item() { |
547 | covers!(macro_dollar_crate_self); | 547 | mark::check!(macro_dollar_crate_self); |
548 | covers!(macro_dollar_crate_other); | ||
549 | let map = def_map( | 548 | let map = def_map( |
550 | " | 549 | " |
551 | //- /main.rs crate:main deps:foo | 550 | //- /main.rs crate:main deps:foo |
@@ -603,7 +602,7 @@ fn macro_dollar_crate_is_correct_in_item() { | |||
603 | 602 | ||
604 | #[test] | 603 | #[test] |
605 | fn macro_dollar_crate_is_correct_in_indirect_deps() { | 604 | fn macro_dollar_crate_is_correct_in_indirect_deps() { |
606 | covers!(macro_dollar_crate_other); | 605 | mark::check!(macro_dollar_crate_other); |
607 | // From std | 606 | // From std |
608 | let map = def_map( | 607 | let map = def_map( |
609 | r#" | 608 | r#" |
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index 37fcdfb8c..b43b294ca 100644 --- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs | |||
@@ -2,7 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | #[test] | 3 | #[test] |
4 | fn name_res_works_for_broken_modules() { | 4 | fn name_res_works_for_broken_modules() { |
5 | covers!(name_res_works_for_broken_modules); | 5 | mark::check!(name_res_works_for_broken_modules); |
6 | let map = def_map( | 6 | let map = def_map( |
7 | r" | 7 | r" |
8 | //- /lib.rs | 8 | //- /lib.rs |
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index 5b6854b0f..7cc655487 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs | |||
@@ -6,7 +6,7 @@ use std::iter; | |||
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_expand::{hygiene::Hygiene, name::AsName}; | 7 | use hir_expand::{hygiene::Hygiene, name::AsName}; |
8 | use ra_syntax::ast::{self, NameOwner}; | 8 | use ra_syntax::ast::{self, NameOwner}; |
9 | use test_utils::tested_by; | 9 | use test_utils::mark; |
10 | 10 | ||
11 | use crate::path::{ImportAlias, ModPath, PathKind}; | 11 | use crate::path::{ImportAlias, ModPath, PathKind}; |
12 | 12 | ||
@@ -54,7 +54,7 @@ pub(crate) fn lower_use_tree( | |||
54 | // FIXME: report errors somewhere | 54 | // FIXME: report errors somewhere |
55 | // We get here if we do | 55 | // We get here if we do |
56 | } else if is_glob { | 56 | } else if is_glob { |
57 | tested_by!(glob_enum_group); | 57 | mark::hit!(glob_enum_group); |
58 | if let Some(prefix) = prefix { | 58 | if let Some(prefix) = prefix { |
59 | cb(prefix, &tree, is_glob, None) | 59 | cb(prefix, &tree, is_glob, None) |
60 | } | 60 | } |
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs index 149f65042..3e6e1e333 100644 --- a/crates/ra_hir_ty/src/_match.rs +++ b/crates/ra_hir_ty/src/_match.rs | |||
@@ -1946,6 +1946,23 @@ mod tests { | |||
1946 | 1946 | ||
1947 | check_no_diagnostic(content); | 1947 | check_no_diagnostic(content); |
1948 | } | 1948 | } |
1949 | |||
1950 | #[test] | ||
1951 | fn expr_diverges_missing_arm() { | ||
1952 | let content = r" | ||
1953 | enum Either { | ||
1954 | A, | ||
1955 | B, | ||
1956 | } | ||
1957 | fn test_fn() { | ||
1958 | match loop {} { | ||
1959 | Either::A => (), | ||
1960 | } | ||
1961 | } | ||
1962 | "; | ||
1963 | |||
1964 | check_no_diagnostic(content); | ||
1965 | } | ||
1949 | } | 1966 | } |
1950 | 1967 | ||
1951 | #[cfg(test)] | 1968 | #[cfg(test)] |
@@ -1998,26 +2015,6 @@ mod false_negatives { | |||
1998 | } | 2015 | } |
1999 | 2016 | ||
2000 | #[test] | 2017 | #[test] |
2001 | fn expr_diverges_missing_arm() { | ||
2002 | let content = r" | ||
2003 | enum Either { | ||
2004 | A, | ||
2005 | B, | ||
2006 | } | ||
2007 | fn test_fn() { | ||
2008 | match loop {} { | ||
2009 | Either::A => (), | ||
2010 | } | ||
2011 | } | ||
2012 | "; | ||
2013 | |||
2014 | // This is a false negative. | ||
2015 | // Even though the match expression diverges, rustc fails | ||
2016 | // to compile here since `Either::B` is missing. | ||
2017 | check_no_diagnostic(content); | ||
2018 | } | ||
2019 | |||
2020 | #[test] | ||
2021 | fn expr_loop_missing_arm() { | 2018 | fn expr_loop_missing_arm() { |
2022 | let content = r" | 2019 | let content = r" |
2023 | enum Either { | 2020 | enum Either { |
@@ -2035,7 +2032,7 @@ mod false_negatives { | |||
2035 | // We currently infer the type of `loop { break Foo::A }` to `!`, which | 2032 | // We currently infer the type of `loop { break Foo::A }` to `!`, which |
2036 | // causes us to skip the diagnostic since `Either::A` doesn't type check | 2033 | // causes us to skip the diagnostic since `Either::A` doesn't type check |
2037 | // with `!`. | 2034 | // with `!`. |
2038 | check_no_diagnostic(content); | 2035 | check_diagnostic(content); |
2039 | } | 2036 | } |
2040 | 2037 | ||
2041 | #[test] | 2038 | #[test] |
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 2876cb141..957d6e0b5 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -218,6 +218,7 @@ struct InferenceContext<'a> { | |||
218 | #[derive(Clone, Debug)] | 218 | #[derive(Clone, Debug)] |
219 | struct BreakableContext { | 219 | struct BreakableContext { |
220 | pub may_break: bool, | 220 | pub may_break: bool, |
221 | pub break_ty: Ty, | ||
221 | } | 222 | } |
222 | 223 | ||
223 | impl<'a> InferenceContext<'a> { | 224 | impl<'a> InferenceContext<'a> { |
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 173ec59ed..2ee9adb16 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; | 7 | use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; |
8 | use test_utils::tested_by; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; | 10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; |
11 | 11 | ||
@@ -34,7 +34,7 @@ impl<'a> InferenceContext<'a> { | |||
34 | ty1.clone() | 34 | ty1.clone() |
35 | } else { | 35 | } else { |
36 | if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { | 36 | if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { |
37 | tested_by!(coerce_fn_reification); | 37 | mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 38 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 39 | // pointers to have a chance at getting a match. See |
40 | // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 | 40 | // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 |
@@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> { | |||
44 | let ptr_ty2 = Ty::fn_ptr(sig2); | 44 | let ptr_ty2 = Ty::fn_ptr(sig2); |
45 | self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) | 45 | self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) |
46 | } else { | 46 | } else { |
47 | tested_by!(coerce_merge_fail_fallback); | 47 | mark::hit!(coerce_merge_fail_fallback); |
48 | // For incompatible types, we use the latter one as result | 48 | // For incompatible types, we use the latter one as result |
49 | // to be better recovery for `if` without `else`. | 49 | // to be better recovery for `if` without `else`. |
50 | ty2.clone() | 50 | ty2.clone() |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 0b67d216a..b28724f0e 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -93,22 +93,25 @@ impl<'a> InferenceContext<'a> { | |||
93 | Ty::Unknown | 93 | Ty::Unknown |
94 | } | 94 | } |
95 | Expr::Loop { body } => { | 95 | Expr::Loop { body } => { |
96 | self.breakables.push(BreakableContext { may_break: false }); | 96 | self.breakables.push(BreakableContext { |
97 | may_break: false, | ||
98 | break_ty: self.table.new_type_var(), | ||
99 | }); | ||
97 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 100 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
98 | 101 | ||
99 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | 102 | let ctxt = self.breakables.pop().expect("breakable stack broken"); |
100 | if ctxt.may_break { | 103 | if ctxt.may_break { |
101 | self.diverges = Diverges::Maybe; | 104 | self.diverges = Diverges::Maybe; |
102 | } | 105 | } |
103 | // FIXME handle break with value | 106 | |
104 | if ctxt.may_break { | 107 | if ctxt.may_break { |
105 | Ty::unit() | 108 | ctxt.break_ty |
106 | } else { | 109 | } else { |
107 | Ty::simple(TypeCtor::Never) | 110 | Ty::simple(TypeCtor::Never) |
108 | } | 111 | } |
109 | } | 112 | } |
110 | Expr::While { condition, body } => { | 113 | Expr::While { condition, body } => { |
111 | self.breakables.push(BreakableContext { may_break: false }); | 114 | self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); |
112 | // while let is desugared to a match loop, so this is always simple while | 115 | // while let is desugared to a match loop, so this is always simple while |
113 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 116 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); |
114 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 117 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
@@ -120,7 +123,7 @@ impl<'a> InferenceContext<'a> { | |||
120 | Expr::For { iterable, body, pat } => { | 123 | Expr::For { iterable, body, pat } => { |
121 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 124 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
122 | 125 | ||
123 | self.breakables.push(BreakableContext { may_break: false }); | 126 | self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown }); |
124 | let pat_ty = | 127 | let pat_ty = |
125 | self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); | 128 | self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); |
126 | 129 | ||
@@ -229,17 +232,29 @@ impl<'a> InferenceContext<'a> { | |||
229 | } | 232 | } |
230 | Expr::Continue => Ty::simple(TypeCtor::Never), | 233 | Expr::Continue => Ty::simple(TypeCtor::Never), |
231 | Expr::Break { expr } => { | 234 | Expr::Break { expr } => { |
232 | if let Some(expr) = expr { | 235 | let val_ty = if let Some(expr) = expr { |
233 | // FIXME handle break with value | 236 | self.infer_expr(*expr, &Expectation::none()) |
234 | self.infer_expr(*expr, &Expectation::none()); | 237 | } else { |
235 | } | 238 | Ty::unit() |
239 | }; | ||
240 | |||
241 | let last_ty = if let Some(ctxt) = self.breakables.last() { | ||
242 | ctxt.break_ty.clone() | ||
243 | } else { | ||
244 | Ty::Unknown | ||
245 | }; | ||
246 | |||
247 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | ||
248 | |||
236 | if let Some(ctxt) = self.breakables.last_mut() { | 249 | if let Some(ctxt) = self.breakables.last_mut() { |
250 | ctxt.break_ty = merged_type; | ||
237 | ctxt.may_break = true; | 251 | ctxt.may_break = true; |
238 | } else { | 252 | } else { |
239 | self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop { | 253 | self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop { |
240 | expr: tgt_expr, | 254 | expr: tgt_expr, |
241 | }); | 255 | }); |
242 | } | 256 | } |
257 | |||
243 | Ty::simple(TypeCtor::Never) | 258 | Ty::simple(TypeCtor::Never) |
244 | } | 259 | } |
245 | Expr::Return { expr } => { | 260 | Expr::Return { expr } => { |
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index 54ec870df..4006f595d 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -10,7 +10,7 @@ use hir_def::{ | |||
10 | FieldId, | 10 | FieldId, |
11 | }; | 11 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use test_utils::tested_by; | 13 | use test_utils::mark; |
14 | 14 | ||
15 | use super::{BindingMode, Expectation, InferenceContext}; | 15 | use super::{BindingMode, Expectation, InferenceContext}; |
16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; | 16 | use crate::{utils::variant_data, Substs, Ty, TypeCtor}; |
@@ -111,7 +111,7 @@ impl<'a> InferenceContext<'a> { | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | } else if let Pat::Ref { .. } = &body[pat] { | 113 | } else if let Pat::Ref { .. } = &body[pat] { |
114 | tested_by!(match_ergonomics_ref); | 114 | mark::hit!(match_ergonomics_ref); |
115 | // When you encounter a `&pat` pattern, reset to Move. | 115 | // When you encounter a `&pat` pattern, reset to Move. |
116 | // This is so that `w` is by value: `let (_, &w) = &(1, &2);` | 116 | // This is so that `w` is by value: `let (_, &w) = &(1, &2);` |
117 | default_bm = BindingMode::Move; | 117 | default_bm = BindingMode::Move; |
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs index ab0bc8b70..269495ca0 100644 --- a/crates/ra_hir_ty/src/infer/unify.rs +++ b/crates/ra_hir_ty/src/infer/unify.rs | |||
@@ -4,7 +4,7 @@ use std::borrow::Cow; | |||
4 | 4 | ||
5 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 5 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
6 | 6 | ||
7 | use test_utils::tested_by; | 7 | use test_utils::mark; |
8 | 8 | ||
9 | use super::{InferenceContext, Obligation}; | 9 | use super::{InferenceContext, Obligation}; |
10 | use crate::{ | 10 | use crate::{ |
@@ -313,7 +313,7 @@ impl InferenceTable { | |||
313 | // more than once | 313 | // more than once |
314 | for i in 0..3 { | 314 | for i in 0..3 { |
315 | if i > 0 { | 315 | if i > 0 { |
316 | tested_by!(type_var_resolves_to_int_var); | 316 | mark::hit!(type_var_resolves_to_int_var); |
317 | } | 317 | } |
318 | match &*ty { | 318 | match &*ty { |
319 | Ty::Infer(tv) => { | 319 | Ty::Infer(tv) => { |
@@ -342,7 +342,7 @@ impl InferenceTable { | |||
342 | Ty::Infer(tv) => { | 342 | Ty::Infer(tv) => { |
343 | let inner = tv.to_inner(); | 343 | let inner = tv.to_inner(); |
344 | if tv_stack.contains(&inner) { | 344 | if tv_stack.contains(&inner) { |
345 | tested_by!(type_var_cycles_resolve_as_possible); | 345 | mark::hit!(type_var_cycles_resolve_as_possible); |
346 | // recursive type | 346 | // recursive type |
347 | return tv.fallback_value(); | 347 | return tv.fallback_value(); |
348 | } | 348 | } |
@@ -369,7 +369,7 @@ impl InferenceTable { | |||
369 | Ty::Infer(tv) => { | 369 | Ty::Infer(tv) => { |
370 | let inner = tv.to_inner(); | 370 | let inner = tv.to_inner(); |
371 | if tv_stack.contains(&inner) { | 371 | if tv_stack.contains(&inner) { |
372 | tested_by!(type_var_cycles_resolve_completely); | 372 | mark::hit!(type_var_cycles_resolve_completely); |
373 | // recursive type | 373 | // recursive type |
374 | return tv.fallback_value(); | 374 | return tv.fallback_value(); |
375 | } | 375 | } |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index daea02f88..c87ee06ce 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -42,7 +42,6 @@ pub mod expr; | |||
42 | mod tests; | 42 | mod tests; |
43 | #[cfg(test)] | 43 | #[cfg(test)] |
44 | mod test_db; | 44 | mod test_db; |
45 | mod marks; | ||
46 | mod _match; | 45 | mod _match; |
47 | 46 | ||
48 | use std::ops::Deref; | 47 | use std::ops::Deref; |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 9ad6dbe07..35ac86a46 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -812,7 +812,7 @@ impl TraitEnvironment { | |||
812 | // add `Self: Trait<T1, T2, ...>` to the environment in trait | 812 | // add `Self: Trait<T1, T2, ...>` to the environment in trait |
813 | // function default implementations (and hypothetical code | 813 | // function default implementations (and hypothetical code |
814 | // inside consts or type aliases) | 814 | // inside consts or type aliases) |
815 | test_utils::tested_by!(trait_self_implements_self); | 815 | test_utils::mark::hit!(trait_self_implements_self); |
816 | let substs = Substs::type_params(db, trait_id); | 816 | let substs = Substs::type_params(db, trait_id); |
817 | let trait_ref = TraitRef { trait_: trait_id, substs }; | 817 | let trait_ref = TraitRef { trait_: trait_id, substs }; |
818 | let pred = GenericPredicate::Implemented(trait_ref); | 818 | let pred = GenericPredicate::Implemented(trait_ref); |
diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs deleted file mode 100644 index a39740143..000000000 --- a/crates/ra_hir_ty/src/marks.rs +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | //! See test_utils/src/marks.rs | ||
2 | |||
3 | test_utils::marks!( | ||
4 | type_var_cycles_resolve_completely | ||
5 | type_var_cycles_resolve_as_possible | ||
6 | type_var_resolves_to_int_var | ||
7 | impl_self_type_match_without_receiver | ||
8 | match_ergonomics_ref | ||
9 | coerce_merge_fail_fallback | ||
10 | coerce_fn_reification | ||
11 | trait_self_implements_self | ||
12 | ); | ||
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 0851e16a8..e19628fdf 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -469,7 +469,7 @@ fn iterate_inherent_methods<T>( | |||
469 | // already happens in `is_valid_candidate` above; if not, we | 469 | // already happens in `is_valid_candidate` above; if not, we |
470 | // check it here | 470 | // check it here |
471 | if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() { | 471 | if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() { |
472 | test_utils::tested_by!(impl_self_type_match_without_receiver); | 472 | test_utils::mark::hit!(impl_self_type_match_without_receiver); |
473 | continue; | 473 | continue; |
474 | } | 474 | } |
475 | if let Some(result) = callback(&self_ty.value, item) { | 475 | if let Some(result) = callback(&self_ty.value, item) { |
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 6dc4b2cd1..2cc4f4bf9 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use super::infer_with_mismatches; | 1 | use super::infer_with_mismatches; |
2 | use insta::assert_snapshot; | 2 | use insta::assert_snapshot; |
3 | use test_utils::covers; | 3 | use test_utils::mark; |
4 | 4 | ||
5 | // Infer with some common definitions and impls. | 5 | // Infer with some common definitions and impls. |
6 | fn infer(source: &str) -> String { | 6 | fn infer(source: &str) -> String { |
@@ -339,7 +339,7 @@ fn test(i: i32) { | |||
339 | 339 | ||
340 | #[test] | 340 | #[test] |
341 | fn coerce_merge_one_by_one1() { | 341 | fn coerce_merge_one_by_one1() { |
342 | covers!(coerce_merge_fail_fallback); | 342 | mark::check!(coerce_merge_fail_fallback); |
343 | 343 | ||
344 | assert_snapshot!( | 344 | assert_snapshot!( |
345 | infer(r#" | 345 | infer(r#" |
@@ -547,7 +547,7 @@ fn test() { | |||
547 | 547 | ||
548 | #[test] | 548 | #[test] |
549 | fn coerce_fn_items_in_match_arms() { | 549 | fn coerce_fn_items_in_match_arms() { |
550 | covers!(coerce_fn_reification); | 550 | mark::check!(coerce_fn_reification); |
551 | assert_snapshot!( | 551 | assert_snapshot!( |
552 | infer_with_mismatches(r#" | 552 | infer_with_mismatches(r#" |
553 | fn foo1(x: u32) -> isize { 1 } | 553 | fn foo1(x: u32) -> isize { 1 } |
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 9c2c9e1d2..558a70022 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -984,7 +984,7 @@ fn test() { S2.into()<|>; } | |||
984 | 984 | ||
985 | #[test] | 985 | #[test] |
986 | fn method_resolution_overloaded_method() { | 986 | fn method_resolution_overloaded_method() { |
987 | test_utils::covers!(impl_self_type_match_without_receiver); | 987 | test_utils::mark::check!(impl_self_type_match_without_receiver); |
988 | let t = type_at( | 988 | let t = type_at( |
989 | r#" | 989 | r#" |
990 | //- main.rs | 990 | //- main.rs |
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index d83ff5e0e..0c5f972a2 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
2 | use test_utils::covers; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{infer, infer_with_mismatches}; | 4 | use super::{infer, infer_with_mismatches}; |
5 | 5 | ||
@@ -197,7 +197,7 @@ fn test() { | |||
197 | 197 | ||
198 | #[test] | 198 | #[test] |
199 | fn infer_pattern_match_ergonomics_ref() { | 199 | fn infer_pattern_match_ergonomics_ref() { |
200 | covers!(match_ergonomics_ref); | 200 | mark::check!(match_ergonomics_ref); |
201 | assert_snapshot!( | 201 | assert_snapshot!( |
202 | infer(r#" | 202 | infer(r#" |
203 | fn test() { | 203 | fn test() { |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index c2168222e..1f004bd63 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -1,9 +1,10 @@ | |||
1 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
2 | use test_utils::covers; | 2 | use ra_db::fixture::WithFixture; |
3 | use test_utils::mark; | ||
3 | 4 | ||
4 | use super::infer; | ||
5 | use crate::test_db::TestDB; | 5 | use crate::test_db::TestDB; |
6 | use ra_db::fixture::WithFixture; | 6 | |
7 | use super::infer; | ||
7 | 8 | ||
8 | #[test] | 9 | #[test] |
9 | fn bug_484() { | 10 | fn bug_484() { |
@@ -89,8 +90,8 @@ fn quux() { | |||
89 | 90 | ||
90 | #[test] | 91 | #[test] |
91 | fn recursive_vars() { | 92 | fn recursive_vars() { |
92 | covers!(type_var_cycles_resolve_completely); | 93 | mark::check!(type_var_cycles_resolve_completely); |
93 | covers!(type_var_cycles_resolve_as_possible); | 94 | mark::check!(type_var_cycles_resolve_as_possible); |
94 | assert_snapshot!( | 95 | assert_snapshot!( |
95 | infer(r#" | 96 | infer(r#" |
96 | fn test() { | 97 | fn test() { |
@@ -112,8 +113,6 @@ fn test() { | |||
112 | 113 | ||
113 | #[test] | 114 | #[test] |
114 | fn recursive_vars_2() { | 115 | fn recursive_vars_2() { |
115 | covers!(type_var_cycles_resolve_completely); | ||
116 | covers!(type_var_cycles_resolve_as_possible); | ||
117 | assert_snapshot!( | 116 | assert_snapshot!( |
118 | infer(r#" | 117 | infer(r#" |
119 | fn test() { | 118 | fn test() { |
@@ -170,7 +169,7 @@ fn write() { | |||
170 | 169 | ||
171 | #[test] | 170 | #[test] |
172 | fn infer_std_crash_2() { | 171 | fn infer_std_crash_2() { |
173 | covers!(type_var_resolves_to_int_var); | 172 | mark::check!(type_var_resolves_to_int_var); |
174 | // caused "equating two type variables, ...", taken from std | 173 | // caused "equating two type variables, ...", taken from std |
175 | assert_snapshot!( | 174 | assert_snapshot!( |
176 | infer(r#" | 175 | infer(r#" |
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 72122c070..fd2208af2 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -1860,3 +1860,66 @@ fn test() { | |||
1860 | "### | 1860 | "### |
1861 | ); | 1861 | ); |
1862 | } | 1862 | } |
1863 | |||
1864 | #[test] | ||
1865 | fn infer_loop_break_with_val() { | ||
1866 | assert_snapshot!( | ||
1867 | infer(r#" | ||
1868 | enum Option<T> { Some(T), None } | ||
1869 | use Option::*; | ||
1870 | |||
1871 | fn test() { | ||
1872 | let x = loop { | ||
1873 | if false { | ||
1874 | break None; | ||
1875 | } | ||
1876 | |||
1877 | break Some(true); | ||
1878 | }; | ||
1879 | } | ||
1880 | "#), | ||
1881 | @r###" | ||
1882 | 60..169 '{ ... }; }': () | ||
1883 | 70..71 'x': Option<bool> | ||
1884 | 74..166 'loop {... }': Option<bool> | ||
1885 | 79..166 '{ ... }': () | ||
1886 | 89..133 'if fal... }': () | ||
1887 | 92..97 'false': bool | ||
1888 | 98..133 '{ ... }': () | ||
1889 | 112..122 'break None': ! | ||
1890 | 118..122 'None': Option<bool> | ||
1891 | 143..159 'break ...(true)': ! | ||
1892 | 149..153 'Some': Some<bool>(bool) -> Option<bool> | ||
1893 | 149..159 'Some(true)': Option<bool> | ||
1894 | 154..158 'true': bool | ||
1895 | "### | ||
1896 | ); | ||
1897 | } | ||
1898 | |||
1899 | #[test] | ||
1900 | fn infer_loop_break_without_val() { | ||
1901 | assert_snapshot!( | ||
1902 | infer(r#" | ||
1903 | enum Option<T> { Some(T), None } | ||
1904 | use Option::*; | ||
1905 | |||
1906 | fn test() { | ||
1907 | let x = loop { | ||
1908 | if false { | ||
1909 | break; | ||
1910 | } | ||
1911 | }; | ||
1912 | } | ||
1913 | "#), | ||
1914 | @r###" | ||
1915 | 60..137 '{ ... }; }': () | ||
1916 | 70..71 'x': () | ||
1917 | 74..134 'loop {... }': () | ||
1918 | 79..134 '{ ... }': () | ||
1919 | 89..128 'if fal... }': () | ||
1920 | 92..97 'false': bool | ||
1921 | 98..128 '{ ... }': () | ||
1922 | 112..117 'break': ! | ||
1923 | "### | ||
1924 | ); | ||
1925 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index c49aacf98..34f4b9039 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
2 | |||
3 | use ra_db::fixture::WithFixture; | 2 | use ra_db::fixture::WithFixture; |
3 | use test_utils::mark; | ||
4 | 4 | ||
5 | use super::{infer, infer_with_mismatches, type_at, type_at_pos}; | ||
6 | use crate::test_db::TestDB; | 5 | use crate::test_db::TestDB; |
7 | 6 | ||
7 | use super::{infer, infer_with_mismatches, type_at, type_at_pos}; | ||
8 | |||
8 | #[test] | 9 | #[test] |
9 | fn infer_await() { | 10 | fn infer_await() { |
10 | let (db, pos) = TestDB::with_position( | 11 | let (db, pos) = TestDB::with_position( |
@@ -301,7 +302,7 @@ fn test() { | |||
301 | 302 | ||
302 | #[test] | 303 | #[test] |
303 | fn trait_default_method_self_bound_implements_trait() { | 304 | fn trait_default_method_self_bound_implements_trait() { |
304 | test_utils::covers!(trait_self_implements_self); | 305 | mark::check!(trait_self_implements_self); |
305 | assert_snapshot!( | 306 | assert_snapshot!( |
306 | infer(r#" | 307 | infer(r#" |
307 | trait Trait { | 308 | trait Trait { |
@@ -324,7 +325,6 @@ trait Trait { | |||
324 | 325 | ||
325 | #[test] | 326 | #[test] |
326 | fn trait_default_method_self_bound_implements_super_trait() { | 327 | fn trait_default_method_self_bound_implements_super_trait() { |
327 | test_utils::covers!(trait_self_implements_self); | ||
328 | assert_snapshot!( | 328 | assert_snapshot!( |
329 | infer(r#" | 329 | infer(r#" |
330 | trait SuperTrait { | 330 | trait SuperTrait { |
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index 780a03c13..aa039e6fc 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ | |||
5 | ast::{self, ArgListOwner}, | 5 | ast::{self, ArgListOwner}, |
6 | match_ast, AstNode, SyntaxNode, SyntaxToken, | 6 | match_ast, AstNode, SyntaxNode, SyntaxToken, |
7 | }; | 7 | }; |
8 | use test_utils::tested_by; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{CallInfo, FilePosition, FunctionSignature}; | 10 | use crate::{CallInfo, FilePosition, FunctionSignature}; |
11 | 11 | ||
@@ -84,7 +84,7 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op | |||
84 | 84 | ||
85 | let arg_list_range = arg_list.syntax().text_range(); | 85 | let arg_list_range = arg_list.syntax().text_range(); |
86 | if !arg_list_range.contains_inclusive(token.text_range().start()) { | 86 | if !arg_list_range.contains_inclusive(token.text_range().start()) { |
87 | tested_by!(call_info_bad_offset); | 87 | mark::hit!(call_info_bad_offset); |
88 | return None; | 88 | return None; |
89 | } | 89 | } |
90 | 90 | ||
@@ -213,7 +213,7 @@ impl CallInfo { | |||
213 | 213 | ||
214 | #[cfg(test)] | 214 | #[cfg(test)] |
215 | mod tests { | 215 | mod tests { |
216 | use test_utils::covers; | 216 | use test_utils::mark; |
217 | 217 | ||
218 | use crate::mock_analysis::single_file_with_position; | 218 | use crate::mock_analysis::single_file_with_position; |
219 | 219 | ||
@@ -529,7 +529,7 @@ By default this method stops actor's `Context`."# | |||
529 | 529 | ||
530 | #[test] | 530 | #[test] |
531 | fn call_info_bad_offset() { | 531 | fn call_info_bad_offset() { |
532 | covers!(call_info_bad_offset); | 532 | mark::check!(call_info_bad_offset); |
533 | let (analysis, position) = single_file_with_position( | 533 | let (analysis, position) = single_file_with_position( |
534 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} | 534 | r#"fn foo(x: u32, y: u32) -> u32 {x + y} |
535 | fn bar() { foo <|> (3, ); }"#, | 535 | fn bar() { foo <|> (3, ); }"#, |
diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index db7430454..02ac0166b 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | 3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; |
4 | use ra_syntax::AstNode; | 4 | use ra_syntax::AstNode; |
5 | use rustc_hash::FxHashSet; | 5 | use rustc_hash::FxHashSet; |
6 | use test_utils::tested_by; | 6 | use test_utils::mark; |
7 | 7 | ||
8 | use crate::completion::{CompletionContext, Completions}; | 8 | use crate::completion::{CompletionContext, Completions}; |
9 | 9 | ||
@@ -40,7 +40,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
40 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { | 40 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { |
41 | if name_ref.syntax().text() == name.to_string().as_str() { | 41 | if name_ref.syntax().text() == name.to_string().as_str() { |
42 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 42 | // for `use self::foo<|>`, don't suggest `foo` as a completion |
43 | tested_by!(dont_complete_current_use); | 43 | mark::hit!(dont_complete_current_use); |
44 | continue; | 44 | continue; |
45 | } | 45 | } |
46 | } | 46 | } |
@@ -147,7 +147,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
147 | 147 | ||
148 | #[cfg(test)] | 148 | #[cfg(test)] |
149 | mod tests { | 149 | mod tests { |
150 | use test_utils::covers; | 150 | use test_utils::mark; |
151 | 151 | ||
152 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; | 152 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
153 | use insta::assert_debug_snapshot; | 153 | use insta::assert_debug_snapshot; |
@@ -158,7 +158,7 @@ mod tests { | |||
158 | 158 | ||
159 | #[test] | 159 | #[test] |
160 | fn dont_complete_current_use() { | 160 | fn dont_complete_current_use() { |
161 | covers!(dont_complete_current_use); | 161 | mark::check!(dont_complete_current_use); |
162 | let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference); | 162 | let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference); |
163 | assert!(completions.is_empty()); | 163 | assert!(completions.is_empty()); |
164 | } | 164 | } |
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs index bd40af1cb..db791660a 100644 --- a/crates/ra_ide/src/completion/complete_unqualified_path.rs +++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Completion of names from the current scope, e.g. locals and imported items. | 1 | //! Completion of names from the current scope, e.g. locals and imported items. |
2 | 2 | ||
3 | use hir::ScopeDef; | 3 | use hir::ScopeDef; |
4 | use test_utils::tested_by; | 4 | use test_utils::mark; |
5 | 5 | ||
6 | use crate::completion::{CompletionContext, Completions}; | 6 | use crate::completion::{CompletionContext, Completions}; |
7 | use hir::{Adt, ModuleDef, Type}; | 7 | use hir::{Adt, ModuleDef, Type}; |
@@ -30,7 +30,7 @@ pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
30 | if ctx.use_item_syntax.is_some() { | 30 | if ctx.use_item_syntax.is_some() { |
31 | if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { | 31 | if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { |
32 | if name_ref.syntax().text() == name.to_string().as_str() { | 32 | if name_ref.syntax().text() == name.to_string().as_str() { |
33 | tested_by!(self_fulfilling_completion); | 33 | mark::hit!(self_fulfilling_completion); |
34 | return; | 34 | return; |
35 | } | 35 | } |
36 | } | 36 | } |
@@ -66,7 +66,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T | |||
66 | #[cfg(test)] | 66 | #[cfg(test)] |
67 | mod tests { | 67 | mod tests { |
68 | use insta::assert_debug_snapshot; | 68 | use insta::assert_debug_snapshot; |
69 | use test_utils::covers; | 69 | use test_utils::mark; |
70 | 70 | ||
71 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; | 71 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
72 | 72 | ||
@@ -76,7 +76,7 @@ mod tests { | |||
76 | 76 | ||
77 | #[test] | 77 | #[test] |
78 | fn self_fulfilling_completion() { | 78 | fn self_fulfilling_completion() { |
79 | covers!(self_fulfilling_completion); | 79 | mark::check!(self_fulfilling_completion); |
80 | assert_debug_snapshot!( | 80 | assert_debug_snapshot!( |
81 | do_reference_completion( | 81 | do_reference_completion( |
82 | r#" | 82 | r#" |
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 077cf9647..440ffa31d 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; | 3 | use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; |
4 | use ra_syntax::ast::NameOwner; | 4 | use ra_syntax::ast::NameOwner; |
5 | use stdx::SepBy; | 5 | use stdx::SepBy; |
6 | use test_utils::tested_by; | 6 | use test_utils::mark; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | completion::{ | 9 | completion::{ |
@@ -121,7 +121,7 @@ impl Completions { | |||
121 | _ => false, | 121 | _ => false, |
122 | }; | 122 | }; |
123 | if has_non_default_type_params { | 123 | if has_non_default_type_params { |
124 | tested_by!(inserts_angle_brackets_for_generics); | 124 | mark::hit!(inserts_angle_brackets_for_generics); |
125 | completion_item = completion_item | 125 | completion_item = completion_item |
126 | .lookup_by(local_name.clone()) | 126 | .lookup_by(local_name.clone()) |
127 | .label(format!("{}<…>", local_name)) | 127 | .label(format!("{}<…>", local_name)) |
@@ -176,7 +176,7 @@ impl Completions { | |||
176 | } | 176 | } |
177 | None if needs_bang => builder.insert_text(format!("{}!", name)), | 177 | None if needs_bang => builder.insert_text(format!("{}!", name)), |
178 | _ => { | 178 | _ => { |
179 | tested_by!(dont_insert_macro_call_parens_unncessary); | 179 | mark::hit!(dont_insert_macro_call_parens_unncessary); |
180 | builder.insert_text(name) | 180 | builder.insert_text(name) |
181 | } | 181 | } |
182 | }; | 182 | }; |
@@ -330,14 +330,14 @@ pub(crate) fn compute_score( | |||
330 | // FIXME: this should not fall back to string equality. | 330 | // FIXME: this should not fall back to string equality. |
331 | let ty = &ty.display(ctx.db).to_string(); | 331 | let ty = &ty.display(ctx.db).to_string(); |
332 | let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { | 332 | let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { |
333 | tested_by!(test_struct_field_completion_in_record_lit); | 333 | mark::hit!(test_struct_field_completion_in_record_lit); |
334 | let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; | 334 | let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; |
335 | ( | 335 | ( |
336 | struct_field.name(ctx.db).to_string(), | 336 | struct_field.name(ctx.db).to_string(), |
337 | struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), | 337 | struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), |
338 | ) | 338 | ) |
339 | } else if let Some(active_parameter) = &ctx.active_parameter { | 339 | } else if let Some(active_parameter) = &ctx.active_parameter { |
340 | tested_by!(test_struct_field_completion_in_func_call); | 340 | mark::hit!(test_struct_field_completion_in_func_call); |
341 | (active_parameter.name.clone(), active_parameter.ty.clone()) | 341 | (active_parameter.name.clone(), active_parameter.ty.clone()) |
342 | } else { | 342 | } else { |
343 | return None; | 343 | return None; |
@@ -398,7 +398,7 @@ impl Builder { | |||
398 | None => return self, | 398 | None => return self, |
399 | }; | 399 | }; |
400 | // If not an import, add parenthesis automatically. | 400 | // If not an import, add parenthesis automatically. |
401 | tested_by!(inserts_parens_for_function_calls); | 401 | mark::hit!(inserts_parens_for_function_calls); |
402 | 402 | ||
403 | let (snippet, label) = if params.is_empty() { | 403 | let (snippet, label) = if params.is_empty() { |
404 | (format!("{}()$0", name), format!("{}()", name)) | 404 | (format!("{}()$0", name), format!("{}()", name)) |
@@ -457,7 +457,7 @@ fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static s | |||
457 | #[cfg(test)] | 457 | #[cfg(test)] |
458 | mod tests { | 458 | mod tests { |
459 | use insta::assert_debug_snapshot; | 459 | use insta::assert_debug_snapshot; |
460 | use test_utils::covers; | 460 | use test_utils::mark; |
461 | 461 | ||
462 | use crate::completion::{ | 462 | use crate::completion::{ |
463 | test_utils::{do_completion, do_completion_with_options}, | 463 | test_utils::{do_completion, do_completion_with_options}, |
@@ -607,7 +607,7 @@ mod tests { | |||
607 | 607 | ||
608 | #[test] | 608 | #[test] |
609 | fn inserts_parens_for_function_calls() { | 609 | fn inserts_parens_for_function_calls() { |
610 | covers!(inserts_parens_for_function_calls); | 610 | mark::check!(inserts_parens_for_function_calls); |
611 | assert_debug_snapshot!( | 611 | assert_debug_snapshot!( |
612 | do_reference_completion( | 612 | do_reference_completion( |
613 | r" | 613 | r" |
@@ -992,7 +992,7 @@ mod tests { | |||
992 | 992 | ||
993 | #[test] | 993 | #[test] |
994 | fn inserts_angle_brackets_for_generics() { | 994 | fn inserts_angle_brackets_for_generics() { |
995 | covers!(inserts_angle_brackets_for_generics); | 995 | mark::check!(inserts_angle_brackets_for_generics); |
996 | assert_debug_snapshot!( | 996 | assert_debug_snapshot!( |
997 | do_reference_completion( | 997 | do_reference_completion( |
998 | r" | 998 | r" |
@@ -1115,7 +1115,7 @@ mod tests { | |||
1115 | 1115 | ||
1116 | #[test] | 1116 | #[test] |
1117 | fn dont_insert_macro_call_parens_unncessary() { | 1117 | fn dont_insert_macro_call_parens_unncessary() { |
1118 | covers!(dont_insert_macro_call_parens_unncessary); | 1118 | mark::check!(dont_insert_macro_call_parens_unncessary); |
1119 | assert_debug_snapshot!( | 1119 | assert_debug_snapshot!( |
1120 | do_reference_completion( | 1120 | do_reference_completion( |
1121 | r" | 1121 | r" |
@@ -1181,7 +1181,7 @@ mod tests { | |||
1181 | 1181 | ||
1182 | #[test] | 1182 | #[test] |
1183 | fn test_struct_field_completion_in_func_call() { | 1183 | fn test_struct_field_completion_in_func_call() { |
1184 | covers!(test_struct_field_completion_in_func_call); | 1184 | mark::check!(test_struct_field_completion_in_func_call); |
1185 | assert_debug_snapshot!( | 1185 | assert_debug_snapshot!( |
1186 | do_reference_completion( | 1186 | do_reference_completion( |
1187 | r" | 1187 | r" |
@@ -1271,7 +1271,7 @@ mod tests { | |||
1271 | 1271 | ||
1272 | #[test] | 1272 | #[test] |
1273 | fn test_struct_field_completion_in_record_lit() { | 1273 | fn test_struct_field_completion_in_record_lit() { |
1274 | covers!(test_struct_field_completion_in_record_lit); | 1274 | mark::check!(test_struct_field_completion_in_record_lit); |
1275 | assert_debug_snapshot!( | 1275 | assert_debug_snapshot!( |
1276 | do_reference_completion( | 1276 | do_reference_completion( |
1277 | r" | 1277 | r" |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 150895abb..90e85d419 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -93,7 +93,7 @@ pub(crate) fn reference_definition( | |||
93 | 93 | ||
94 | #[cfg(test)] | 94 | #[cfg(test)] |
95 | mod tests { | 95 | mod tests { |
96 | use test_utils::{assert_eq_text, covers}; | 96 | use test_utils::assert_eq_text; |
97 | 97 | ||
98 | use crate::mock_analysis::analysis_and_position; | 98 | use crate::mock_analysis::analysis_and_position; |
99 | 99 | ||
@@ -208,7 +208,6 @@ mod tests { | |||
208 | 208 | ||
209 | #[test] | 209 | #[test] |
210 | fn goto_def_for_macros() { | 210 | fn goto_def_for_macros() { |
211 | covers!(ra_ide_db::goto_def_for_macros); | ||
212 | check_goto( | 211 | check_goto( |
213 | " | 212 | " |
214 | //- /lib.rs | 213 | //- /lib.rs |
@@ -225,7 +224,6 @@ mod tests { | |||
225 | 224 | ||
226 | #[test] | 225 | #[test] |
227 | fn goto_def_for_macros_from_other_crates() { | 226 | fn goto_def_for_macros_from_other_crates() { |
228 | covers!(ra_ide_db::goto_def_for_macros); | ||
229 | check_goto( | 227 | check_goto( |
230 | " | 228 | " |
231 | //- /lib.rs | 229 | //- /lib.rs |
@@ -245,7 +243,6 @@ mod tests { | |||
245 | 243 | ||
246 | #[test] | 244 | #[test] |
247 | fn goto_def_for_use_alias() { | 245 | fn goto_def_for_use_alias() { |
248 | covers!(ra_ide_db::goto_def_for_use_alias); | ||
249 | check_goto( | 246 | check_goto( |
250 | " | 247 | " |
251 | //- /lib.rs | 248 | //- /lib.rs |
@@ -370,7 +367,6 @@ mod tests { | |||
370 | 367 | ||
371 | #[test] | 368 | #[test] |
372 | fn goto_def_for_methods() { | 369 | fn goto_def_for_methods() { |
373 | covers!(ra_ide_db::goto_def_for_methods); | ||
374 | check_goto( | 370 | check_goto( |
375 | " | 371 | " |
376 | //- /lib.rs | 372 | //- /lib.rs |
@@ -390,7 +386,6 @@ mod tests { | |||
390 | 386 | ||
391 | #[test] | 387 | #[test] |
392 | fn goto_def_for_fields() { | 388 | fn goto_def_for_fields() { |
393 | covers!(ra_ide_db::goto_def_for_fields); | ||
394 | check_goto( | 389 | check_goto( |
395 | r" | 390 | r" |
396 | //- /lib.rs | 391 | //- /lib.rs |
@@ -409,7 +404,6 @@ mod tests { | |||
409 | 404 | ||
410 | #[test] | 405 | #[test] |
411 | fn goto_def_for_record_fields() { | 406 | fn goto_def_for_record_fields() { |
412 | covers!(ra_ide_db::goto_def_for_record_fields); | ||
413 | check_goto( | 407 | check_goto( |
414 | r" | 408 | r" |
415 | //- /lib.rs | 409 | //- /lib.rs |
@@ -430,7 +424,6 @@ mod tests { | |||
430 | 424 | ||
431 | #[test] | 425 | #[test] |
432 | fn goto_def_for_record_pat_fields() { | 426 | fn goto_def_for_record_pat_fields() { |
433 | covers!(ra_ide_db::goto_def_for_record_field_pats); | ||
434 | check_goto( | 427 | check_goto( |
435 | r" | 428 | r" |
436 | //- /lib.rs | 429 | //- /lib.rs |
@@ -873,7 +866,6 @@ mod tests { | |||
873 | 866 | ||
874 | #[test] | 867 | #[test] |
875 | fn goto_def_for_field_init_shorthand() { | 868 | fn goto_def_for_field_init_shorthand() { |
876 | covers!(ra_ide_db::goto_def_for_field_init_shorthand); | ||
877 | check_goto( | 869 | check_goto( |
878 | " | 870 | " |
879 | //- /lib.rs | 871 | //- /lib.rs |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 66125f2f5..83cb498f7 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -43,8 +43,6 @@ mod expand_macro; | |||
43 | mod ssr; | 43 | mod ssr; |
44 | 44 | ||
45 | #[cfg(test)] | 45 | #[cfg(test)] |
46 | mod marks; | ||
47 | #[cfg(test)] | ||
48 | mod test_utils; | 46 | mod test_utils; |
49 | 47 | ||
50 | use std::sync::Arc; | 48 | use std::sync::Arc; |
diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs deleted file mode 100644 index 51ca4dde3..000000000 --- a/crates/ra_ide/src/marks.rs +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | //! See test_utils/src/marks.rs | ||
2 | |||
3 | test_utils::marks!( | ||
4 | inserts_angle_brackets_for_generics | ||
5 | inserts_parens_for_function_calls | ||
6 | call_info_bad_offset | ||
7 | dont_complete_current_use | ||
8 | test_resolve_parent_module_on_module_decl | ||
9 | search_filters_by_range | ||
10 | dont_insert_macro_call_parens_unncessary | ||
11 | self_fulfilling_completion | ||
12 | test_struct_field_completion_in_func_call | ||
13 | test_struct_field_completion_in_record_lit | ||
14 | test_rename_struct_field_for_shorthand | ||
15 | test_rename_local_for_field_shorthand | ||
16 | ); | ||
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index aaf4460df..a083fb1eb 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs | |||
@@ -7,7 +7,7 @@ use ra_syntax::{ | |||
7 | algo::find_node_at_offset, | 7 | algo::find_node_at_offset, |
8 | ast::{self, AstNode}, | 8 | ast::{self, AstNode}, |
9 | }; | 9 | }; |
10 | use test_utils::tested_by; | 10 | use test_utils::mark; |
11 | 11 | ||
12 | use crate::NavigationTarget; | 12 | use crate::NavigationTarget; |
13 | 13 | ||
@@ -25,7 +25,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na | |||
25 | .item_list() | 25 | .item_list() |
26 | .map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset)) | 26 | .map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset)) |
27 | { | 27 | { |
28 | tested_by!(test_resolve_parent_module_on_module_decl); | 28 | mark::hit!(test_resolve_parent_module_on_module_decl); |
29 | module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast); | 29 | module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast); |
30 | } | 30 | } |
31 | } | 31 | } |
@@ -57,7 +57,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { | |||
57 | mod tests { | 57 | mod tests { |
58 | use ra_cfg::CfgOptions; | 58 | use ra_cfg::CfgOptions; |
59 | use ra_db::Env; | 59 | use ra_db::Env; |
60 | use test_utils::covers; | 60 | use test_utils::mark; |
61 | 61 | ||
62 | use crate::{ | 62 | use crate::{ |
63 | mock_analysis::{analysis_and_position, MockAnalysis}, | 63 | mock_analysis::{analysis_and_position, MockAnalysis}, |
@@ -81,7 +81,7 @@ mod tests { | |||
81 | 81 | ||
82 | #[test] | 82 | #[test] |
83 | fn test_resolve_parent_module_on_module_decl() { | 83 | fn test_resolve_parent_module_on_module_decl() { |
84 | covers!(test_resolve_parent_module_on_module_decl); | 84 | mark::check!(test_resolve_parent_module_on_module_decl); |
85 | let (analysis, pos) = analysis_and_position( | 85 | let (analysis, pos) = analysis_and_position( |
86 | " | 86 | " |
87 | //- /lib.rs | 87 | //- /lib.rs |
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 074284b42..96444bf6a 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -190,8 +190,6 @@ fn get_struct_def_name_for_struct_literal_search( | |||
190 | 190 | ||
191 | #[cfg(test)] | 191 | #[cfg(test)] |
192 | mod tests { | 192 | mod tests { |
193 | use test_utils::covers; | ||
194 | |||
195 | use crate::{ | 193 | use crate::{ |
196 | mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis}, | 194 | mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis}, |
197 | Declaration, Reference, ReferenceSearchResult, SearchScope, | 195 | Declaration, Reference, ReferenceSearchResult, SearchScope, |
@@ -301,7 +299,6 @@ mod tests { | |||
301 | 299 | ||
302 | #[test] | 300 | #[test] |
303 | fn search_filters_by_range() { | 301 | fn search_filters_by_range() { |
304 | covers!(ra_ide_db::search_filters_by_range); | ||
305 | let code = r#" | 302 | let code = r#" |
306 | fn foo() { | 303 | fn foo() { |
307 | let spam<|> = 92; | 304 | let spam<|> = 92; |
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 68a53ad4b..62ec8d85d 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -9,7 +9,7 @@ use ra_syntax::{ | |||
9 | }; | 9 | }; |
10 | use ra_text_edit::TextEdit; | 10 | use ra_text_edit::TextEdit; |
11 | use std::convert::TryInto; | 11 | use std::convert::TryInto; |
12 | use test_utils::tested_by; | 12 | use test_utils::mark; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, | 15 | references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, |
@@ -57,13 +57,13 @@ fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFil | |||
57 | let file_id = reference.file_range.file_id; | 57 | let file_id = reference.file_range.file_id; |
58 | let range = match reference.kind { | 58 | let range = match reference.kind { |
59 | ReferenceKind::FieldShorthandForField => { | 59 | ReferenceKind::FieldShorthandForField => { |
60 | tested_by!(test_rename_struct_field_for_shorthand); | 60 | mark::hit!(test_rename_struct_field_for_shorthand); |
61 | replacement_text.push_str(new_name); | 61 | replacement_text.push_str(new_name); |
62 | replacement_text.push_str(": "); | 62 | replacement_text.push_str(": "); |
63 | TextRange::new(reference.file_range.range.start(), reference.file_range.range.start()) | 63 | TextRange::new(reference.file_range.range.start(), reference.file_range.range.start()) |
64 | } | 64 | } |
65 | ReferenceKind::FieldShorthandForLocal => { | 65 | ReferenceKind::FieldShorthandForLocal => { |
66 | tested_by!(test_rename_local_for_field_shorthand); | 66 | mark::hit!(test_rename_local_for_field_shorthand); |
67 | replacement_text.push_str(": "); | 67 | replacement_text.push_str(": "); |
68 | replacement_text.push_str(new_name); | 68 | replacement_text.push_str(new_name); |
69 | TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) | 69 | TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) |
@@ -260,7 +260,7 @@ fn rename_reference( | |||
260 | mod tests { | 260 | mod tests { |
261 | use insta::assert_debug_snapshot; | 261 | use insta::assert_debug_snapshot; |
262 | use ra_text_edit::TextEditBuilder; | 262 | use ra_text_edit::TextEditBuilder; |
263 | use test_utils::{assert_eq_text, covers}; | 263 | use test_utils::{assert_eq_text, mark}; |
264 | 264 | ||
265 | use crate::{ | 265 | use crate::{ |
266 | mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, | 266 | mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, |
@@ -492,7 +492,7 @@ mod tests { | |||
492 | 492 | ||
493 | #[test] | 493 | #[test] |
494 | fn test_rename_struct_field_for_shorthand() { | 494 | fn test_rename_struct_field_for_shorthand() { |
495 | covers!(test_rename_struct_field_for_shorthand); | 495 | mark::check!(test_rename_struct_field_for_shorthand); |
496 | test_rename( | 496 | test_rename( |
497 | r#" | 497 | r#" |
498 | struct Foo { | 498 | struct Foo { |
@@ -522,7 +522,7 @@ mod tests { | |||
522 | 522 | ||
523 | #[test] | 523 | #[test] |
524 | fn test_rename_local_for_field_shorthand() { | 524 | fn test_rename_local_for_field_shorthand() { |
525 | covers!(test_rename_local_for_field_shorthand); | 525 | mark::check!(test_rename_local_for_field_shorthand); |
526 | test_rename( | 526 | test_rename( |
527 | r#" | 527 | r#" |
528 | struct Foo { | 528 | struct Foo { |
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 60c11178e..8b06cbfc5 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs | |||
@@ -14,7 +14,6 @@ use ra_syntax::{ | |||
14 | ast::{self, AstNode}, | 14 | ast::{self, AstNode}, |
15 | match_ast, | 15 | match_ast, |
16 | }; | 16 | }; |
17 | use test_utils::tested_by; | ||
18 | 17 | ||
19 | use crate::RootDatabase; | 18 | use crate::RootDatabase; |
20 | 19 | ||
@@ -118,7 +117,6 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti | |||
118 | match_ast! { | 117 | match_ast! { |
119 | match parent { | 118 | match parent { |
120 | ast::Alias(it) => { | 119 | ast::Alias(it) => { |
121 | tested_by!(goto_def_for_use_alias; force); | ||
122 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; | 120 | let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; |
123 | let path = use_tree.path()?; | 121 | let path = use_tree.path()?; |
124 | let path_segment = path.segment()?; | 122 | let path_segment = path.segment()?; |
@@ -203,6 +201,8 @@ impl NameRefClass { | |||
203 | } | 201 | } |
204 | } | 202 | } |
205 | 203 | ||
204 | // Note: we don't have unit-tests for this rather important function. | ||
205 | // It is primarily exercised via goto definition tests in `ra_ide`. | ||
206 | pub fn classify_name_ref( | 206 | pub fn classify_name_ref( |
207 | sema: &Semantics<RootDatabase>, | 207 | sema: &Semantics<RootDatabase>, |
208 | name_ref: &ast::NameRef, | 208 | name_ref: &ast::NameRef, |
@@ -212,22 +212,18 @@ pub fn classify_name_ref( | |||
212 | let parent = name_ref.syntax().parent()?; | 212 | let parent = name_ref.syntax().parent()?; |
213 | 213 | ||
214 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { | 214 | if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { |
215 | tested_by!(goto_def_for_methods; force); | ||
216 | if let Some(func) = sema.resolve_method_call(&method_call) { | 215 | if let Some(func) = sema.resolve_method_call(&method_call) { |
217 | return Some(NameRefClass::Definition(Definition::ModuleDef(func.into()))); | 216 | return Some(NameRefClass::Definition(Definition::ModuleDef(func.into()))); |
218 | } | 217 | } |
219 | } | 218 | } |
220 | 219 | ||
221 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { | 220 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { |
222 | tested_by!(goto_def_for_fields; force); | ||
223 | if let Some(field) = sema.resolve_field(&field_expr) { | 221 | if let Some(field) = sema.resolve_field(&field_expr) { |
224 | return Some(NameRefClass::Definition(Definition::Field(field))); | 222 | return Some(NameRefClass::Definition(Definition::Field(field))); |
225 | } | 223 | } |
226 | } | 224 | } |
227 | 225 | ||
228 | if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { | 226 | if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { |
229 | tested_by!(goto_def_for_record_fields; force); | ||
230 | tested_by!(goto_def_for_field_init_shorthand; force); | ||
231 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { | 227 | if let Some((field, local)) = sema.resolve_record_field(&record_field) { |
232 | let field = Definition::Field(field); | 228 | let field = Definition::Field(field); |
233 | let res = match local { | 229 | let res = match local { |
@@ -239,7 +235,6 @@ pub fn classify_name_ref( | |||
239 | } | 235 | } |
240 | 236 | ||
241 | if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) { | 237 | if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) { |
242 | tested_by!(goto_def_for_record_field_pats; force); | ||
243 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { | 238 | if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { |
244 | let field = Definition::Field(field); | 239 | let field = Definition::Field(field); |
245 | return Some(NameRefClass::Definition(field)); | 240 | return Some(NameRefClass::Definition(field)); |
@@ -247,7 +242,6 @@ pub fn classify_name_ref( | |||
247 | } | 242 | } |
248 | 243 | ||
249 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { | 244 | if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { |
250 | tested_by!(goto_def_for_macros; force); | ||
251 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { | 245 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { |
252 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); | 246 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); |
253 | } | 247 | } |
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index 52fcd7b6f..4f37954bf 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | //! | 2 | //! |
3 | //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. | 3 | //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. |
4 | 4 | ||
5 | pub mod marks; | ||
6 | pub mod line_index; | 5 | pub mod line_index; |
7 | pub mod line_index_utils; | 6 | pub mod line_index_utils; |
8 | pub mod symbol_index; | 7 | pub mod symbol_index; |
diff --git a/crates/ra_ide_db/src/marks.rs b/crates/ra_ide_db/src/marks.rs deleted file mode 100644 index 386fe605c..000000000 --- a/crates/ra_ide_db/src/marks.rs +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | //! See test_utils/src/marks.rs | ||
2 | |||
3 | test_utils::marks![ | ||
4 | goto_def_for_macros | ||
5 | goto_def_for_use_alias | ||
6 | goto_def_for_methods | ||
7 | goto_def_for_fields | ||
8 | goto_def_for_record_fields | ||
9 | goto_def_for_field_init_shorthand | ||
10 | goto_def_for_record_field_pats | ||
11 | search_filters_by_range | ||
12 | ]; | ||
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index b464959fc..589f44771 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs | |||
@@ -12,7 +12,6 @@ use ra_db::{FileId, FileRange, SourceDatabaseExt}; | |||
12 | use ra_prof::profile; | 12 | use ra_prof::profile; |
13 | use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize}; | 13 | use ra_syntax::{ast, match_ast, AstNode, TextRange, TextSize}; |
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
15 | use test_utils::tested_by; | ||
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
18 | defs::{classify_name_ref, Definition, NameRefClass}, | 17 | defs::{classify_name_ref, Definition, NameRefClass}, |
@@ -209,7 +208,6 @@ impl Definition { | |||
209 | for (idx, _) in text.match_indices(pat) { | 208 | for (idx, _) in text.match_indices(pat) { |
210 | let offset: TextSize = idx.try_into().unwrap(); | 209 | let offset: TextSize = idx.try_into().unwrap(); |
211 | if !search_range.contains_inclusive(offset) { | 210 | if !search_range.contains_inclusive(offset) { |
212 | tested_by!(search_filters_by_range; force); | ||
213 | continue; | 211 | continue; |
214 | } | 212 | } |
215 | 213 | ||
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index b1e3c328f..be2cfbaa2 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | //! * marks (see the eponymous module). | 7 | //! * marks (see the eponymous module). |
8 | 8 | ||
9 | #[macro_use] | 9 | #[macro_use] |
10 | pub mod marks; | 10 | pub mod mark; |
11 | 11 | ||
12 | use std::{ | 12 | use std::{ |
13 | fs, | 13 | fs, |
diff --git a/crates/test_utils/src/marks.rs b/crates/test_utils/src/mark.rs index c3185e860..7c309a894 100644 --- a/crates/test_utils/src/marks.rs +++ b/crates/test_utils/src/mark.rs | |||
@@ -7,18 +7,18 @@ | |||
7 | //! ``` | 7 | //! ``` |
8 | //! #[test] | 8 | //! #[test] |
9 | //! fn test_foo() { | 9 | //! fn test_foo() { |
10 | //! covers!(test_foo); | 10 | //! mark::check!(test_foo); |
11 | //! } | 11 | //! } |
12 | //! ``` | 12 | //! ``` |
13 | //! | 13 | //! |
14 | //! and in the code under test you write | 14 | //! and in the code under test you write |
15 | //! | 15 | //! |
16 | //! ``` | 16 | //! ``` |
17 | //! # use test_utils::tested_by; | 17 | //! # use test_utils::mark; |
18 | //! # fn some_condition() -> bool { true } | 18 | //! # fn some_condition() -> bool { true } |
19 | //! fn foo() { | 19 | //! fn foo() { |
20 | //! if some_condition() { | 20 | //! if some_condition() { |
21 | //! tested_by!(test_foo); | 21 | //! mark::hit!(test_foo); |
22 | //! } | 22 | //! } |
23 | //! } | 23 | //! } |
24 | //! ``` | 24 | //! ``` |
@@ -29,43 +29,31 @@ | |||
29 | use std::sync::atomic::{AtomicUsize, Ordering}; | 29 | use std::sync::atomic::{AtomicUsize, Ordering}; |
30 | 30 | ||
31 | #[macro_export] | 31 | #[macro_export] |
32 | macro_rules! tested_by { | 32 | macro_rules! _hit { |
33 | ($ident:ident; force) => {{ | ||
34 | { | ||
35 | // sic! use call-site crate | ||
36 | crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst); | ||
37 | } | ||
38 | }}; | ||
39 | ($ident:ident) => {{ | 33 | ($ident:ident) => {{ |
40 | #[cfg(test)] | 34 | #[cfg(test)] |
41 | { | 35 | { |
42 | // sic! use call-site crate | 36 | extern "C" { |
43 | crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst); | 37 | #[no_mangle] |
38 | static $ident: std::sync::atomic::AtomicUsize; | ||
39 | } | ||
40 | unsafe { | ||
41 | $ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst); | ||
42 | } | ||
44 | } | 43 | } |
45 | }}; | 44 | }}; |
46 | } | 45 | } |
46 | pub use _hit as hit; | ||
47 | 47 | ||
48 | #[macro_export] | 48 | #[macro_export] |
49 | macro_rules! covers { | 49 | macro_rules! _check { |
50 | // sic! use call-site crate | ||
51 | ($ident:ident) => { | 50 | ($ident:ident) => { |
52 | $crate::covers!(crate::$ident) | 51 | #[no_mangle] |
53 | }; | 52 | static $ident: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); |
54 | ($krate:ident :: $ident:ident) => { | 53 | let _checker = $crate::mark::MarkChecker::new(&$ident); |
55 | let _checker = $crate::marks::MarkChecker::new(&$krate::marks::$ident); | ||
56 | }; | ||
57 | } | ||
58 | |||
59 | #[macro_export] | ||
60 | macro_rules! marks { | ||
61 | ($($ident:ident)*) => { | ||
62 | $( | ||
63 | #[allow(bad_style)] | ||
64 | pub static $ident: std::sync::atomic::AtomicUsize = | ||
65 | std::sync::atomic::AtomicUsize::new(0); | ||
66 | )* | ||
67 | }; | 54 | }; |
68 | } | 55 | } |
56 | pub use _check as check; | ||
69 | 57 | ||
70 | pub struct MarkChecker { | 58 | pub struct MarkChecker { |
71 | mark: &'static AtomicUsize, | 59 | mark: &'static AtomicUsize, |