aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-23 22:34:12 +0100
committerGitHub <[email protected]>2020-06-23 22:34:12 +0100
commite2e373e0716cea4ea341c7f381da0d39f484cd30 (patch)
tree0337d53010edd2d5d09ab3ceffb0945b8eb4ae55 /crates
parent846ed08fba1331f1ca8d3512e7536c05784ae4bc (diff)
parentaa69757a01c26cfad12498053c55cbc3d66a4bdb (diff)
Merge #5013
5013: More principled indentation trimming in fixtures r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/add_function.rs1
-rw-r--r--crates/ra_assists/src/handlers/auto_import.rs92
-rw-r--r--crates/ra_assists/src/handlers/fix_visibility.rs157
-rw-r--r--crates/ra_db/src/fixture.rs2
-rw-r--r--crates/ra_ide/src/call_hierarchy.rs172
-rw-r--r--crates/ra_ide/src/completion/complete_macro_in_item_position.rs16
-rw-r--r--crates/ra_ide/src/completion/complete_qualified_path.rs112
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs48
-rw-r--r--crates/ra_ide/src/diagnostics.rs23
-rw-r--r--crates/ra_ide/src/goto_definition.rs146
-rw-r--r--crates/ra_ide/src/hover.rs86
-rw-r--r--crates/ra_ide/src/references.rs16
-rw-r--r--crates/ra_ide/src/runnables.rs16
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/main.rs20
-rw-r--r--crates/stdx/src/lib.rs82
-rw-r--r--crates/test_utils/src/fixture.rs114
-rw-r--r--crates/test_utils/src/lib.rs2
17 files changed, 544 insertions, 561 deletions
diff --git a/crates/ra_assists/src/handlers/add_function.rs b/crates/ra_assists/src/handlers/add_function.rs
index 1cfbd75aa..19ce81d99 100644
--- a/crates/ra_assists/src/handlers/add_function.rs
+++ b/crates/ra_assists/src/handlers/add_function.rs
@@ -986,7 +986,6 @@ fn main() {
986", 986",
987 r" 987 r"
988 988
989
990pub(crate) fn bar() { 989pub(crate) fn bar() {
991 ${0:todo!()} 990 ${0:todo!()}
992}", 991}",
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs
index 5092bf336..d1cafa7d9 100644
--- a/crates/ra_assists/src/handlers/auto_import.rs
+++ b/crates/ra_assists/src/handlers/auto_import.rs
@@ -488,16 +488,17 @@ mod tests {
488 check_assist( 488 check_assist(
489 auto_import, 489 auto_import,
490 r" 490 r"
491 //- /lib.rs crate:crate_with_macro 491//- /lib.rs crate:crate_with_macro
492 #[macro_export] 492#[macro_export]
493 macro_rules! foo { 493macro_rules! foo {
494 () => () 494 () => ()
495 } 495}
496 496
497 //- /main.rs crate:main deps:crate_with_macro 497//- /main.rs crate:main deps:crate_with_macro
498 fn main() { 498fn main() {
499 foo<|> 499 foo<|>
500 }", 500}
501",
501 r"use crate_with_macro::foo; 502 r"use crate_with_macro::foo;
502 503
503fn main() { 504fn main() {
@@ -847,13 +848,14 @@ fn main() {
847 check_assist( 848 check_assist(
848 auto_import, 849 auto_import,
849 r" 850 r"
850 //- /lib.rs crate:dep 851//- /lib.rs crate:dep
851 pub struct Struct; 852pub struct Struct;
852 853
853 //- /main.rs crate:main deps:dep 854//- /main.rs crate:main deps:dep
854 fn main() { 855fn main() {
855 Struct<|> 856 Struct<|>
856 }", 857}
858",
857 r"use dep::Struct; 859 r"use dep::Struct;
858 860
859fn main() { 861fn main() {
@@ -869,20 +871,22 @@ fn main() {
869 check_assist( 871 check_assist(
870 auto_import, 872 auto_import,
871 r" 873 r"
872 //- /lib.rs crate:dep 874//- /lib.rs crate:dep
873 pub mod fmt { 875pub mod fmt {
874 pub trait Display {} 876 pub trait Display {}
875 } 877}
876 878
877 pub fn panic_fmt() {} 879pub fn panic_fmt() {}
878 880
879 //- /main.rs crate:main deps:dep 881//- /main.rs crate:main deps:dep
880 struct S; 882struct S;
881 883
882 impl f<|>mt::Display for S {}", 884impl f<|>mt::Display for S {}
885",
883 r"use dep::fmt; 886 r"use dep::fmt;
884 887
885struct S; 888struct S;
889
886impl fmt::Display for S {} 890impl fmt::Display for S {}
887", 891",
888 ); 892 );
@@ -894,21 +898,20 @@ impl fmt::Display for S {}
894 check_assist( 898 check_assist(
895 auto_import, 899 auto_import,
896 r" 900 r"
897 //- /lib.rs crate:dep 901//- /lib.rs crate:dep
898 902macro_rules! mac {
899 macro_rules! mac { 903 () => {
900 () => { 904 pub struct Cheese;
901 pub struct Cheese; 905 };
902 }; 906}
903 }
904
905 mac!();
906 907
907 //- /main.rs crate:main deps:dep 908mac!();
908 909
909 fn main() { 910//- /main.rs crate:main deps:dep
910 Cheese<|>; 911fn main() {
911 }", 912 Cheese<|>;
913}
914",
912 r"use dep::Cheese; 915 r"use dep::Cheese;
913 916
914fn main() { 917fn main() {
@@ -924,16 +927,15 @@ fn main() {
924 check_assist( 927 check_assist(
925 auto_import, 928 auto_import,
926 r" 929 r"
927 //- /lib.rs crate:dep 930//- /lib.rs crate:dep
928 931pub struct FMT;
929 pub struct FMT; 932pub struct fmt;
930 pub struct fmt;
931
932 //- /main.rs crate:main deps:dep
933 933
934 fn main() { 934//- /main.rs crate:main deps:dep
935 FMT<|>; 935fn main() {
936 }", 936 FMT<|>;
937}
938",
937 r"use dep::FMT; 939 r"use dep::FMT;
938 940
939fn main() { 941fn main() {
diff --git a/crates/ra_assists/src/handlers/fix_visibility.rs b/crates/ra_assists/src/handlers/fix_visibility.rs
index 531b3560f..54601d1f3 100644
--- a/crates/ra_assists/src/handlers/fix_visibility.rs
+++ b/crates/ra_assists/src/handlers/fix_visibility.rs
@@ -255,15 +255,14 @@ mod tests {
255 check_assist( 255 check_assist(
256 fix_visibility, 256 fix_visibility,
257 r" 257 r"
258 //- /main.rs 258//- /main.rs
259 mod foo; 259mod foo;
260 fn main() { foo::Foo<|> } 260fn main() { foo::Foo<|> }
261 261
262 //- /foo.rs 262//- /foo.rs
263 struct Foo; 263struct Foo;
264 ", 264",
265 r"$0pub(crate) struct Foo; 265 r"$0pub(crate) struct Foo;
266
267", 266",
268 ); 267 );
269 } 268 }
@@ -279,14 +278,14 @@ mod tests {
279 ); 278 );
280 check_assist( 279 check_assist(
281 fix_visibility, 280 fix_visibility,
282 r"//- /lib.rs 281 r"
283 mod foo; 282//- /lib.rs
284 fn main() { foo::Foo { <|>bar: () }; } 283mod foo;
285 //- /foo.rs 284fn main() { foo::Foo { <|>bar: () }; }
286 pub struct Foo { bar: () } 285//- /foo.rs
287 ", 286pub struct Foo { bar: () }
287",
288 r"pub struct Foo { $0pub(crate) bar: () } 288 r"pub struct Foo { $0pub(crate) bar: () }
289
290", 289",
291 ); 290 );
292 check_assist_not_applicable( 291 check_assist_not_applicable(
@@ -296,12 +295,13 @@ mod tests {
296 ); 295 );
297 check_assist_not_applicable( 296 check_assist_not_applicable(
298 fix_visibility, 297 fix_visibility,
299 r"//- /lib.rs 298 r"
300 mod foo; 299//- /lib.rs
301 fn main() { foo::Foo { <|>bar: () }; } 300mod foo;
302 //- /foo.rs 301fn main() { foo::Foo { <|>bar: () }; }
303 pub struct Foo { pub bar: () } 302//- /foo.rs
304 ", 303pub struct Foo { pub bar: () }
304",
305 ); 305 );
306 } 306 }
307 307
@@ -316,14 +316,14 @@ mod tests {
316 ); 316 );
317 check_assist( 317 check_assist(
318 fix_visibility, 318 fix_visibility,
319 r"//- /lib.rs 319 r"
320 mod foo; 320//- /lib.rs
321 fn main() { foo::Foo::Bar { <|>bar: () }; } 321mod foo;
322 //- /foo.rs 322fn main() { foo::Foo::Bar { <|>bar: () }; }
323 pub enum Foo { Bar { bar: () } } 323//- /foo.rs
324 ", 324pub enum Foo { Bar { bar: () } }
325",
325 r"pub enum Foo { Bar { $0pub(crate) bar: () } } 326 r"pub enum Foo { Bar { $0pub(crate) bar: () } }
326
327", 327",
328 ); 328 );
329 check_assist_not_applicable( 329 check_assist_not_applicable(
@@ -333,12 +333,13 @@ mod tests {
333 ); 333 );
334 check_assist_not_applicable( 334 check_assist_not_applicable(
335 fix_visibility, 335 fix_visibility,
336 r"//- /lib.rs 336 r"
337 mod foo; 337//- /lib.rs
338 fn main() { foo::Foo { <|>bar: () }; } 338mod foo;
339 //- /foo.rs 339fn main() { foo::Foo { <|>bar: () }; }
340 pub struct Foo { pub bar: () } 340//- /foo.rs
341 ", 341pub struct Foo { pub bar: () }
342",
342 ); 343 );
343 } 344 }
344 345
@@ -355,14 +356,14 @@ mod tests {
355 ); 356 );
356 check_assist( 357 check_assist(
357 fix_visibility, 358 fix_visibility,
358 r"//- /lib.rs 359 r"
359 mod foo; 360//- /lib.rs
360 fn main() { foo::Foo { <|>bar: () }; } 361mod foo;
361 //- /foo.rs 362fn main() { foo::Foo { <|>bar: () }; }
362 pub union Foo { bar: () } 363//- /foo.rs
363 ", 364pub union Foo { bar: () }
365",
364 r"pub union Foo { $0pub(crate) bar: () } 366 r"pub union Foo { $0pub(crate) bar: () }
365
366", 367",
367 ); 368 );
368 check_assist_not_applicable( 369 check_assist_not_applicable(
@@ -372,12 +373,13 @@ mod tests {
372 ); 373 );
373 check_assist_not_applicable( 374 check_assist_not_applicable(
374 fix_visibility, 375 fix_visibility,
375 r"//- /lib.rs 376 r"
376 mod foo; 377//- /lib.rs
377 fn main() { foo::Foo { <|>bar: () }; } 378mod foo;
378 //- /foo.rs 379fn main() { foo::Foo { <|>bar: () }; }
379 pub union Foo { pub bar: () } 380//- /foo.rs
380 ", 381pub union Foo { pub bar: () }
382",
381 ); 383 );
382 } 384 }
383 385
@@ -458,19 +460,18 @@ mod tests {
458 check_assist( 460 check_assist(
459 fix_visibility, 461 fix_visibility,
460 r" 462 r"
461 //- /main.rs 463//- /main.rs
462 mod foo; 464mod foo;
463 fn main() { foo::bar<|>::baz(); } 465fn main() { foo::bar<|>::baz(); }
464 466
465 //- /foo.rs 467//- /foo.rs
466 mod bar { 468mod bar {
467 pub fn baz() {} 469 pub fn baz() {}
468 } 470}
469 ", 471",
470 r"$0pub(crate) mod bar { 472 r"$0pub(crate) mod bar {
471 pub fn baz() {} 473 pub fn baz() {}
472} 474}
473
474", 475",
475 ); 476 );
476 477
@@ -486,17 +487,15 @@ mod tests {
486 check_assist( 487 check_assist(
487 fix_visibility, 488 fix_visibility,
488 r" 489 r"
489 //- /main.rs 490//- /main.rs
490 mod foo; 491mod foo;
491 fn main() { foo::bar<|>::baz(); } 492fn main() { foo::bar<|>::baz(); }
492 493
493 //- /foo.rs 494//- /foo.rs
494 mod bar; 495mod bar;
495 496//- /foo/bar.rs
496 //- /foo/bar.rs 497pub fn baz() {}
497 pub fn baz() {} 498",
498 }
499 ",
500 r"$0pub(crate) mod bar; 499 r"$0pub(crate) mod bar;
501", 500",
502 ); 501 );
@@ -506,14 +505,16 @@ mod tests {
506 fn fix_visibility_of_module_declaration_in_other_file() { 505 fn fix_visibility_of_module_declaration_in_other_file() {
507 check_assist( 506 check_assist(
508 fix_visibility, 507 fix_visibility,
509 r"//- /main.rs 508 r"
510 mod foo; 509//- /main.rs
511 fn main() { foo::bar<|>>::baz(); } 510mod foo;
511fn main() { foo::bar<|>>::baz(); }
512 512
513 //- /foo.rs 513//- /foo.rs
514 mod bar { 514mod bar {
515 pub fn baz() {} 515 pub fn baz() {}
516 }", 516}
517",
517 r"$0pub(crate) mod bar { 518 r"$0pub(crate) mod bar {
518 pub fn baz() {} 519 pub fn baz() {}
519} 520}
@@ -525,10 +526,12 @@ mod tests {
525 fn adds_pub_when_target_is_in_another_crate() { 526 fn adds_pub_when_target_is_in_another_crate() {
526 check_assist( 527 check_assist(
527 fix_visibility, 528 fix_visibility,
528 r"//- /main.rs crate:a deps:foo 529 r"
529 foo::Bar<|> 530//- /main.rs crate:a deps:foo
530 //- /lib.rs crate:foo 531foo::Bar<|>
531 struct Bar;", 532//- /lib.rs crate:foo
533struct Bar;
534",
532 r"$0pub struct Bar; 535 r"$0pub struct Bar;
533", 536",
534 ) 537 )
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 20f291568..3959d7efe 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -110,7 +110,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
110 let source_root = SourceRoot::new_local(file_set); 110 let source_root = SourceRoot::new_local(file_set);
111 111
112 let crate_graph = if let Some(meta) = ra_fixture.lines().find(|it| it.contains("//-")) { 112 let crate_graph = if let Some(meta) = ra_fixture.lines().find(|it| it.contains("//-")) {
113 let entry = Fixture::parse_single(meta.trim()); 113 let entry = Fixture::parse_meta_line(meta.trim());
114 let meta = match ParsedMeta::from(&entry) { 114 let meta = match ParsedMeta::from(&entry) {
115 ParsedMeta::File(it) => it, 115 ParsedMeta::File(it) => it,
116 }; 116 };
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
index defd8176f..1e3a31602 100644
--- a/crates/ra_ide/src/call_hierarchy.rs
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -145,12 +145,12 @@ mod tests {
145 use crate::mock_analysis::analysis_and_position; 145 use crate::mock_analysis::analysis_and_position;
146 146
147 fn check_hierarchy( 147 fn check_hierarchy(
148 fixture: &str, 148 ra_fixture: &str,
149 expected: &str, 149 expected: &str,
150 expected_incoming: &[&str], 150 expected_incoming: &[&str],
151 expected_outgoing: &[&str], 151 expected_outgoing: &[&str],
152 ) { 152 ) {
153 let (analysis, pos) = analysis_and_position(fixture); 153 let (analysis, pos) = analysis_and_position(ra_fixture);
154 154
155 let mut navs = analysis.call_hierarchy(pos).unwrap().unwrap().info; 155 let mut navs = analysis.call_hierarchy(pos).unwrap().unwrap().info;
156 assert_eq!(navs.len(), 1); 156 assert_eq!(navs.len(), 1);
@@ -177,12 +177,12 @@ mod tests {
177 fn test_call_hierarchy_on_ref() { 177 fn test_call_hierarchy_on_ref() {
178 check_hierarchy( 178 check_hierarchy(
179 r#" 179 r#"
180 //- /lib.rs 180//- /lib.rs
181 fn callee() {} 181fn callee() {}
182 fn caller() { 182fn caller() {
183 call<|>ee(); 183 call<|>ee();
184 } 184}
185 "#, 185"#,
186 "callee FN_DEF FileId(1) 0..14 3..9", 186 "callee FN_DEF FileId(1) 0..14 3..9",
187 &["caller FN_DEF FileId(1) 15..44 18..24 : [33..39]"], 187 &["caller FN_DEF FileId(1) 15..44 18..24 : [33..39]"],
188 &[], 188 &[],
@@ -193,12 +193,12 @@ mod tests {
193 fn test_call_hierarchy_on_def() { 193 fn test_call_hierarchy_on_def() {
194 check_hierarchy( 194 check_hierarchy(
195 r#" 195 r#"
196 //- /lib.rs 196//- /lib.rs
197 fn call<|>ee() {} 197fn call<|>ee() {}
198 fn caller() { 198fn caller() {
199 callee(); 199 callee();
200 } 200}
201 "#, 201"#,
202 "callee FN_DEF FileId(1) 0..14 3..9", 202 "callee FN_DEF FileId(1) 0..14 3..9",
203 &["caller FN_DEF FileId(1) 15..44 18..24 : [33..39]"], 203 &["caller FN_DEF FileId(1) 15..44 18..24 : [33..39]"],
204 &[], 204 &[],
@@ -209,13 +209,13 @@ mod tests {
209 fn test_call_hierarchy_in_same_fn() { 209 fn test_call_hierarchy_in_same_fn() {
210 check_hierarchy( 210 check_hierarchy(
211 r#" 211 r#"
212 //- /lib.rs 212//- /lib.rs
213 fn callee() {} 213fn callee() {}
214 fn caller() { 214fn caller() {
215 call<|>ee(); 215 call<|>ee();
216 callee(); 216 callee();
217 } 217}
218 "#, 218"#,
219 "callee FN_DEF FileId(1) 0..14 3..9", 219 "callee FN_DEF FileId(1) 0..14 3..9",
220 &["caller FN_DEF FileId(1) 15..58 18..24 : [33..39, 47..53]"], 220 &["caller FN_DEF FileId(1) 15..58 18..24 : [33..39, 47..53]"],
221 &[], 221 &[],
@@ -226,20 +226,20 @@ mod tests {
226 fn test_call_hierarchy_in_different_fn() { 226 fn test_call_hierarchy_in_different_fn() {
227 check_hierarchy( 227 check_hierarchy(
228 r#" 228 r#"
229 //- /lib.rs 229//- /lib.rs
230 fn callee() {} 230fn callee() {}
231 fn caller1() { 231fn caller1() {
232 call<|>ee(); 232 call<|>ee();
233 } 233}
234 234
235 fn caller2() { 235fn caller2() {
236 callee(); 236 callee();
237 } 237}
238 "#, 238"#,
239 "callee FN_DEF FileId(1) 0..14 3..9", 239 "callee FN_DEF FileId(1) 0..14 3..9",
240 &[ 240 &[
241 "caller1 FN_DEF FileId(1) 15..45 18..25 : [34..40]", 241 "caller1 FN_DEF FileId(1) 15..45 18..25 : [34..40]",
242 "caller2 FN_DEF FileId(1) 46..76 49..56 : [65..71]", 242 "caller2 FN_DEF FileId(1) 47..77 50..57 : [66..72]",
243 ], 243 ],
244 &[], 244 &[],
245 ); 245 );
@@ -249,26 +249,26 @@ mod tests {
249 fn test_call_hierarchy_in_tests_mod() { 249 fn test_call_hierarchy_in_tests_mod() {
250 check_hierarchy( 250 check_hierarchy(
251 r#" 251 r#"
252 //- /lib.rs cfg:test 252//- /lib.rs cfg:test
253 fn callee() {} 253fn callee() {}
254 fn caller1() { 254fn caller1() {
255 call<|>ee(); 255 call<|>ee();
256 } 256}
257 257
258 #[cfg(test)] 258#[cfg(test)]
259 mod tests { 259mod tests {
260 use super::*; 260 use super::*;
261 261
262 #[test] 262 #[test]
263 fn test_caller() { 263 fn test_caller() {
264 callee(); 264 callee();
265 } 265 }
266 } 266}
267 "#, 267"#,
268 "callee FN_DEF FileId(1) 0..14 3..9", 268 "callee FN_DEF FileId(1) 0..14 3..9",
269 &[ 269 &[
270 "caller1 FN_DEF FileId(1) 15..45 18..25 : [34..40]", 270 "caller1 FN_DEF FileId(1) 15..45 18..25 : [34..40]",
271 "test_caller FN_DEF FileId(1) 93..147 108..119 : [132..138]", 271 "test_caller FN_DEF FileId(1) 95..149 110..121 : [134..140]",
272 ], 272 ],
273 &[], 273 &[],
274 ); 274 );
@@ -278,19 +278,19 @@ mod tests {
278 fn test_call_hierarchy_in_different_files() { 278 fn test_call_hierarchy_in_different_files() {
279 check_hierarchy( 279 check_hierarchy(
280 r#" 280 r#"
281 //- /lib.rs 281//- /lib.rs
282 mod foo; 282mod foo;
283 use foo::callee; 283use foo::callee;
284 284
285 fn caller() { 285fn caller() {
286 call<|>ee(); 286 call<|>ee();
287 } 287}
288 288
289 //- /foo/mod.rs 289//- /foo/mod.rs
290 pub fn callee() {} 290pub fn callee() {}
291 "#, 291"#,
292 "callee FN_DEF FileId(2) 0..18 7..13", 292 "callee FN_DEF FileId(2) 0..18 7..13",
293 &["caller FN_DEF FileId(1) 26..55 29..35 : [44..50]"], 293 &["caller FN_DEF FileId(1) 27..56 30..36 : [45..51]"],
294 &[], 294 &[],
295 ); 295 );
296 } 296 }
@@ -299,13 +299,13 @@ mod tests {
299 fn test_call_hierarchy_outgoing() { 299 fn test_call_hierarchy_outgoing() {
300 check_hierarchy( 300 check_hierarchy(
301 r#" 301 r#"
302 //- /lib.rs 302//- /lib.rs
303 fn callee() {} 303fn callee() {}
304 fn call<|>er() { 304fn call<|>er() {
305 callee(); 305 callee();
306 callee(); 306 callee();
307 } 307}
308 "#, 308"#,
309 "caller FN_DEF FileId(1) 15..58 18..24", 309 "caller FN_DEF FileId(1) 15..58 18..24",
310 &[], 310 &[],
311 &["callee FN_DEF FileId(1) 0..14 3..9 : [33..39, 47..53]"], 311 &["callee FN_DEF FileId(1) 0..14 3..9 : [33..39, 47..53]"],
@@ -316,20 +316,20 @@ mod tests {
316 fn test_call_hierarchy_outgoing_in_different_files() { 316 fn test_call_hierarchy_outgoing_in_different_files() {
317 check_hierarchy( 317 check_hierarchy(
318 r#" 318 r#"
319 //- /lib.rs 319//- /lib.rs
320 mod foo; 320mod foo;
321 use foo::callee; 321use foo::callee;
322 322
323 fn call<|>er() { 323fn call<|>er() {
324 callee(); 324 callee();
325 } 325}
326 326
327 //- /foo/mod.rs 327//- /foo/mod.rs
328 pub fn callee() {} 328pub fn callee() {}
329 "#, 329"#,
330 "caller FN_DEF FileId(1) 26..55 29..35", 330 "caller FN_DEF FileId(1) 27..56 30..36",
331 &[], 331 &[],
332 &["callee FN_DEF FileId(2) 0..18 7..13 : [44..50]"], 332 &["callee FN_DEF FileId(2) 0..18 7..13 : [45..51]"],
333 ); 333 );
334 } 334 }
335 335
@@ -337,22 +337,22 @@ mod tests {
337 fn test_call_hierarchy_incoming_outgoing() { 337 fn test_call_hierarchy_incoming_outgoing() {
338 check_hierarchy( 338 check_hierarchy(
339 r#" 339 r#"
340 //- /lib.rs 340//- /lib.rs
341 fn caller1() { 341fn caller1() {
342 call<|>er2(); 342 call<|>er2();
343 } 343}
344 344
345 fn caller2() { 345fn caller2() {
346 caller3(); 346 caller3();
347 } 347}
348 348
349 fn caller3() { 349fn caller3() {
350 350
351 } 351}
352 "#, 352"#,
353 "caller2 FN_DEF FileId(1) 32..63 35..42", 353 "caller2 FN_DEF FileId(1) 33..64 36..43",
354 &["caller1 FN_DEF FileId(1) 0..31 3..10 : [19..26]"], 354 &["caller1 FN_DEF FileId(1) 0..31 3..10 : [19..26]"],
355 &["caller3 FN_DEF FileId(1) 64..80 67..74 : [51..58]"], 355 &["caller3 FN_DEF FileId(1) 66..83 69..76 : [52..59]"],
356 ); 356 );
357 } 357 }
358} 358}
diff --git a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs
index d9bb5fd25..4c33f41d4 100644
--- a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs
+++ b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs
@@ -42,8 +42,8 @@ mod tests {
42 [ 42 [
43 CompletionItem { 43 CompletionItem {
44 label: "foo!(…)", 44 label: "foo!(…)",
45 source_range: 46..46, 45 source_range: 48..48,
46 delete: 46..46, 46 delete: 48..48,
47 insert: "foo!($0)", 47 insert: "foo!($0)",
48 kind: Macro, 48 kind: Macro,
49 detail: "macro_rules! foo", 49 detail: "macro_rules! foo",
@@ -82,8 +82,8 @@ mod tests {
82 [ 82 [
83 CompletionItem { 83 CompletionItem {
84 label: "vec![…]", 84 label: "vec![…]",
85 source_range: 280..280, 85 source_range: 282..282,
86 delete: 280..280, 86 delete: 282..282,
87 insert: "vec![$0]", 87 insert: "vec![$0]",
88 kind: Macro, 88 kind: Macro,
89 detail: "macro_rules! vec", 89 detail: "macro_rules! vec",
@@ -119,8 +119,8 @@ mod tests {
119 [ 119 [
120 CompletionItem { 120 CompletionItem {
121 label: "foo! {…}", 121 label: "foo! {…}",
122 source_range: 163..163, 122 source_range: 164..164,
123 delete: 163..163, 123 delete: 164..164,
124 insert: "foo! {$0}", 124 insert: "foo! {$0}",
125 kind: Macro, 125 kind: Macro,
126 detail: "macro_rules! foo", 126 detail: "macro_rules! foo",
@@ -130,8 +130,8 @@ mod tests {
130 }, 130 },
131 CompletionItem { 131 CompletionItem {
132 label: "main()", 132 label: "main()",
133 source_range: 163..163, 133 source_range: 164..164,
134 delete: 163..163, 134 delete: 164..164,
135 insert: "main()$0", 135 insert: "main()$0",
136 kind: Function, 136 kind: Function,
137 lookup: "main", 137 lookup: "main",
diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs
index 02ac0166b..d3a1cbc1d 100644
--- a/crates/ra_ide/src/completion/complete_qualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_qualified_path.rs
@@ -541,8 +541,8 @@ mod tests {
541 [ 541 [
542 CompletionItem { 542 CompletionItem {
543 label: "m()", 543 label: "m()",
544 source_range: 100..100, 544 source_range: 102..102,
545 delete: 100..100, 545 delete: 102..102,
546 insert: "m()$0", 546 insert: "m()$0",
547 kind: Function, 547 kind: Function,
548 lookup: "m", 548 lookup: "m",
@@ -577,8 +577,8 @@ mod tests {
577 [ 577 [
578 CompletionItem { 578 CompletionItem {
579 label: "m()", 579 label: "m()",
580 source_range: 105..105, 580 source_range: 107..107,
581 delete: 105..105, 581 delete: 107..107,
582 insert: "m()$0", 582 insert: "m()$0",
583 kind: Method, 583 kind: Method,
584 lookup: "m", 584 lookup: "m",
@@ -613,8 +613,8 @@ mod tests {
613 [ 613 [
614 CompletionItem { 614 CompletionItem {
615 label: "C", 615 label: "C",
616 source_range: 107..107, 616 source_range: 109..109,
617 delete: 107..107, 617 delete: 109..109,
618 insert: "C", 618 insert: "C",
619 kind: Const, 619 kind: Const,
620 detail: "const C: i32 = 42;", 620 detail: "const C: i32 = 42;",
@@ -648,8 +648,8 @@ mod tests {
648 [ 648 [
649 CompletionItem { 649 CompletionItem {
650 label: "T", 650 label: "T",
651 source_range: 101..101, 651 source_range: 103..103,
652 delete: 101..101, 652 delete: 103..103,
653 insert: "T", 653 insert: "T",
654 kind: TypeAlias, 654 kind: TypeAlias,
655 detail: "type T = i32;", 655 detail: "type T = i32;",
@@ -688,24 +688,24 @@ mod tests {
688 [ 688 [
689 CompletionItem { 689 CompletionItem {
690 label: "PUBLIC_CONST", 690 label: "PUBLIC_CONST",
691 source_range: 302..302, 691 source_range: 304..304,
692 delete: 302..302, 692 delete: 304..304,
693 insert: "PUBLIC_CONST", 693 insert: "PUBLIC_CONST",
694 kind: Const, 694 kind: Const,
695 detail: "pub(super) const PUBLIC_CONST: u32 = 1;", 695 detail: "pub(super) const PUBLIC_CONST: u32 = 1;",
696 }, 696 },
697 CompletionItem { 697 CompletionItem {
698 label: "PublicType", 698 label: "PublicType",
699 source_range: 302..302, 699 source_range: 304..304,
700 delete: 302..302, 700 delete: 304..304,
701 insert: "PublicType", 701 insert: "PublicType",
702 kind: TypeAlias, 702 kind: TypeAlias,
703 detail: "pub(super) type PublicType = u32;", 703 detail: "pub(super) type PublicType = u32;",
704 }, 704 },
705 CompletionItem { 705 CompletionItem {
706 label: "public_method()", 706 label: "public_method()",
707 source_range: 302..302, 707 source_range: 304..304,
708 delete: 302..302, 708 delete: 304..304,
709 insert: "public_method()$0", 709 insert: "public_method()$0",
710 kind: Function, 710 kind: Function,
711 lookup: "public_method", 711 lookup: "public_method",
@@ -737,8 +737,8 @@ mod tests {
737 [ 737 [
738 CompletionItem { 738 CompletionItem {
739 label: "m()", 739 label: "m()",
740 source_range: 100..100, 740 source_range: 102..102,
741 delete: 100..100, 741 delete: 102..102,
742 insert: "m()$0", 742 insert: "m()$0",
743 kind: Function, 743 kind: Function,
744 lookup: "m", 744 lookup: "m",
@@ -773,8 +773,8 @@ mod tests {
773 [ 773 [
774 CompletionItem { 774 CompletionItem {
775 label: "m()", 775 label: "m()",
776 source_range: 101..101, 776 source_range: 103..103,
777 delete: 101..101, 777 delete: 103..103,
778 insert: "m()$0", 778 insert: "m()$0",
779 kind: Function, 779 kind: Function,
780 lookup: "m", 780 lookup: "m",
@@ -834,8 +834,8 @@ mod tests {
834 [ 834 [
835 CompletionItem { 835 CompletionItem {
836 label: "m()", 836 label: "m()",
837 source_range: 73..73, 837 source_range: 74..74,
838 delete: 73..73, 838 delete: 74..74,
839 insert: "m()$0", 839 insert: "m()$0",
840 kind: Function, 840 kind: Function,
841 lookup: "m", 841 lookup: "m",
@@ -870,8 +870,8 @@ mod tests {
870 [ 870 [
871 CompletionItem { 871 CompletionItem {
872 label: "m()", 872 label: "m()",
873 source_range: 99..99, 873 source_range: 101..101,
874 delete: 99..99, 874 delete: 101..101,
875 insert: "m()$0", 875 insert: "m()$0",
876 kind: Function, 876 kind: Function,
877 lookup: "m", 877 lookup: "m",
@@ -906,8 +906,8 @@ mod tests {
906 [ 906 [
907 CompletionItem { 907 CompletionItem {
908 label: "m()", 908 label: "m()",
909 source_range: 110..110, 909 source_range: 112..112,
910 delete: 110..110, 910 delete: 112..112,
911 insert: "m()$0", 911 insert: "m()$0",
912 kind: Function, 912 kind: Function,
913 lookup: "m", 913 lookup: "m",
@@ -950,40 +950,40 @@ mod tests {
950 [ 950 [
951 CompletionItem { 951 CompletionItem {
952 label: "C2", 952 label: "C2",
953 source_range: 219..219, 953 source_range: 221..221,
954 delete: 219..219, 954 delete: 221..221,
955 insert: "C2", 955 insert: "C2",
956 kind: Const, 956 kind: Const,
957 detail: "const C2: ();", 957 detail: "const C2: ();",
958 }, 958 },
959 CompletionItem { 959 CompletionItem {
960 label: "CONST", 960 label: "CONST",
961 source_range: 219..219, 961 source_range: 221..221,
962 delete: 219..219, 962 delete: 221..221,
963 insert: "CONST", 963 insert: "CONST",
964 kind: Const, 964 kind: Const,
965 detail: "const CONST: u8;", 965 detail: "const CONST: u8;",
966 }, 966 },
967 CompletionItem { 967 CompletionItem {
968 label: "SubTy", 968 label: "SubTy",
969 source_range: 219..219, 969 source_range: 221..221,
970 delete: 219..219, 970 delete: 221..221,
971 insert: "SubTy", 971 insert: "SubTy",
972 kind: TypeAlias, 972 kind: TypeAlias,
973 detail: "type SubTy;", 973 detail: "type SubTy;",
974 }, 974 },
975 CompletionItem { 975 CompletionItem {
976 label: "Ty", 976 label: "Ty",
977 source_range: 219..219, 977 source_range: 221..221,
978 delete: 219..219, 978 delete: 221..221,
979 insert: "Ty", 979 insert: "Ty",
980 kind: TypeAlias, 980 kind: TypeAlias,
981 detail: "type Ty;", 981 detail: "type Ty;",
982 }, 982 },
983 CompletionItem { 983 CompletionItem {
984 label: "func()", 984 label: "func()",
985 source_range: 219..219, 985 source_range: 221..221,
986 delete: 219..219, 986 delete: 221..221,
987 insert: "func()$0", 987 insert: "func()$0",
988 kind: Function, 988 kind: Function,
989 lookup: "func", 989 lookup: "func",
@@ -991,8 +991,8 @@ mod tests {
991 }, 991 },
992 CompletionItem { 992 CompletionItem {
993 label: "method()", 993 label: "method()",
994 source_range: 219..219, 994 source_range: 221..221,
995 delete: 219..219, 995 delete: 221..221,
996 insert: "method()$0", 996 insert: "method()$0",
997 kind: Method, 997 kind: Method,
998 lookup: "method", 998 lookup: "method",
@@ -1000,8 +1000,8 @@ mod tests {
1000 }, 1000 },
1001 CompletionItem { 1001 CompletionItem {
1002 label: "subfunc()", 1002 label: "subfunc()",
1003 source_range: 219..219, 1003 source_range: 221..221,
1004 delete: 219..219, 1004 delete: 221..221,
1005 insert: "subfunc()$0", 1005 insert: "subfunc()$0",
1006 kind: Function, 1006 kind: Function,
1007 lookup: "subfunc", 1007 lookup: "subfunc",
@@ -1009,8 +1009,8 @@ mod tests {
1009 }, 1009 },
1010 CompletionItem { 1010 CompletionItem {
1011 label: "submethod()", 1011 label: "submethod()",
1012 source_range: 219..219, 1012 source_range: 221..221,
1013 delete: 219..219, 1013 delete: 221..221,
1014 insert: "submethod()$0", 1014 insert: "submethod()$0",
1015 kind: Method, 1015 kind: Method,
1016 lookup: "submethod", 1016 lookup: "submethod",
@@ -1055,40 +1055,40 @@ mod tests {
1055 [ 1055 [
1056 CompletionItem { 1056 CompletionItem {
1057 label: "C2", 1057 label: "C2",
1058 source_range: 365..365, 1058 source_range: 367..367,
1059 delete: 365..365, 1059 delete: 367..367,
1060 insert: "C2", 1060 insert: "C2",
1061 kind: Const, 1061 kind: Const,
1062 detail: "const C2: () = ();", 1062 detail: "const C2: () = ();",
1063 }, 1063 },
1064 CompletionItem { 1064 CompletionItem {
1065 label: "CONST", 1065 label: "CONST",
1066 source_range: 365..365, 1066 source_range: 367..367,
1067 delete: 365..365, 1067 delete: 367..367,
1068 insert: "CONST", 1068 insert: "CONST",
1069 kind: Const, 1069 kind: Const,
1070 detail: "const CONST: u8 = 0;", 1070 detail: "const CONST: u8 = 0;",
1071 }, 1071 },
1072 CompletionItem { 1072 CompletionItem {
1073 label: "SubTy", 1073 label: "SubTy",
1074 source_range: 365..365, 1074 source_range: 367..367,
1075 delete: 365..365, 1075 delete: 367..367,
1076 insert: "SubTy", 1076 insert: "SubTy",
1077 kind: TypeAlias, 1077 kind: TypeAlias,
1078 detail: "type SubTy;", 1078 detail: "type SubTy;",
1079 }, 1079 },
1080 CompletionItem { 1080 CompletionItem {
1081 label: "Ty", 1081 label: "Ty",
1082 source_range: 365..365, 1082 source_range: 367..367,
1083 delete: 365..365, 1083 delete: 367..367,
1084 insert: "Ty", 1084 insert: "Ty",
1085 kind: TypeAlias, 1085 kind: TypeAlias,
1086 detail: "type Ty;", 1086 detail: "type Ty;",
1087 }, 1087 },
1088 CompletionItem { 1088 CompletionItem {
1089 label: "func()", 1089 label: "func()",
1090 source_range: 365..365, 1090 source_range: 367..367,
1091 delete: 365..365, 1091 delete: 367..367,
1092 insert: "func()$0", 1092 insert: "func()$0",
1093 kind: Function, 1093 kind: Function,
1094 lookup: "func", 1094 lookup: "func",
@@ -1096,8 +1096,8 @@ mod tests {
1096 }, 1096 },
1097 CompletionItem { 1097 CompletionItem {
1098 label: "method()", 1098 label: "method()",
1099 source_range: 365..365, 1099 source_range: 367..367,
1100 delete: 365..365, 1100 delete: 367..367,
1101 insert: "method()$0", 1101 insert: "method()$0",
1102 kind: Method, 1102 kind: Method,
1103 lookup: "method", 1103 lookup: "method",
@@ -1105,8 +1105,8 @@ mod tests {
1105 }, 1105 },
1106 CompletionItem { 1106 CompletionItem {
1107 label: "subfunc()", 1107 label: "subfunc()",
1108 source_range: 365..365, 1108 source_range: 367..367,
1109 delete: 365..365, 1109 delete: 367..367,
1110 insert: "subfunc()$0", 1110 insert: "subfunc()$0",
1111 kind: Function, 1111 kind: Function,
1112 lookup: "subfunc", 1112 lookup: "subfunc",
@@ -1114,8 +1114,8 @@ mod tests {
1114 }, 1114 },
1115 CompletionItem { 1115 CompletionItem {
1116 label: "submethod()", 1116 label: "submethod()",
1117 source_range: 365..365, 1117 source_range: 367..367,
1118 delete: 365..365, 1118 delete: 367..367,
1119 insert: "submethod()$0", 1119 insert: "submethod()$0",
1120 kind: Method, 1120 kind: Method,
1121 lookup: "submethod", 1121 lookup: "submethod",
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs
index 68032c37e..aa2b07a2f 100644
--- a/crates/ra_ide/src/completion/complete_unqualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs
@@ -781,46 +781,46 @@ mod tests {
781 [ 781 [
782 CompletionItem { 782 CompletionItem {
783 label: "bar!(…)", 783 label: "bar!(…)",
784 source_range: 252..252, 784 source_range: 256..256,
785 delete: 252..252, 785 delete: 256..256,
786 insert: "bar!($0)", 786 insert: "bar!($0)",
787 kind: Macro, 787 kind: Macro,
788 detail: "macro_rules! bar", 788 detail: "macro_rules! bar",
789 }, 789 },
790 CompletionItem { 790 CompletionItem {
791 label: "baz!(…)", 791 label: "baz!(…)",
792 source_range: 252..252, 792 source_range: 256..256,
793 delete: 252..252, 793 delete: 256..256,
794 insert: "baz!($0)", 794 insert: "baz!($0)",
795 kind: Macro, 795 kind: Macro,
796 detail: "#[macro_export]\nmacro_rules! baz", 796 detail: "#[macro_export]\nmacro_rules! baz",
797 }, 797 },
798 CompletionItem { 798 CompletionItem {
799 label: "foo!(…)", 799 label: "foo!(…)",
800 source_range: 252..252, 800 source_range: 256..256,
801 delete: 252..252, 801 delete: 256..256,
802 insert: "foo!($0)", 802 insert: "foo!($0)",
803 kind: Macro, 803 kind: Macro,
804 detail: "macro_rules! foo", 804 detail: "macro_rules! foo",
805 }, 805 },
806 CompletionItem { 806 CompletionItem {
807 label: "m1", 807 label: "m1",
808 source_range: 252..252, 808 source_range: 256..256,
809 delete: 252..252, 809 delete: 256..256,
810 insert: "m1", 810 insert: "m1",
811 kind: Module, 811 kind: Module,
812 }, 812 },
813 CompletionItem { 813 CompletionItem {
814 label: "m2", 814 label: "m2",
815 source_range: 252..252, 815 source_range: 256..256,
816 delete: 252..252, 816 delete: 256..256,
817 insert: "m2", 817 insert: "m2",
818 kind: Module, 818 kind: Module,
819 }, 819 },
820 CompletionItem { 820 CompletionItem {
821 label: "main()", 821 label: "main()",
822 source_range: 252..252, 822 source_range: 256..256,
823 delete: 252..252, 823 delete: 256..256,
824 insert: "main()$0", 824 insert: "main()$0",
825 kind: Function, 825 kind: Function,
826 lookup: "main", 826 lookup: "main",
@@ -850,16 +850,16 @@ mod tests {
850 [ 850 [
851 CompletionItem { 851 CompletionItem {
852 label: "foo!(…)", 852 label: "foo!(…)",
853 source_range: 49..49, 853 source_range: 50..50,
854 delete: 49..49, 854 delete: 50..50,
855 insert: "foo!($0)", 855 insert: "foo!($0)",
856 kind: Macro, 856 kind: Macro,
857 detail: "macro_rules! foo", 857 detail: "macro_rules! foo",
858 }, 858 },
859 CompletionItem { 859 CompletionItem {
860 label: "foo()", 860 label: "foo()",
861 source_range: 49..49, 861 source_range: 50..50,
862 delete: 49..49, 862 delete: 50..50,
863 insert: "foo()$0", 863 insert: "foo()$0",
864 kind: Function, 864 kind: Function,
865 lookup: "foo", 865 lookup: "foo",
@@ -889,16 +889,16 @@ mod tests {
889 [ 889 [
890 CompletionItem { 890 CompletionItem {
891 label: "foo!(…)", 891 label: "foo!(…)",
892 source_range: 57..57, 892 source_range: 58..58,
893 delete: 57..57, 893 delete: 58..58,
894 insert: "foo!($0)", 894 insert: "foo!($0)",
895 kind: Macro, 895 kind: Macro,
896 detail: "macro_rules! foo", 896 detail: "macro_rules! foo",
897 }, 897 },
898 CompletionItem { 898 CompletionItem {
899 label: "main()", 899 label: "main()",
900 source_range: 57..57, 900 source_range: 58..58,
901 delete: 57..57, 901 delete: 58..58,
902 insert: "main()$0", 902 insert: "main()$0",
903 kind: Function, 903 kind: Function,
904 lookup: "main", 904 lookup: "main",
@@ -928,16 +928,16 @@ mod tests {
928 [ 928 [
929 CompletionItem { 929 CompletionItem {
930 label: "foo!(…)", 930 label: "foo!(…)",
931 source_range: 50..50, 931 source_range: 51..51,
932 delete: 50..50, 932 delete: 51..51,
933 insert: "foo!($0)", 933 insert: "foo!($0)",
934 kind: Macro, 934 kind: Macro,
935 detail: "macro_rules! foo", 935 detail: "macro_rules! foo",
936 }, 936 },
937 CompletionItem { 937 CompletionItem {
938 label: "main()", 938 label: "main()",
939 source_range: 50..50, 939 source_range: 51..51,
940 delete: 50..50, 940 delete: 51..51,
941 insert: "main()$0", 941 insert: "main()$0",
942 kind: Function, 942 kind: Function,
943 lookup: "main", 943 lookup: "main",
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index 9bde1db8e..8cb0700b9 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -283,7 +283,7 @@ fn check_struct_shorthand_initialization(
283mod tests { 283mod tests {
284 use insta::assert_debug_snapshot; 284 use insta::assert_debug_snapshot;
285 use ra_syntax::SourceFile; 285 use ra_syntax::SourceFile;
286 use stdx::SepBy; 286 use stdx::trim_indent;
287 use test_utils::assert_eq_text; 287 use test_utils::assert_eq_text;
288 288
289 use crate::mock_analysis::{analysis_and_position, single_file}; 289 use crate::mock_analysis::{analysis_and_position, single_file};
@@ -325,6 +325,8 @@ mod tests {
325 /// * this diagnostic touches the input cursor position 325 /// * this diagnostic touches the input cursor position
326 /// * that the contents of the file containing the cursor match `after` after the diagnostic fix is applied 326 /// * that the contents of the file containing the cursor match `after` after the diagnostic fix is applied
327 fn check_apply_diagnostic_fix_from_position(fixture: &str, after: &str) { 327 fn check_apply_diagnostic_fix_from_position(fixture: &str, after: &str) {
328 let after = trim_indent(after);
329
328 let (analysis, file_position) = analysis_and_position(fixture); 330 let (analysis, file_position) = analysis_and_position(fixture);
329 let diagnostic = analysis.diagnostics(file_position.file_id).unwrap().pop().unwrap(); 331 let diagnostic = analysis.diagnostics(file_position.file_id).unwrap().pop().unwrap();
330 let mut fix = diagnostic.fix.unwrap(); 332 let mut fix = diagnostic.fix.unwrap();
@@ -336,21 +338,6 @@ mod tests {
336 actual 338 actual
337 }; 339 };
338 340
339 // Strip indent and empty lines from `after`, to match the behaviour of
340 // `parse_fixture` called from `analysis_and_position`.
341 let margin = fixture
342 .lines()
343 .filter(|it| it.trim_start().starts_with("//-"))
344 .map(|it| it.len() - it.trim_start().len())
345 .next()
346 .expect("empty fixture");
347 let after = after
348 .lines()
349 .filter_map(|line| if line.len() > margin { Some(&line[margin..]) } else { None })
350 .sep_by("\n")
351 .suffix("\n")
352 .to_string();
353
354 assert_eq_text!(&after, &actual); 341 assert_eq_text!(&after, &actual);
355 assert!( 342 assert!(
356 diagnostic.range.start() <= file_position.offset 343 diagnostic.range.start() <= file_position.offset
@@ -400,7 +387,6 @@ mod tests {
400 } 387 }
401 x / y<|> 388 x / y<|>
402 } 389 }
403
404 //- /core/lib.rs 390 //- /core/lib.rs
405 pub mod result { 391 pub mod result {
406 pub enum Result<T, E> { Ok(T), Err(E) } 392 pub enum Result<T, E> { Ok(T), Err(E) }
@@ -431,7 +417,6 @@ mod tests {
431 } 417 }
432 <|>x 418 <|>x
433 } 419 }
434
435 //- /core/lib.rs 420 //- /core/lib.rs
436 pub mod result { 421 pub mod result {
437 pub enum Result<T, E> { Ok(T), Err(E) } 422 pub enum Result<T, E> { Ok(T), Err(E) }
@@ -464,7 +449,6 @@ mod tests {
464 } 449 }
465 x <|>/ y 450 x <|>/ y
466 } 451 }
467
468 //- /core/lib.rs 452 //- /core/lib.rs
469 pub mod result { 453 pub mod result {
470 pub enum Result<T, E> { Ok(T), Err(E) } 454 pub enum Result<T, E> { Ok(T), Err(E) }
@@ -474,6 +458,7 @@ mod tests {
474 use core::result::Result::{self, Ok, Err}; 458 use core::result::Result::{self, Ok, Err};
475 459
476 type MyResult<T> = Result<T, ()>; 460 type MyResult<T> = Result<T, ()>;
461
477 fn div(x: i32, y: i32) -> MyResult<i32> { 462 fn div(x: i32, y: i32) -> MyResult<i32> {
478 if y == 0 { 463 if y == 0 {
479 return Err(()); 464 return Err(());
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 450ce0ba7..bea7fbfa7 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -192,27 +192,27 @@ mod tests {
192 #[test] 192 #[test]
193 fn goto_def_for_module_declaration() { 193 fn goto_def_for_module_declaration() {
194 check_goto( 194 check_goto(
195 " 195 r#"
196 //- /lib.rs 196//- /lib.rs
197 mod <|>foo; 197mod <|>foo;
198 198
199 //- /foo.rs 199//- /foo.rs
200 // empty 200// empty
201 ", 201"#,
202 "foo SOURCE_FILE FileId(2) 0..10", 202 "foo SOURCE_FILE FileId(2) 0..9",
203 "// empty\n\n", 203 "// empty\n",
204 ); 204 );
205 205
206 check_goto( 206 check_goto(
207 " 207 r#"
208 //- /lib.rs 208//- /lib.rs
209 mod <|>foo; 209mod <|>foo;
210 210
211 //- /foo/mod.rs 211//- /foo/mod.rs
212 // empty 212// empty
213 ", 213"#,
214 "foo SOURCE_FILE FileId(2) 0..10", 214 "foo SOURCE_FILE FileId(2) 0..9",
215 "// empty\n\n", 215 "// empty\n",
216 ); 216 );
217 } 217 }
218 218
@@ -254,14 +254,14 @@ mod tests {
254 #[test] 254 #[test]
255 fn goto_def_for_use_alias() { 255 fn goto_def_for_use_alias() {
256 check_goto( 256 check_goto(
257 " 257 r#"
258 //- /lib.rs 258//- /lib.rs
259 use foo as bar<|>; 259use foo as bar<|>;
260
261 260
262 //- /foo/lib.rs 261//- /foo/lib.rs
263 #[macro_export] 262#[macro_export]
264 macro_rules! foo { () => { () } }", 263macro_rules! foo { () => { () } }
264"#,
265 "SOURCE_FILE FileId(2) 0..50", 265 "SOURCE_FILE FileId(2) 0..50",
266 "#[macro_export]\nmacro_rules! foo { () => { () } }\n", 266 "#[macro_export]\nmacro_rules! foo { () => { () } }\n",
267 ); 267 );
@@ -302,19 +302,19 @@ mod tests {
302 #[test] 302 #[test]
303 fn goto_def_for_macro_defined_fn_with_arg() { 303 fn goto_def_for_macro_defined_fn_with_arg() {
304 check_goto( 304 check_goto(
305 " 305 r#"
306 //- /lib.rs 306//- /lib.rs
307 macro_rules! define_fn { 307macro_rules! define_fn {
308 ($name:ident) => (fn $name() {}) 308 ($name:ident) => (fn $name() {})
309 } 309}
310 310
311 define_fn!(foo); 311define_fn!(foo);
312 312
313 fn bar() { 313fn bar() {
314 <|>foo(); 314 <|>foo();
315 } 315}
316 ", 316"#,
317 "foo FN_DEF FileId(1) 64..80 75..78", 317 "foo FN_DEF FileId(1) 65..81 76..79",
318 "define_fn!(foo);|foo", 318 "define_fn!(foo);|foo",
319 ); 319 );
320 } 320 }
@@ -322,19 +322,19 @@ mod tests {
322 #[test] 322 #[test]
323 fn goto_def_for_macro_defined_fn_no_arg() { 323 fn goto_def_for_macro_defined_fn_no_arg() {
324 check_goto( 324 check_goto(
325 " 325 r#"
326 //- /lib.rs 326//- /lib.rs
327 macro_rules! define_fn { 327macro_rules! define_fn {
328 () => (fn foo() {}) 328 () => (fn foo() {})
329 } 329}
330 330
331 define_fn!(); 331define_fn!();
332 332
333 fn bar() { 333fn bar() {
334 <|>foo(); 334 <|>foo();
335 } 335}
336 ", 336"#,
337 "foo FN_DEF FileId(1) 51..64 51..64", 337 "foo FN_DEF FileId(1) 52..65 52..65",
338 "define_fn!();|define_fn!();", 338 "define_fn!();|define_fn!();",
339 ); 339 );
340 } 340 }
@@ -804,40 +804,40 @@ mod tests {
804 #[test] 804 #[test]
805 fn goto_within_macro() { 805 fn goto_within_macro() {
806 check_goto( 806 check_goto(
807 " 807 r#"
808 //- /lib.rs 808//- /lib.rs
809 macro_rules! id { 809macro_rules! id {
810 ($($tt:tt)*) => ($($tt)*) 810 ($($tt:tt)*) => ($($tt)*)
811 } 811}
812 812
813 fn foo() { 813fn foo() {
814 let x = 1; 814 let x = 1;
815 id!({ 815 id!({
816 let y = <|>x; 816 let y = <|>x;
817 let z = y; 817 let z = y;
818 }); 818 });
819 } 819}
820 ", 820"#,
821 "x BIND_PAT FileId(1) 69..70", 821 "x BIND_PAT FileId(1) 70..71",
822 "x", 822 "x",
823 ); 823 );
824 824
825 check_goto( 825 check_goto(
826 " 826 r#"
827 //- /lib.rs 827//- /lib.rs
828 macro_rules! id { 828macro_rules! id {
829 ($($tt:tt)*) => ($($tt)*) 829 ($($tt:tt)*) => ($($tt)*)
830 } 830}
831 831
832 fn foo() { 832fn foo() {
833 let x = 1; 833 let x = 1;
834 id!({ 834 id!({
835 let y = x; 835 let y = x;
836 let z = <|>y; 836 let z = <|>y;
837 }); 837 });
838 } 838}
839 ", 839"#,
840 "y BIND_PAT FileId(1) 98..99", 840 "y BIND_PAT FileId(1) 99..100",
841 "y", 841 "y",
842 ); 842 );
843 } 843 }
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index d870e4cbc..a898f2e4a 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -2106,51 +2106,51 @@ fn func(foo: i32) { if true { <|>foo; }; }
2106 ); 2106 );
2107 assert_debug_snapshot!(actions, 2107 assert_debug_snapshot!(actions,
2108 @r###" 2108 @r###"
2109 [ 2109 [
2110 GoToType( 2110 GoToType(
2111 [ 2111 [
2112 HoverGotoTypeData { 2112 HoverGotoTypeData {
2113 mod_path: "B", 2113 mod_path: "B",
2114 nav: NavigationTarget { 2114 nav: NavigationTarget {
2115 file_id: FileId( 2115 file_id: FileId(
2116 1, 2116 1,
2117 ), 2117 ),
2118 full_range: 41..54, 2118 full_range: 42..55,
2119 name: "B", 2119 name: "B",
2120 kind: STRUCT_DEF, 2120 kind: STRUCT_DEF,
2121 focus_range: Some( 2121 focus_range: Some(
2122 48..49, 2122 49..50,
2123 ), 2123 ),
2124 container_name: None, 2124 container_name: None,
2125 description: Some( 2125 description: Some(
2126 "struct B", 2126 "struct B",
2127 ), 2127 ),
2128 docs: None, 2128 docs: None,
2129 },
2130 }, 2129 },
2131 HoverGotoTypeData { 2130 },
2132 mod_path: "Foo", 2131 HoverGotoTypeData {
2133 nav: NavigationTarget { 2132 mod_path: "Foo",
2134 file_id: FileId( 2133 nav: NavigationTarget {
2135 1, 2134 file_id: FileId(
2136 ), 2135 1,
2137 full_range: 0..12, 2136 ),
2138 name: "Foo", 2137 full_range: 0..12,
2139 kind: TRAIT_DEF, 2138 name: "Foo",
2140 focus_range: Some( 2139 kind: TRAIT_DEF,
2141 6..9, 2140 focus_range: Some(
2142 ), 2141 6..9,
2143 container_name: None, 2142 ),
2144 description: Some( 2143 container_name: None,
2145 "trait Foo", 2144 description: Some(
2146 ), 2145 "trait Foo",
2147 docs: None, 2146 ),
2148 }, 2147 docs: None,
2149 }, 2148 },
2150 ], 2149 },
2151 ), 2150 ],
2152 ] 2151 ),
2153 "###); 2152 ]
2153 "###);
2154 } 2154 }
2155 2155
2156 #[test] 2156 #[test]
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index bb40d2043..4a96d6505 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -427,8 +427,8 @@ mod tests {
427 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 427 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
428 check_result( 428 check_result(
429 refs, 429 refs,
430 "Foo STRUCT_DEF FileId(2) 16..50 27..30 Other", 430 "Foo STRUCT_DEF FileId(2) 17..51 28..31 Other",
431 &["FileId(1) 52..55 StructLiteral", "FileId(3) 77..80 StructLiteral"], 431 &["FileId(1) 53..56 StructLiteral", "FileId(3) 79..82 StructLiteral"],
432 ); 432 );
433 } 433 }
434 434
@@ -455,7 +455,7 @@ mod tests {
455 455
456 let (analysis, pos) = analysis_and_position(code); 456 let (analysis, pos) = analysis_and_position(code);
457 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 457 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
458 check_result(refs, "foo SOURCE_FILE FileId(2) 0..35 Other", &["FileId(1) 13..16 Other"]); 458 check_result(refs, "foo SOURCE_FILE FileId(2) 0..35 Other", &["FileId(1) 14..17 Other"]);
459 } 459 }
460 460
461 #[test] 461 #[test]
@@ -483,7 +483,7 @@ mod tests {
483 check_result( 483 check_result(
484 refs, 484 refs,
485 "Foo STRUCT_DEF FileId(3) 0..41 18..21 Other", 485 "Foo STRUCT_DEF FileId(3) 0..41 18..21 Other",
486 &["FileId(2) 20..23 Other", "FileId(2) 46..49 StructLiteral"], 486 &["FileId(2) 20..23 Other", "FileId(2) 47..50 StructLiteral"],
487 ); 487 );
488 } 488 }
489 489
@@ -510,7 +510,7 @@ mod tests {
510 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 510 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
511 check_result( 511 check_result(
512 refs, 512 refs,
513 "quux FN_DEF FileId(1) 18..34 25..29 Other", 513 "quux FN_DEF FileId(1) 19..35 26..30 Other",
514 &["FileId(2) 16..20 StructLiteral", "FileId(3) 16..20 StructLiteral"], 514 &["FileId(2) 16..20 StructLiteral", "FileId(3) 16..20 StructLiteral"],
515 ); 515 );
516 516
@@ -518,7 +518,7 @@ mod tests {
518 analysis.find_all_refs(pos, Some(SearchScope::single_file(bar))).unwrap().unwrap(); 518 analysis.find_all_refs(pos, Some(SearchScope::single_file(bar))).unwrap().unwrap();
519 check_result( 519 check_result(
520 refs, 520 refs,
521 "quux FN_DEF FileId(1) 18..34 25..29 Other", 521 "quux FN_DEF FileId(1) 19..35 26..30 Other",
522 &["FileId(3) 16..20 StructLiteral"], 522 &["FileId(3) 16..20 StructLiteral"],
523 ); 523 );
524 } 524 }
@@ -637,8 +637,8 @@ mod tests {
637 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 637 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
638 check_result( 638 check_result(
639 refs, 639 refs,
640 "f FN_DEF FileId(1) 25..34 28..29 Other", 640 "f FN_DEF FileId(1) 26..35 29..30 Other",
641 &["FileId(2) 11..12 Other", "FileId(2) 27..28 StructLiteral"], 641 &["FileId(2) 11..12 Other", "FileId(2) 28..29 StructLiteral"],
642 ); 642 );
643 } 643 }
644 644
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 8105ef373..f569a3f17 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -310,11 +310,11 @@ mod tests {
310 file_id: FileId( 310 file_id: FileId(
311 1, 311 1,
312 ), 312 ),
313 full_range: 22..46, 313 full_range: 23..47,
314 name: "test_foo", 314 name: "test_foo",
315 kind: FN_DEF, 315 kind: FN_DEF,
316 focus_range: Some( 316 focus_range: Some(
317 33..41, 317 34..42,
318 ), 318 ),
319 container_name: None, 319 container_name: None,
320 description: None, 320 description: None,
@@ -335,11 +335,11 @@ mod tests {
335 file_id: FileId( 335 file_id: FileId(
336 1, 336 1,
337 ), 337 ),
338 full_range: 47..81, 338 full_range: 49..83,
339 name: "test_foo", 339 name: "test_foo",
340 kind: FN_DEF, 340 kind: FN_DEF,
341 focus_range: Some( 341 focus_range: Some(
342 68..76, 342 70..78,
343 ), 343 ),
344 container_name: None, 344 container_name: None,
345 description: None, 345 description: None,
@@ -360,11 +360,11 @@ mod tests {
360 file_id: FileId( 360 file_id: FileId(
361 1, 361 1,
362 ), 362 ),
363 full_range: 82..104, 363 full_range: 85..107,
364 name: "bench", 364 name: "bench",
365 kind: FN_DEF, 365 kind: FN_DEF,
366 focus_range: Some( 366 focus_range: Some(
367 94..99, 367 97..102,
368 ), 368 ),
369 container_name: None, 369 container_name: None,
370 description: None, 370 description: None,
@@ -424,7 +424,7 @@ mod tests {
424 file_id: FileId( 424 file_id: FileId(
425 1, 425 1,
426 ), 426 ),
427 full_range: 22..64, 427 full_range: 23..65,
428 name: "foo", 428 name: "foo",
429 kind: FN_DEF, 429 kind: FN_DEF,
430 focus_range: None, 430 focus_range: None,
@@ -489,7 +489,7 @@ mod tests {
489 file_id: FileId( 489 file_id: FileId(
490 1, 490 1,
491 ), 491 ),
492 full_range: 51..105, 492 full_range: 52..106,
493 name: "foo", 493 name: "foo",
494 kind: FN_DEF, 494 kind: FN_DEF,
495 focus_range: None, 495 focus_range: None,
diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs
index e0de377b4..58839b14a 100644
--- a/crates/rust-analyzer/tests/heavy_tests/main.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/main.rs
@@ -178,14 +178,8 @@ fn main() {}
178pub use std::collections::HashMap; 178pub use std::collections::HashMap;
179"#, 179"#,
180 "range": { 180 "range": {
181 "end": { 181 "end": { "character": 0, "line": 6 },
182 "character": 0, 182 "start": { "character": 0, "line": 0 }
183 "line": 7
184 },
185 "start": {
186 "character": 0,
187 "line": 0
188 }
189 } 183 }
190 } 184 }
191 ]), 185 ]),
@@ -244,14 +238,8 @@ fn main() {}
244pub use std::collections::HashMap; 238pub use std::collections::HashMap;
245"#, 239"#,
246 "range": { 240 "range": {
247 "end": { 241 "end": { "character": 0, "line": 9 },
248 "character": 0, 242 "start": { "character": 0, "line": 0 }
249 "line": 10
250 },
251 "start": {
252 "character": 0,
253 "line": 0
254 }
255 } 243 }
256 } 244 }
257 ]), 245 ]),
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index 100db9d5d..08ac6f70f 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -128,3 +128,85 @@ pub fn split_delim(haystack: &str, delim: char) -> Option<(&str, &str)> {
128 let idx = haystack.find(delim)?; 128 let idx = haystack.find(delim)?;
129 Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..])) 129 Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..]))
130} 130}
131
132pub fn trim_indent(mut text: &str) -> String {
133 if text.starts_with('\n') {
134 text = &text[1..];
135 }
136 let indent = text
137 .lines()
138 .filter(|it| !it.trim().is_empty())
139 .map(|it| it.len() - it.trim_start().len())
140 .min()
141 .unwrap_or(0);
142 lines_with_ends(text)
143 .map(
144 |line| {
145 if line.len() <= indent {
146 line.trim_start_matches(' ')
147 } else {
148 &line[indent..]
149 }
150 },
151 )
152 .collect()
153}
154
155pub fn lines_with_ends(text: &str) -> LinesWithEnds {
156 LinesWithEnds { text }
157}
158
159pub struct LinesWithEnds<'a> {
160 text: &'a str,
161}
162
163impl<'a> Iterator for LinesWithEnds<'a> {
164 type Item = &'a str;
165 fn next(&mut self) -> Option<&'a str> {
166 if self.text.is_empty() {
167 return None;
168 }
169 let idx = self.text.find('\n').map_or(self.text.len(), |it| it + 1);
170 let (res, next) = self.text.split_at(idx);
171 self.text = next;
172 Some(res)
173 }
174}
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
181 fn test_trim_indent() {
182 assert_eq!(trim_indent(""), "");
183 assert_eq!(
184 trim_indent(
185 "
186 hello
187 world
188"
189 ),
190 "hello\nworld\n"
191 );
192 assert_eq!(
193 trim_indent(
194 "
195 hello
196 world"
197 ),
198 "hello\nworld"
199 );
200 assert_eq!(trim_indent(" hello\n world\n"), "hello\nworld\n");
201 assert_eq!(
202 trim_indent(
203 "
204 fn main() {
205 return 92;
206 }
207 "
208 ),
209 "fn main() {\n return 92;\n}\n"
210 );
211 }
212}
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index 0cd51ab3e..8747fa4a5 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -2,7 +2,7 @@
2//! rust-analyzer database from a single string. 2//! rust-analyzer database from a single string.
3 3
4use rustc_hash::FxHashMap; 4use rustc_hash::FxHashMap;
5use stdx::split_delim; 5use stdx::{lines_with_ends, split_delim, trim_indent};
6 6
7#[derive(Debug, Eq, PartialEq)] 7#[derive(Debug, Eq, PartialEq)]
8pub struct Fixture { 8pub struct Fixture {
@@ -26,47 +26,35 @@ impl Fixture {
26 /// // - other meta 26 /// // - other meta
27 /// ``` 27 /// ```
28 pub fn parse(ra_fixture: &str) -> Vec<Fixture> { 28 pub fn parse(ra_fixture: &str) -> Vec<Fixture> {
29 let fixture = indent_first_line(ra_fixture); 29 let fixture = trim_indent(ra_fixture);
30 let margin = fixture_margin(&fixture);
31
32 let mut lines = fixture
33 .split('\n') // don't use `.lines` to not drop `\r\n`
34 .enumerate()
35 .filter_map(|(ix, line)| {
36 if line.len() >= margin {
37 assert!(line[..margin].trim().is_empty());
38 let line_content = &line[margin..];
39 if !line_content.starts_with("//-") {
40 assert!(
41 !line_content.contains("//-"),
42 r#"Metadata line {} has invalid indentation. All metadata lines need to have the same indentation.
43The offending line: {:?}"#,
44 ix,
45 line
46 );
47 }
48 Some(line_content)
49 } else {
50 assert!(line.trim().is_empty());
51 None
52 }
53 });
54 30
55 let mut res: Vec<Fixture> = Vec::new(); 31 let mut res: Vec<Fixture> = Vec::new();
56 for line in lines.by_ref() { 32
33 for (ix, line) in lines_with_ends(&fixture).enumerate() {
34 if line.contains("//-") {
35 assert!(
36 line.starts_with("//-"),
37 "Metadata line {} has invalid indentation. \
38 All metadata lines need to have the same indentation.\n\
39 The offending line: {:?}",
40 ix,
41 line
42 );
43 }
44
57 if line.starts_with("//-") { 45 if line.starts_with("//-") {
58 let meta = Fixture::parse_single(line); 46 let meta = Fixture::parse_meta_line(line);
59 res.push(meta) 47 res.push(meta)
60 } else if let Some(entry) = res.last_mut() { 48 } else if let Some(entry) = res.last_mut() {
61 entry.text.push_str(line); 49 entry.text.push_str(line);
62 entry.text.push('\n');
63 } 50 }
64 } 51 }
52
65 res 53 res
66 } 54 }
67 55
68 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo 56 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
69 pub fn parse_single(meta: &str) -> Fixture { 57 pub fn parse_meta_line(meta: &str) -> Fixture {
70 assert!(meta.starts_with("//-")); 58 assert!(meta.starts_with("//-"));
71 let meta = meta["//-".len()..].trim(); 59 let meta = meta["//-".len()..].trim();
72 let components = meta.split_ascii_whitespace().collect::<Vec<_>>(); 60 let components = meta.split_ascii_whitespace().collect::<Vec<_>>();
@@ -118,51 +106,6 @@ The offending line: {:?}"#,
118 } 106 }
119} 107}
120 108
121/// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines.
122/// This allows fixtures to start off in a different indentation, e.g. to align the first line with
123/// the other lines visually:
124/// ```
125/// let fixture = "//- /lib.rs
126/// mod foo;
127/// //- /foo.rs
128/// fn bar() {}
129/// ";
130/// assert_eq!(fixture_margin(fixture),
131/// " //- /lib.rs
132/// mod foo;
133/// //- /foo.rs
134/// fn bar() {}
135/// ")
136/// ```
137fn indent_first_line(fixture: &str) -> String {
138 if fixture.is_empty() {
139 return String::new();
140 }
141 let mut lines = fixture.lines();
142 let first_line = lines.next().unwrap();
143 if first_line.contains("//-") {
144 let rest = lines.collect::<Vec<_>>().join("\n");
145 let fixed_margin = fixture_margin(&rest);
146 let fixed_indent = fixed_margin - indent_len(first_line);
147 format!("\n{}{}\n{}", " ".repeat(fixed_indent), first_line, rest)
148 } else {
149 fixture.to_owned()
150 }
151}
152
153fn fixture_margin(fixture: &str) -> usize {
154 fixture
155 .lines()
156 .filter(|it| it.trim_start().starts_with("//-"))
157 .map(indent_len)
158 .next()
159 .expect("empty fixture")
160}
161
162fn indent_len(s: &str) -> usize {
163 s.len() - s.trim_start().len()
164}
165
166#[test] 109#[test]
167#[should_panic] 110#[should_panic]
168fn parse_fixture_checks_further_indented_metadata() { 111fn parse_fixture_checks_further_indented_metadata() {
@@ -179,25 +122,6 @@ fn parse_fixture_checks_further_indented_metadata() {
179} 122}
180 123
181#[test] 124#[test]
182fn parse_fixture_can_handle_dedented_first_line() {
183 let fixture = "//- /lib.rs
184 mod foo;
185 //- /foo.rs
186 struct Bar;
187";
188 assert_eq!(
189 Fixture::parse(fixture),
190 Fixture::parse(
191 "//- /lib.rs
192mod foo;
193//- /foo.rs
194struct Bar;
195"
196 )
197 )
198}
199
200#[test]
201fn parse_fixture_gets_full_meta() { 125fn parse_fixture_gets_full_meta() {
202 let parsed = Fixture::parse( 126 let parsed = Fixture::parse(
203 r" 127 r"
@@ -208,7 +132,7 @@ fn parse_fixture_gets_full_meta() {
208 assert_eq!(1, parsed.len()); 132 assert_eq!(1, parsed.len());
209 133
210 let meta = &parsed[0]; 134 let meta = &parsed[0];
211 assert_eq!("mod m;\n\n", meta.text); 135 assert_eq!("mod m;\n", meta.text);
212 136
213 assert_eq!("foo", meta.crate_name.as_ref().unwrap()); 137 assert_eq!("foo", meta.crate_name.as_ref().unwrap());
214 assert_eq!("/lib.rs", meta.path); 138 assert_eq!("/lib.rs", meta.path);
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 3fd8505ed..eaeeeb97b 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -43,7 +43,7 @@ macro_rules! assert_eq_text {
43 if left.trim() == right.trim() { 43 if left.trim() == right.trim() {
44 eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right); 44 eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right);
45 } else { 45 } else {
46 let changeset = $crate::__Changeset::new(right, left, "\n"); 46 let changeset = $crate::__Changeset::new(left, right, "\n");
47 eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset); 47 eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset);
48 } 48 }
49 eprintln!($($tt)*); 49 eprintln!($($tt)*);