aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/goto_definition.rs')
-rw-r--r--crates/ra_ide/src/goto_definition.rs1052
1 files changed, 459 insertions, 593 deletions
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index bea7fbfa7..4c78fa214 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -103,205 +103,149 @@ pub(crate) fn reference_definition(
103 103
104#[cfg(test)] 104#[cfg(test)]
105mod tests { 105mod tests {
106 use test_utils::assert_eq_text; 106 use ra_db::FileRange;
107 107 use ra_syntax::{TextRange, TextSize};
108 use crate::mock_analysis::analysis_and_position; 108
109 109 use crate::mock_analysis::MockAnalysis;
110 fn check_goto(ra_fixture: &str, expected: &str, expected_range: &str) { 110
111 let (analysis, pos) = analysis_and_position(ra_fixture); 111 fn check(ra_fixture: &str) {
112 let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture);
113 let (mut expected, data) = mock.annotation();
114 let analysis = mock.analysis();
115 match data.as_str() {
116 "" => (),
117 "file" => {
118 expected.range =
119 TextRange::up_to(TextSize::of(&*analysis.file_text(expected.file_id).unwrap()))
120 }
121 data => panic!("bad data: {}", data),
122 }
112 123
113 let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info; 124 let mut navs = analysis.goto_definition(position).unwrap().unwrap().info;
114 if navs.len() == 0 { 125 if navs.len() == 0 {
115 panic!("unresolved reference") 126 panic!("unresolved reference")
116 } 127 }
117 assert_eq!(navs.len(), 1); 128 assert_eq!(navs.len(), 1);
118 129
119 let nav = navs.pop().unwrap(); 130 let nav = navs.pop().unwrap();
120 let file_text = analysis.file_text(nav.file_id()).unwrap(); 131 assert_eq!(expected, FileRange { file_id: nav.file_id(), range: nav.range() });
121
122 let mut actual = file_text[nav.full_range()].to_string();
123 if let Some(focus) = nav.focus_range() {
124 actual += "|";
125 actual += &file_text[focus];
126 }
127
128 if !expected_range.contains("...") {
129 test_utils::assert_eq_text!(&actual, expected_range);
130 } else {
131 let mut parts = expected_range.split("...");
132 let prefix = parts.next().unwrap();
133 let suffix = parts.next().unwrap();
134 assert!(
135 actual.starts_with(prefix) && actual.ends_with(suffix),
136 "\nExpected: {}\n Actual: {}\n",
137 expected_range,
138 actual
139 );
140 }
141
142 nav.assert_match(expected);
143 } 132 }
144 133
145 #[test] 134 #[test]
146 fn goto_def_in_items() { 135 fn goto_def_in_items() {
147 check_goto( 136 check(
148 " 137 r#"
149 //- /lib.rs 138struct Foo;
150 struct Foo; 139 //^^^
151 enum E { X(Foo<|>) } 140enum E { X(Foo<|>) }
152 ", 141"#,
153 "Foo STRUCT_DEF FileId(1) 0..11 7..10",
154 "struct Foo;|Foo",
155 ); 142 );
156 } 143 }
157 144
158 #[test] 145 #[test]
159 fn goto_def_at_start_of_item() { 146 fn goto_def_at_start_of_item() {
160 check_goto( 147 check(
161 " 148 r#"
162 //- /lib.rs 149struct Foo;
163 struct Foo; 150 //^^^
164 enum E { X(<|>Foo) } 151enum E { X(<|>Foo) }
165 ", 152"#,
166 "Foo STRUCT_DEF FileId(1) 0..11 7..10",
167 "struct Foo;|Foo",
168 ); 153 );
169 } 154 }
170 155
171 #[test] 156 #[test]
172 fn goto_definition_resolves_correct_name() { 157 fn goto_definition_resolves_correct_name() {
173 check_goto( 158 check(
174 " 159 r#"
175 //- /lib.rs 160//- /lib.rs
176 use a::Foo; 161use a::Foo;
177 mod a; 162mod a;
178 mod b; 163mod b;
179 enum E { X(Foo<|>) } 164enum E { X(Foo<|>) }
180 165
181 //- /a.rs 166//- /a.rs
182 struct Foo; 167struct Foo;
183 168 //^^^
184 //- /b.rs 169//- /b.rs
185 struct Foo; 170struct Foo;
186 ", 171"#,
187 "Foo STRUCT_DEF FileId(2) 0..11 7..10",
188 "struct Foo;|Foo",
189 ); 172 );
190 } 173 }
191 174
192 #[test] 175 #[test]
193 fn goto_def_for_module_declaration() { 176 fn goto_def_for_module_declaration() {
194 check_goto( 177 check(
195 r#" 178 r#"
196//- /lib.rs 179//- /lib.rs
197mod <|>foo; 180mod <|>foo;
198 181
199//- /foo.rs 182//- /foo.rs
200// empty 183// empty
184//^ file
201"#, 185"#,
202 "foo SOURCE_FILE FileId(2) 0..9",
203 "// empty\n",
204 ); 186 );
205 187
206 check_goto( 188 check(
207 r#" 189 r#"
208//- /lib.rs 190//- /lib.rs
209mod <|>foo; 191mod <|>foo;
210 192
211//- /foo/mod.rs 193//- /foo/mod.rs
212// empty 194// empty
195//^ file
213"#, 196"#,
214 "foo SOURCE_FILE FileId(2) 0..9",
215 "// empty\n",
216 ); 197 );
217 } 198 }
218 199
219 #[test] 200 #[test]
220 fn goto_def_for_macros() { 201 fn goto_def_for_macros() {
221 check_goto( 202 check(
222 " 203 r#"
223 //- /lib.rs 204macro_rules! foo { () => { () } }
224 macro_rules! foo { () => { () } } 205 //^^^
225 206fn bar() {
226 fn bar() { 207 <|>foo!();
227 <|>foo!(); 208}
228 } 209"#,
229 ",
230 "foo MACRO_CALL FileId(1) 0..33 13..16",
231 "macro_rules! foo { () => { () } }|foo",
232 ); 210 );
233 } 211 }
234 212
235 #[test] 213 #[test]
236 fn goto_def_for_macros_from_other_crates() { 214 fn goto_def_for_macros_from_other_crates() {
237 check_goto( 215 check(
238 "
239 //- /lib.rs
240 use foo::foo;
241 fn bar() {
242 <|>foo!();
243 }
244
245 //- /foo/lib.rs
246 #[macro_export]
247 macro_rules! foo { () => { () } }
248 ",
249 "foo MACRO_CALL FileId(2) 0..49 29..32",
250 "#[macro_export]\nmacro_rules! foo { () => { () } }|foo",
251 );
252 }
253
254 #[test]
255 fn goto_def_for_use_alias() {
256 check_goto(
257 r#" 216 r#"
258//- /lib.rs 217//- /lib.rs
259use foo as bar<|>; 218use foo::foo;
219fn bar() {
220 <|>foo!();
221}
260 222
261//- /foo/lib.rs 223//- /foo/lib.rs
262#[macro_export] 224#[macro_export]
263macro_rules! foo { () => { () } } 225macro_rules! foo { () => { () } }
226 //^^^
264"#, 227"#,
265 "SOURCE_FILE FileId(2) 0..50",
266 "#[macro_export]\nmacro_rules! foo { () => { () } }\n",
267 );
268 }
269
270 #[test]
271 fn goto_def_for_use_alias_foo_macro() {
272 check_goto(
273 "
274 //- /lib.rs
275 use foo::foo as bar<|>;
276
277 //- /foo/lib.rs
278 #[macro_export]
279 macro_rules! foo { () => { () } }
280 ",
281 "foo MACRO_CALL FileId(2) 0..49 29..32",
282 "#[macro_export]\nmacro_rules! foo { () => { () } }|foo",
283 ); 228 );
284 } 229 }
285 230
286 #[test] 231 #[test]
287 fn goto_def_for_macros_in_use_tree() { 232 fn goto_def_for_macros_in_use_tree() {
288 check_goto( 233 check(
289 " 234 r#"
290 //- /lib.rs 235//- /lib.rs
291 use foo::foo<|>; 236use foo::foo<|>;
292 237
293 //- /foo/lib.rs 238//- /foo/lib.rs
294 #[macro_export] 239#[macro_export]
295 macro_rules! foo { () => { () } } 240macro_rules! foo { () => { () } }
296 ", 241 //^^^
297 "foo MACRO_CALL FileId(2) 0..49 29..32", 242"#,
298 "#[macro_export]\nmacro_rules! foo { () => { () } }|foo",
299 ); 243 );
300 } 244 }
301 245
302 #[test] 246 #[test]
303 fn goto_def_for_macro_defined_fn_with_arg() { 247 fn goto_def_for_macro_defined_fn_with_arg() {
304 check_goto( 248 check(
305 r#" 249 r#"
306//- /lib.rs 250//- /lib.rs
307macro_rules! define_fn { 251macro_rules! define_fn {
@@ -309,522 +253,478 @@ macro_rules! define_fn {
309} 253}
310 254
311define_fn!(foo); 255define_fn!(foo);
256 //^^^
312 257
313fn bar() { 258fn bar() {
314 <|>foo(); 259 <|>foo();
315} 260}
316"#, 261"#,
317 "foo FN_DEF FileId(1) 65..81 76..79",
318 "define_fn!(foo);|foo",
319 ); 262 );
320 } 263 }
321 264
322 #[test] 265 #[test]
323 fn goto_def_for_macro_defined_fn_no_arg() { 266 fn goto_def_for_macro_defined_fn_no_arg() {
324 check_goto( 267 check(
325 r#" 268 r#"
326//- /lib.rs 269//- /lib.rs
327macro_rules! define_fn { 270macro_rules! define_fn {
328 () => (fn foo() {}) 271 () => (fn foo() {})
329} 272}
330 273
331define_fn!(); 274 define_fn!();
275//^^^^^^^^^^^^^
332 276
333fn bar() { 277fn bar() {
334 <|>foo(); 278 <|>foo();
335} 279}
336"#, 280"#,
337 "foo FN_DEF FileId(1) 52..65 52..65",
338 "define_fn!();|define_fn!();",
339 ); 281 );
340 } 282 }
341 283
342 #[test] 284 #[test]
343 fn goto_definition_works_for_macro_inside_pattern() { 285 fn goto_definition_works_for_macro_inside_pattern() {
344 check_goto( 286 check(
345 " 287 r#"
346 //- /lib.rs 288//- /lib.rs
347 macro_rules! foo {() => {0}} 289macro_rules! foo {() => {0}}
348 290 //^^^
349 fn bar() { 291
350 match (0,1) { 292fn bar() {
351 (<|>foo!(), _) => {} 293 match (0,1) {
352 } 294 (<|>foo!(), _) => {}
353 } 295 }
354 ", 296}
355 "foo MACRO_CALL FileId(1) 0..28 13..16", 297"#,
356 "macro_rules! foo {() => {0}}|foo",
357 ); 298 );
358 } 299 }
359 300
360 #[test] 301 #[test]
361 fn goto_definition_works_for_macro_inside_match_arm_lhs() { 302 fn goto_definition_works_for_macro_inside_match_arm_lhs() {
362 check_goto( 303 check(
363 " 304 r#"
364 //- /lib.rs 305//- /lib.rs
365 macro_rules! foo {() => {0}} 306macro_rules! foo {() => {0}}
366 307 //^^^
367 fn bar() { 308fn bar() {
368 match 0 { 309 match 0 {
369 <|>foo!() => {} 310 <|>foo!() => {}
370 } 311 }
371 } 312}
372 ", 313"#,
373 "foo MACRO_CALL FileId(1) 0..28 13..16", 314 );
374 "macro_rules! foo {() => {0}}|foo", 315 }
316
317 #[test]
318 fn goto_def_for_use_alias() {
319 check(
320 r#"
321//- /lib.rs
322use foo as bar<|>;
323
324//- /foo/lib.rs
325// empty
326//^ file
327"#,
328 );
329 }
330
331 #[test]
332 fn goto_def_for_use_alias_foo_macro() {
333 check(
334 r#"
335//- /lib.rs
336use foo::foo as bar<|>;
337
338//- /foo/lib.rs
339#[macro_export]
340macro_rules! foo { () => { () } }
341 //^^^
342"#,
375 ); 343 );
376 } 344 }
377 345
378 #[test] 346 #[test]
379 fn goto_def_for_methods() { 347 fn goto_def_for_methods() {
380 check_goto( 348 check(
381 " 349 r#"
382 //- /lib.rs 350//- /lib.rs
383 struct Foo; 351struct Foo;
384 impl Foo { 352impl Foo {
385 fn frobnicate(&self) { } 353 fn frobnicate(&self) { }
386 } 354 //^^^^^^^^^^
355}
387 356
388 fn bar(foo: &Foo) { 357fn bar(foo: &Foo) {
389 foo.frobnicate<|>(); 358 foo.frobnicate<|>();
390 } 359}
391 ", 360"#,
392 "frobnicate FN_DEF FileId(1) 27..51 30..40",
393 "fn frobnicate(&self) { }|frobnicate",
394 ); 361 );
395 } 362 }
396 363
397 #[test] 364 #[test]
398 fn goto_def_for_fields() { 365 fn goto_def_for_fields() {
399 check_goto( 366 check(
400 r" 367 r#"
401 //- /lib.rs 368struct Foo {
402 struct Foo { 369 spam: u32,
403 spam: u32, 370} //^^^^
404 }
405 371
406 fn bar(foo: &Foo) { 372fn bar(foo: &Foo) {
407 foo.spam<|>; 373 foo.spam<|>;
408 } 374}
409 ", 375"#,
410 "spam RECORD_FIELD_DEF FileId(1) 17..26 17..21",
411 "spam: u32|spam",
412 ); 376 );
413 } 377 }
414 378
415 #[test] 379 #[test]
416 fn goto_def_for_record_fields() { 380 fn goto_def_for_record_fields() {
417 check_goto( 381 check(
418 r" 382 r#"
419 //- /lib.rs 383//- /lib.rs
420 struct Foo { 384struct Foo {
421 spam: u32, 385 spam: u32,
422 } 386} //^^^^
423 387
424 fn bar() -> Foo { 388fn bar() -> Foo {
425 Foo { 389 Foo {
426 spam<|>: 0, 390 spam<|>: 0,
427 } 391 }
428 } 392}
429 ", 393"#,
430 "spam RECORD_FIELD_DEF FileId(1) 17..26 17..21",
431 "spam: u32|spam",
432 ); 394 );
433 } 395 }
434 396
435 #[test] 397 #[test]
436 fn goto_def_for_record_pat_fields() { 398 fn goto_def_for_record_pat_fields() {
437 check_goto( 399 check(
438 r" 400 r#"
439 //- /lib.rs 401//- /lib.rs
440 struct Foo { 402struct Foo {
441 spam: u32, 403 spam: u32,
442 } 404} //^^^^
443 405
444 fn bar(foo: Foo) -> Foo { 406fn bar(foo: Foo) -> Foo {
445 let Foo { spam<|>: _, } = foo 407 let Foo { spam<|>: _, } = foo
446 } 408}
447 ", 409"#,
448 "spam RECORD_FIELD_DEF FileId(1) 17..26 17..21",
449 "spam: u32|spam",
450 ); 410 );
451 } 411 }
452 412
453 #[test] 413 #[test]
454 fn goto_def_for_record_fields_macros() { 414 fn goto_def_for_record_fields_macros() {
455 check_goto( 415 check(
456 r" 416 r"
457 //- /lib.rs 417macro_rules! m { () => { 92 };}
458 macro_rules! m { () => { 92 };} 418struct Foo { spam: u32 }
459 struct Foo { spam: u32 } 419 //^^^^
460 420
461 fn bar() -> Foo { 421fn bar() -> Foo {
462 Foo { spam<|>: m!() } 422 Foo { spam<|>: m!() }
463 } 423}
464 ", 424",
465 "spam RECORD_FIELD_DEF FileId(1) 45..54 45..49",
466 "spam: u32|spam",
467 ); 425 );
468 } 426 }
469 427
470 #[test] 428 #[test]
471 fn goto_for_tuple_fields() { 429 fn goto_for_tuple_fields() {
472 check_goto( 430 check(
473 " 431 r#"
474 //- /lib.rs 432struct Foo(u32);
475 struct Foo(u32); 433 //^^^
476 434
477 fn bar() { 435fn bar() {
478 let foo = Foo(0); 436 let foo = Foo(0);
479 foo.<|>0; 437 foo.<|>0;
480 } 438}
481 ", 439"#,
482 "TUPLE_FIELD_DEF FileId(1) 11..14",
483 "u32",
484 ); 440 );
485 } 441 }
486 442
487 #[test] 443 #[test]
488 fn goto_def_for_ufcs_inherent_methods() { 444 fn goto_def_for_ufcs_inherent_methods() {
489 check_goto( 445 check(
490 " 446 r#"
491 //- /lib.rs 447struct Foo;
492 struct Foo; 448impl Foo {
493 impl Foo { 449 fn frobnicate() { }
494 fn frobnicate() { } 450} //^^^^^^^^^^
495 }
496 451
497 fn bar(foo: &Foo) { 452fn bar(foo: &Foo) {
498 Foo::frobnicate<|>(); 453 Foo::frobnicate<|>();
499 } 454}
500 ", 455"#,
501 "frobnicate FN_DEF FileId(1) 27..46 30..40",
502 "fn frobnicate() { }|frobnicate",
503 ); 456 );
504 } 457 }
505 458
506 #[test] 459 #[test]
507 fn goto_def_for_ufcs_trait_methods_through_traits() { 460 fn goto_def_for_ufcs_trait_methods_through_traits() {
508 check_goto( 461 check(
509 " 462 r#"
510 //- /lib.rs 463trait Foo {
511 trait Foo { 464 fn frobnicate();
512 fn frobnicate(); 465} //^^^^^^^^^^
513 }
514 466
515 fn bar() { 467fn bar() {
516 Foo::frobnicate<|>(); 468 Foo::frobnicate<|>();
517 } 469}
518 ", 470"#,
519 "frobnicate FN_DEF FileId(1) 16..32 19..29",
520 "fn frobnicate();|frobnicate",
521 ); 471 );
522 } 472 }
523 473
524 #[test] 474 #[test]
525 fn goto_def_for_ufcs_trait_methods_through_self() { 475 fn goto_def_for_ufcs_trait_methods_through_self() {
526 check_goto( 476 check(
527 " 477 r#"
528 //- /lib.rs 478struct Foo;
529 struct Foo; 479trait Trait {
530 trait Trait { 480 fn frobnicate();
531 fn frobnicate(); 481} //^^^^^^^^^^
532 } 482impl Trait for Foo {}
533 impl Trait for Foo {}
534 483
535 fn bar() { 484fn bar() {
536 Foo::frobnicate<|>(); 485 Foo::frobnicate<|>();
537 } 486}
538 ", 487"#,
539 "frobnicate FN_DEF FileId(1) 30..46 33..43",
540 "fn frobnicate();|frobnicate",
541 ); 488 );
542 } 489 }
543 490
544 #[test] 491 #[test]
545 fn goto_definition_on_self() { 492 fn goto_definition_on_self() {
546 check_goto( 493 check(
547 " 494 r#"
548 //- /lib.rs 495struct Foo;
549 struct Foo; 496impl Foo {
550 impl Foo { 497 //^^^
551 pub fn new() -> Self { 498 pub fn new() -> Self {
552 Self<|> {} 499 Self<|> {}
553 } 500 }
554 } 501}
555 ", 502"#,
556 "impl IMPL_DEF FileId(1) 12..73", 503 );
557 "impl Foo {...}", 504 check(
558 ); 505 r#"
559 506struct Foo;
560 check_goto( 507impl Foo {
561 " 508 //^^^
562 //- /lib.rs 509 pub fn new() -> Self<|> {
563 struct Foo; 510 Self {}
564 impl Foo { 511 }
565 pub fn new() -> Self<|> { 512}
566 Self {} 513"#,
567 } 514 );
568 } 515
569 ", 516 check(
570 "impl IMPL_DEF FileId(1) 12..73", 517 r#"
571 "impl Foo {...}", 518enum Foo { A }
572 ); 519impl Foo {
573 520 //^^^
574 check_goto( 521 pub fn new() -> Self<|> {
575 " 522 Foo::A
576 //- /lib.rs 523 }
577 enum Foo { A } 524}
578 impl Foo { 525"#,
579 pub fn new() -> Self<|> { 526 );
580 Foo::A 527
581 } 528 check(
582 } 529 r#"
583 ", 530enum Foo { A }
584 "impl IMPL_DEF FileId(1) 15..75", 531impl Foo {
585 "impl Foo {...}", 532 //^^^
586 ); 533 pub fn thing(a: &Self<|>) {
587 534 }
588 check_goto( 535}
589 " 536"#,
590 //- /lib.rs
591 enum Foo { A }
592 impl Foo {
593 pub fn thing(a: &Self<|>) {
594 }
595 }
596 ",
597 "impl IMPL_DEF FileId(1) 15..62",
598 "impl Foo {...}",
599 ); 537 );
600 } 538 }
601 539
602 #[test] 540 #[test]
603 fn goto_definition_on_self_in_trait_impl() { 541 fn goto_definition_on_self_in_trait_impl() {
604 check_goto( 542 check(
605 " 543 r#"
606 //- /lib.rs 544struct Foo;
607 struct Foo; 545trait Make {
608 trait Make { 546 fn new() -> Self;
609 fn new() -> Self; 547}
610 } 548impl Make for Foo {
611 impl Make for Foo { 549 //^^^
612 fn new() -> Self { 550 fn new() -> Self {
613 Self<|> {} 551 Self<|> {}
614 } 552 }
615 } 553}
616 ", 554"#,
617 "impl IMPL_DEF FileId(1) 49..115",
618 "impl Make for Foo {...}",
619 ); 555 );
620 556
621 check_goto( 557 check(
622 " 558 r#"
623 //- /lib.rs 559struct Foo;
624 struct Foo; 560trait Make {
625 trait Make { 561 fn new() -> Self;
626 fn new() -> Self; 562}
627 } 563impl Make for Foo {
628 impl Make for Foo { 564 //^^^
629 fn new() -> Self<|> { 565 fn new() -> Self<|> {
630 Self {} 566 Self {}
631 } 567 }
632 } 568}
633 ", 569"#,
634 "impl IMPL_DEF FileId(1) 49..115",
635 "impl Make for Foo {...}",
636 ); 570 );
637 } 571 }
638 572
639 #[test] 573 #[test]
640 fn goto_def_when_used_on_definition_name_itself() { 574 fn goto_def_when_used_on_definition_name_itself() {
641 check_goto( 575 check(
642 " 576 r#"
643 //- /lib.rs 577struct Foo<|> { value: u32 }
644 struct Foo<|> { value: u32 } 578 //^^^
645 ", 579 "#,
646 "Foo STRUCT_DEF FileId(1) 0..25 7..10",
647 "struct Foo { value: u32 }|Foo",
648 ); 580 );
649 581
650 check_goto( 582 check(
651 r#" 583 r#"
652 //- /lib.rs 584struct Foo {
653 struct Foo { 585 field<|>: string,
654 field<|>: string, 586} //^^^^^
655 } 587"#,
656 "#,
657 "field RECORD_FIELD_DEF FileId(1) 17..30 17..22",
658 "field: string|field",
659 ); 588 );
660 589
661 check_goto( 590 check(
662 " 591 r#"
663 //- /lib.rs 592fn foo_test<|>() { }
664 fn foo_test<|>() { } 593 //^^^^^^^^
665 ", 594"#,
666 "foo_test FN_DEF FileId(1) 0..17 3..11",
667 "fn foo_test() { }|foo_test",
668 ); 595 );
669 596
670 check_goto( 597 check(
671 " 598 r#"
672 //- /lib.rs 599enum Foo<|> { Variant }
673 enum Foo<|> { 600 //^^^
674 Variant, 601"#,
675 }
676 ",
677 "Foo ENUM_DEF FileId(1) 0..25 5..8",
678 "enum Foo {...}|Foo",
679 );
680
681 check_goto(
682 "
683 //- /lib.rs
684 enum Foo {
685 Variant1,
686 Variant2<|>,
687 Variant3,
688 }
689 ",
690 "Variant2 ENUM_VARIANT FileId(1) 29..37 29..37",
691 "Variant2|Variant2",
692 ); 602 );
693 603
694 check_goto( 604 check(
695 r#" 605 r#"
696 //- /lib.rs 606enum Foo {
697 static INNER<|>: &str = ""; 607 Variant1,
698 "#, 608 Variant2<|>,
699 "INNER STATIC_DEF FileId(1) 0..24 7..12", 609 //^^^^^^^^
700 "static INNER: &str = \"\";|INNER", 610 Variant3,
611}
612"#,
701 ); 613 );
702 614
703 check_goto( 615 check(
704 r#" 616 r#"
705 //- /lib.rs 617static INNER<|>: &str = "";
706 const INNER<|>: &str = ""; 618 //^^^^^
707 "#, 619"#,
708 "INNER CONST_DEF FileId(1) 0..23 6..11",
709 "const INNER: &str = \"\";|INNER",
710 ); 620 );
711 621
712 check_goto( 622 check(
713 r#" 623 r#"
714 //- /lib.rs 624const INNER<|>: &str = "";
715 type Thing<|> = Option<()>; 625 //^^^^^
716 "#, 626"#,
717 "Thing TYPE_ALIAS_DEF FileId(1) 0..24 5..10",
718 "type Thing = Option<()>;|Thing",
719 ); 627 );
720 628
721 check_goto( 629 check(
722 r#" 630 r#"
723 //- /lib.rs 631type Thing<|> = Option<()>;
724 trait Foo<|> { } 632 //^^^^^
725 "#, 633"#,
726 "Foo TRAIT_DEF FileId(1) 0..13 6..9",
727 "trait Foo { }|Foo",
728 ); 634 );
729 635
730 check_goto( 636 check(
731 r#" 637 r#"
732 //- /lib.rs 638trait Foo<|> { }
733 mod bar<|> { } 639 //^^^
734 "#, 640"#,
735 "bar MODULE FileId(1) 0..11 4..7", 641 );
736 "mod bar { }|bar", 642
643 check(
644 r#"
645mod bar<|> { }
646 //^^^
647"#,
737 ); 648 );
738 } 649 }
739 650
740 #[test] 651 #[test]
741 fn goto_from_macro() { 652 fn goto_from_macro() {
742 check_goto( 653 check(
743 " 654 r#"
744 //- /lib.rs 655macro_rules! id {
745 macro_rules! id { 656 ($($tt:tt)*) => { $($tt)* }
746 ($($tt:tt)*) => { $($tt)* } 657}
747 } 658fn foo() {}
748 fn foo() {} 659 //^^^
749 id! { 660id! {
750 fn bar() { 661 fn bar() {
751 fo<|>o(); 662 fo<|>o();
752 } 663 }
753 } 664}
754 mod confuse_index { fn foo(); } 665mod confuse_index { fn foo(); }
755 ", 666"#,
756 "foo FN_DEF FileId(1) 52..63 55..58",
757 "fn foo() {}|foo",
758 ); 667 );
759 } 668 }
760 669
761 #[test] 670 #[test]
762 fn goto_through_format() { 671 fn goto_through_format() {
763 check_goto( 672 check(
764 " 673 r#"
765 //- /lib.rs 674#[macro_export]
766 #[macro_export] 675macro_rules! format {
767 macro_rules! format { 676 ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
768 ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*))) 677}
769 } 678#[rustc_builtin_macro]
770 #[rustc_builtin_macro] 679#[macro_export]
771 #[macro_export] 680macro_rules! format_args {
772 macro_rules! format_args { 681 ($fmt:expr) => ({ /* compiler built-in */ });
773 ($fmt:expr) => ({ /* compiler built-in */ }); 682 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
774 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) 683}
775 } 684pub mod __export {
776 pub mod __export { 685 pub use crate::format_args;
777 pub use crate::format_args; 686 fn foo() {} // for index confusion
778 fn foo() {} // for index confusion 687}
779 } 688fn foo() -> i8 {}
780 fn foo() -> i8 {} 689 //^^^
781 fn test() { 690fn test() {
782 format!(\"{}\", fo<|>o()) 691 format!("{}", fo<|>o())
783 } 692}
784 ", 693"#,
785 "foo FN_DEF FileId(1) 398..415 401..404",
786 "fn foo() -> i8 {}|foo",
787 ); 694 );
788 } 695 }
789 696
790 #[test] 697 #[test]
791 fn goto_for_type_param() { 698 fn goto_for_type_param() {
792 check_goto( 699 check(
793 r#" 700 r#"
794 //- /lib.rs 701struct Foo<T: Clone> { t: <|>T }
795 struct Foo<T: Clone> { 702 //^
796 t: <|>T, 703"#,
797 }
798 "#,
799 "T TYPE_PARAM FileId(1) 11..19 11..12",
800 "T: Clone|T",
801 ); 704 );
802 } 705 }
803 706
804 #[test] 707 #[test]
805 fn goto_within_macro() { 708 fn goto_within_macro() {
806 check_goto( 709 check(
807 r#" 710 r#"
808//- /lib.rs
809macro_rules! id { 711macro_rules! id {
810 ($($tt:tt)*) => ($($tt)*) 712 ($($tt:tt)*) => ($($tt)*)
811} 713}
812 714
813fn foo() { 715fn foo() {
814 let x = 1; 716 let x = 1;
717 //^
815 id!({ 718 id!({
816 let y = <|>x; 719 let y = <|>x;
817 let z = y; 720 let z = y;
818 }); 721 });
819} 722}
820"#, 723"#,
821 "x BIND_PAT FileId(1) 70..71",
822 "x",
823 ); 724 );
824 725
825 check_goto( 726 check(
826 r#" 727 r#"
827//- /lib.rs
828macro_rules! id { 728macro_rules! id {
829 ($($tt:tt)*) => ($($tt)*) 729 ($($tt:tt)*) => ($($tt)*)
830} 730}
@@ -833,159 +733,125 @@ fn foo() {
833 let x = 1; 733 let x = 1;
834 id!({ 734 id!({
835 let y = x; 735 let y = x;
736 //^
836 let z = <|>y; 737 let z = <|>y;
837 }); 738 });
838} 739}
839"#, 740"#,
840 "y BIND_PAT FileId(1) 99..100",
841 "y",
842 ); 741 );
843 } 742 }
844 743
845 #[test] 744 #[test]
846 fn goto_def_in_local_fn() { 745 fn goto_def_in_local_fn() {
847 check_goto( 746 check(
848 " 747 r#"
849 //- /lib.rs 748fn main() {
850 fn main() { 749 fn foo() {
851 fn foo() { 750 let x = 92;
852 let x = 92; 751 //^
853 <|>x; 752 <|>x;
854 } 753 }
855 } 754}
856 ", 755"#,
857 "x BIND_PAT FileId(1) 39..40",
858 "x",
859 ); 756 );
860 } 757 }
861 758
862 #[test] 759 #[test]
863 fn goto_def_in_local_macro() { 760 fn goto_def_in_local_macro() {
864 check_goto( 761 check(
865 r" 762 r#"
866 //- /lib.rs 763fn bar() {
867 fn bar() { 764 macro_rules! foo { () => { () } }
868 macro_rules! foo { () => { () } } 765 //^^^
869 <|>foo!(); 766 <|>foo!();
870 } 767}
871 ", 768"#,
872 "foo MACRO_CALL FileId(1) 15..48 28..31",
873 "macro_rules! foo { () => { () } }|foo",
874 ); 769 );
875 } 770 }
876 771
877 #[test] 772 #[test]
878 fn goto_def_for_field_init_shorthand() { 773 fn goto_def_for_field_init_shorthand() {
879 check_goto( 774 check(
880 " 775 r#"
881 //- /lib.rs 776struct Foo { x: i32 }
882 struct Foo { x: i32 } 777fn main() {
883 fn main() { 778 let x = 92;
884 let x = 92; 779 //^
885 Foo { x<|> }; 780 Foo { x<|> };
886 } 781}
887 ", 782"#,
888 "x BIND_PAT FileId(1) 42..43",
889 "x",
890 ) 783 )
891 } 784 }
892 785
893 #[test] 786 #[test]
894 fn goto_def_for_enum_variant_field() { 787 fn goto_def_for_enum_variant_field() {
895 check_goto( 788 check(
896 " 789 r#"
897 //- /lib.rs 790enum Foo {
898 enum Foo { 791 Bar { x: i32 }
899 Bar { x: i32 } 792} //^
900 } 793fn baz(foo: Foo) {
901 fn baz(foo: Foo) { 794 match foo {
902 match foo { 795 Foo::Bar { x<|> } => x
903 Foo::Bar { x<|> } => x 796 };
904 }; 797}
905 } 798"#,
906 ",
907 "x RECORD_FIELD_DEF FileId(1) 21..27 21..22",
908 "x: i32|x",
909 ); 799 );
910 } 800 }
911 801
912 #[test] 802 #[test]
913 fn goto_def_for_enum_variant_self_pattern_const() { 803 fn goto_def_for_enum_variant_self_pattern_const() {
914 check_goto( 804 check(
915 " 805 r#"
916 //- /lib.rs 806enum Foo { Bar }
917 enum Foo { 807 //^^^
918 Bar, 808impl Foo {
919 } 809 fn baz(self) {
920 impl Foo { 810 match self { Self::Bar<|> => {} }
921 fn baz(self) { 811 }
922 match self { 812}
923 Self::Bar<|> => {} 813"#,
924 }
925 }
926 }
927 ",
928 "Bar ENUM_VARIANT FileId(1) 15..18 15..18",
929 "Bar|Bar",
930 ); 814 );
931 } 815 }
932 816
933 #[test] 817 #[test]
934 fn goto_def_for_enum_variant_self_pattern_record() { 818 fn goto_def_for_enum_variant_self_pattern_record() {
935 check_goto( 819 check(
936 " 820 r#"
937 //- /lib.rs 821enum Foo { Bar { val: i32 } }
938 enum Foo { 822 //^^^
939 Bar { val: i32 }, 823impl Foo {
940 } 824 fn baz(self) -> i32 {
941 impl Foo { 825 match self { Self::Bar<|> { val } => {} }
942 fn baz(self) -> i32 { 826 }
943 match self { 827}
944 Self::Bar<|> { val } => {} 828"#,
945 }
946 }
947 }
948 ",
949 "Bar ENUM_VARIANT FileId(1) 15..31 15..18",
950 "Bar { val: i32 }|Bar",
951 ); 829 );
952 } 830 }
953 831
954 #[test] 832 #[test]
955 fn goto_def_for_enum_variant_self_expr_const() { 833 fn goto_def_for_enum_variant_self_expr_const() {
956 check_goto( 834 check(
957 " 835 r#"
958 //- /lib.rs 836enum Foo { Bar }
959 enum Foo { 837 //^^^
960 Bar, 838impl Foo {
961 } 839 fn baz(self) { Self::Bar<|>; }
962 impl Foo { 840}
963 fn baz(self) { 841"#,
964 Self::Bar<|>;
965 }
966 }
967 ",
968 "Bar ENUM_VARIANT FileId(1) 15..18 15..18",
969 "Bar|Bar",
970 ); 842 );
971 } 843 }
972 844
973 #[test] 845 #[test]
974 fn goto_def_for_enum_variant_self_expr_record() { 846 fn goto_def_for_enum_variant_self_expr_record() {
975 check_goto( 847 check(
976 " 848 r#"
977 //- /lib.rs 849enum Foo { Bar { val: i32 } }
978 enum Foo { 850 //^^^
979 Bar { val: i32 }, 851impl Foo {
980 } 852 fn baz(self) { Self::Bar<|> {val: 4}; }
981 impl Foo { 853}
982 fn baz(self) { 854"#,
983 Self::Bar<|> {val: 4};
984 }
985 }
986 ",
987 "Bar ENUM_VARIANT FileId(1) 15..31 15..18",
988 "Bar { val: i32 }|Bar",
989 ); 855 );
990 } 856 }
991} 857}