aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/Cargo.toml3
-rw-r--r--crates/ra_hir_def/src/body.rs65
-rw-r--r--crates/ra_hir_def/src/data.rs4
-rw-r--r--crates/ra_hir_def/src/import_map.rs300
-rw-r--r--crates/ra_hir_def/src/item_tree.rs1
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs28
-rw-r--r--crates/ra_hir_def/src/item_tree/tests.rs214
-rw-r--r--crates/ra_hir_def/src/lib.rs53
-rw-r--r--crates/ra_hir_def/src/nameres.rs20
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs29
-rw-r--r--crates/ra_hir_def/src/nameres/mod_resolution.rs116
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs10
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs844
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs578
-rw-r--r--crates/ra_hir_def/src/nameres/tests/macros.rs1061
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs1289
-rw-r--r--crates/ra_hir_def/src/nameres/tests/primitives.rs33
-rw-r--r--crates/ra_hir_def/src/test_db.rs28
-rw-r--r--crates/ra_hir_def/src/type_ref.rs13
19 files changed, 2369 insertions, 2320 deletions
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 6d43924e3..d96a86b80 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -3,6 +3,7 @@ edition = "2018"
3name = "ra_hir_def" 3name = "ra_hir_def"
4version = "0.1.0" 4version = "0.1.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6license = "MIT OR Apache-2.0"
6 7
7[lib] 8[lib]
8doctest = false 9doctest = false
@@ -32,4 +33,4 @@ ra_cfg = { path = "../ra_cfg" }
32tt = { path = "../ra_tt", package = "ra_tt" } 33tt = { path = "../ra_tt", package = "ra_tt" }
33 34
34[dev-dependencies] 35[dev-dependencies]
35insta = "0.16.0" 36expect = { path = "../expect" }
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 4f2350915..2fe04db2b 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -14,6 +14,7 @@ use ra_db::CrateId;
14use ra_prof::profile; 14use ra_prof::profile;
15use ra_syntax::{ast, AstNode, AstPtr}; 15use ra_syntax::{ast, AstNode, AstPtr};
16use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
17use test_utils::mark;
17 18
18pub(crate) use lower::LowerCtx; 19pub(crate) use lower::LowerCtx;
19 20
@@ -42,9 +43,15 @@ pub(crate) struct Expander {
42 current_file_id: HirFileId, 43 current_file_id: HirFileId,
43 ast_id_map: Arc<AstIdMap>, 44 ast_id_map: Arc<AstIdMap>,
44 module: ModuleId, 45 module: ModuleId,
45 recursive_limit: usize, 46 recursion_limit: usize,
46} 47}
47 48
49#[cfg(test)]
50const EXPANSION_RECURSION_LIMIT: usize = 32;
51
52#[cfg(not(test))]
53const EXPANSION_RECURSION_LIMIT: usize = 128;
54
48impl CfgExpander { 55impl CfgExpander {
49 pub(crate) fn new( 56 pub(crate) fn new(
50 db: &dyn DefDatabase, 57 db: &dyn DefDatabase,
@@ -81,7 +88,7 @@ impl Expander {
81 current_file_id, 88 current_file_id,
82 ast_id_map, 89 ast_id_map,
83 module, 90 module,
84 recursive_limit: 0, 91 recursion_limit: 0,
85 } 92 }
86 } 93 }
87 94
@@ -91,7 +98,9 @@ impl Expander {
91 local_scope: Option<&ItemScope>, 98 local_scope: Option<&ItemScope>,
92 macro_call: ast::MacroCall, 99 macro_call: ast::MacroCall,
93 ) -> Option<(Mark, T)> { 100 ) -> Option<(Mark, T)> {
94 if self.recursive_limit > 1024 { 101 self.recursion_limit += 1;
102 if self.recursion_limit > EXPANSION_RECURSION_LIMIT {
103 mark::hit!(your_stack_belongs_to_me);
95 return None; 104 return None;
96 } 105 }
97 106
@@ -118,8 +127,6 @@ impl Expander {
118 self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); 127 self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id);
119 self.current_file_id = file_id; 128 self.current_file_id = file_id;
120 self.ast_id_map = db.ast_id_map(file_id); 129 self.ast_id_map = db.ast_id_map(file_id);
121 self.recursive_limit += 1;
122
123 return Some((mark, expr)); 130 return Some((mark, expr));
124 } 131 }
125 } 132 }
@@ -134,7 +141,7 @@ impl Expander {
134 self.cfg_expander.hygiene = Hygiene::new(db.upcast(), mark.file_id); 141 self.cfg_expander.hygiene = Hygiene::new(db.upcast(), mark.file_id);
135 self.current_file_id = mark.file_id; 142 self.current_file_id = mark.file_id;
136 self.ast_id_map = mem::take(&mut mark.ast_id_map); 143 self.ast_id_map = mem::take(&mut mark.ast_id_map);
137 self.recursive_limit -= 1; 144 self.recursion_limit -= 1;
138 mark.bomb.defuse(); 145 mark.bomb.defuse();
139 } 146 }
140 147
@@ -302,7 +309,53 @@ impl BodySourceMap {
302 self.pat_map.get(&src).cloned() 309 self.pat_map.get(&src).cloned()
303 } 310 }
304 311
312 pub fn node_self_param(&self, node: InFile<&ast::SelfParam>) -> Option<PatId> {
313 let src = node.map(|it| Either::Right(AstPtr::new(it)));
314 self.pat_map.get(&src).cloned()
315 }
316
305 pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordField>> { 317 pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordField>> {
306 self.field_map[&(expr, field)].clone() 318 self.field_map[&(expr, field)].clone()
307 } 319 }
308} 320}
321
322#[cfg(test)]
323mod tests {
324 use ra_db::{fixture::WithFixture, SourceDatabase};
325 use test_utils::mark;
326
327 use crate::ModuleDefId;
328
329 use super::*;
330
331 fn lower(ra_fixture: &str) -> Arc<Body> {
332 let (db, file_id) = crate::test_db::TestDB::with_single_file(ra_fixture);
333
334 let krate = db.crate_graph().iter().next().unwrap();
335 let def_map = db.crate_def_map(krate);
336 let module = def_map.modules_for_file(file_id).next().unwrap();
337 let module = &def_map[module];
338 let fn_def = match module.scope.declarations().next().unwrap() {
339 ModuleDefId::FunctionId(it) => it,
340 _ => panic!(),
341 };
342
343 db.body(fn_def.into())
344 }
345
346 #[test]
347 fn your_stack_belongs_to_me() {
348 mark::check!(your_stack_belongs_to_me);
349 lower(
350 "
351macro_rules! n_nuple {
352 ($e:tt) => ();
353 ($($rest:tt)*) => {{
354 (n_nuple!($($rest)*)None,)
355 }};
356}
357fn main() { n_nuple!(1,2,3); }
358",
359 );
360 }
361}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 282ade2a3..88a8ef9bf 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -27,11 +27,12 @@ pub struct FunctionData {
27 /// can be called as a method. 27 /// can be called as a method.
28 pub has_self_param: bool, 28 pub has_self_param: bool,
29 pub is_unsafe: bool, 29 pub is_unsafe: bool,
30 pub is_varargs: bool,
30 pub visibility: RawVisibility, 31 pub visibility: RawVisibility,
31} 32}
32 33
33impl FunctionData { 34impl FunctionData {
34 pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { 35 pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> {
35 let loc = func.lookup(db); 36 let loc = func.lookup(db);
36 let item_tree = db.item_tree(loc.id.file_id); 37 let item_tree = db.item_tree(loc.id.file_id);
37 let func = &item_tree[loc.id.value]; 38 let func = &item_tree[loc.id.value];
@@ -43,6 +44,7 @@ impl FunctionData {
43 attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), 44 attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(),
44 has_self_param: func.has_self_param, 45 has_self_param: func.has_self_param,
45 is_unsafe: func.is_unsafe, 46 is_unsafe: func.is_unsafe,
47 is_varargs: func.is_varargs,
46 visibility: item_tree[func.visibility].clone(), 48 visibility: item_tree[func.visibility].clone(),
47 }) 49 })
48 } 50 }
diff --git a/crates/ra_hir_def/src/import_map.rs b/crates/ra_hir_def/src/import_map.rs
index 869f3ca5a..9e4c30b1a 100644
--- a/crates/ra_hir_def/src/import_map.rs
+++ b/crates/ra_hir_def/src/import_map.rs
@@ -327,32 +327,14 @@ pub fn search_dependencies<'a>(
327 327
328#[cfg(test)] 328#[cfg(test)]
329mod tests { 329mod tests {
330 use super::*; 330 use expect::{expect, Expect};
331 use crate::{test_db::TestDB, AssocContainerId, Lookup}; 331 use ra_db::{fixture::WithFixture, SourceDatabase, Upcast};
332 use insta::assert_snapshot;
333 use itertools::Itertools;
334 use ra_db::fixture::WithFixture;
335 use ra_db::{SourceDatabase, Upcast};
336 332
337 fn import_map(ra_fixture: &str) -> String { 333 use crate::{test_db::TestDB, AssocContainerId, Lookup};
338 let db = TestDB::with_files(ra_fixture);
339 let crate_graph = db.crate_graph();
340
341 let s = crate_graph
342 .iter()
343 .filter_map(|krate| {
344 let cdata = &crate_graph[krate];
345 let name = cdata.display_name.as_ref()?;
346
347 let map = db.import_map(krate);
348 334
349 Some(format!("{}:\n{:?}", name, map)) 335 use super::*;
350 })
351 .join("\n");
352 s
353 }
354 336
355 fn search_dependencies_of(ra_fixture: &str, krate_name: &str, query: Query) -> String { 337 fn check_search(ra_fixture: &str, krate_name: &str, query: Query, expect: Expect) {
356 let db = TestDB::with_files(ra_fixture); 338 let db = TestDB::with_files(ra_fixture);
357 let crate_graph = db.crate_graph(); 339 let crate_graph = db.crate_graph();
358 let krate = crate_graph 340 let krate = crate_graph
@@ -363,7 +345,7 @@ mod tests {
363 }) 345 })
364 .unwrap(); 346 .unwrap();
365 347
366 search_dependencies(db.upcast(), krate, query) 348 let actual = search_dependencies(db.upcast(), krate, query)
367 .into_iter() 349 .into_iter()
368 .filter_map(|item| { 350 .filter_map(|item| {
369 let mark = match item { 351 let mark = match item {
@@ -376,14 +358,15 @@ mod tests {
376 let map = db.import_map(krate); 358 let map = db.import_map(krate);
377 let path = map.path_of(item).unwrap(); 359 let path = map.path_of(item).unwrap();
378 format!( 360 format!(
379 "{}::{} ({})", 361 "{}::{} ({})\n",
380 crate_graph[krate].display_name.as_ref().unwrap(), 362 crate_graph[krate].display_name.as_ref().unwrap(),
381 path, 363 path,
382 mark 364 mark
383 ) 365 )
384 }) 366 })
385 }) 367 })
386 .join("\n") 368 .collect::<String>();
369 expect.assert_eq(&actual)
387 } 370 }
388 371
389 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs { 372 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs {
@@ -409,9 +392,28 @@ mod tests {
409 } 392 }
410 } 393 }
411 394
395 fn check(ra_fixture: &str, expect: Expect) {
396 let db = TestDB::with_files(ra_fixture);
397 let crate_graph = db.crate_graph();
398
399 let actual = crate_graph
400 .iter()
401 .filter_map(|krate| {
402 let cdata = &crate_graph[krate];
403 let name = cdata.display_name.as_ref()?;
404
405 let map = db.import_map(krate);
406
407 Some(format!("{}:\n{:?}\n", name, map))
408 })
409 .collect::<String>();
410
411 expect.assert_eq(&actual)
412 }
413
412 #[test] 414 #[test]
413 fn smoke() { 415 fn smoke() {
414 let map = import_map( 416 check(
415 r" 417 r"
416 //- /main.rs crate:main deps:lib 418 //- /main.rs crate:main deps:lib
417 419
@@ -436,24 +438,23 @@ mod tests {
436 pub struct Pub2; // t + v 438 pub struct Pub2; // t + v
437 struct Priv; 439 struct Priv;
438 ", 440 ",
441 expect![[r#"
442 main:
443 - publ1 (t)
444 - real_pu2 (t)
445 - real_pub (t)
446 - real_pub::Pub (t)
447 lib:
448 - Pub (t)
449 - Pub2 (t)
450 - Pub2 (v)
451 "#]],
439 ); 452 );
440
441 assert_snapshot!(map, @r###"
442 main:
443 - publ1 (t)
444 - real_pu2 (t)
445 - real_pub (t)
446 - real_pub::Pub (t)
447 lib:
448 - Pub (t)
449 - Pub2 (t)
450 - Pub2 (v)
451 "###);
452 } 453 }
453 454
454 #[test] 455 #[test]
455 fn prefers_shortest_path() { 456 fn prefers_shortest_path() {
456 let map = import_map( 457 check(
457 r" 458 r"
458 //- /main.rs crate:main 459 //- /main.rs crate:main
459 460
@@ -465,21 +466,20 @@ mod tests {
465 pub use super::sub::subsub::Def; 466 pub use super::sub::subsub::Def;
466 } 467 }
467 ", 468 ",
469 expect![[r#"
470 main:
471 - sub (t)
472 - sub::Def (t)
473 - sub::subsub (t)
474 "#]],
468 ); 475 );
469
470 assert_snapshot!(map, @r###"
471 main:
472 - sub (t)
473 - sub::Def (t)
474 - sub::subsub (t)
475 "###);
476 } 476 }
477 477
478 #[test] 478 #[test]
479 fn type_reexport_cross_crate() { 479 fn type_reexport_cross_crate() {
480 // Reexports need to be visible from a crate, even if the original crate exports the item 480 // Reexports need to be visible from a crate, even if the original crate exports the item
481 // at a shorter path. 481 // at a shorter path.
482 let map = import_map( 482 check(
483 r" 483 r"
484 //- /main.rs crate:main deps:lib 484 //- /main.rs crate:main deps:lib
485 pub mod m { 485 pub mod m {
@@ -488,22 +488,21 @@ mod tests {
488 //- /lib.rs crate:lib 488 //- /lib.rs crate:lib
489 pub struct S; 489 pub struct S;
490 ", 490 ",
491 expect![[r#"
492 main:
493 - m (t)
494 - m::S (t)
495 - m::S (v)
496 lib:
497 - S (t)
498 - S (v)
499 "#]],
491 ); 500 );
492
493 assert_snapshot!(map, @r###"
494 main:
495 - m (t)
496 - m::S (t)
497 - m::S (v)
498 lib:
499 - S (t)
500 - S (v)
501 "###);
502 } 501 }
503 502
504 #[test] 503 #[test]
505 fn macro_reexport() { 504 fn macro_reexport() {
506 let map = import_map( 505 check(
507 r" 506 r"
508 //- /main.rs crate:main deps:lib 507 //- /main.rs crate:main deps:lib
509 pub mod m { 508 pub mod m {
@@ -515,21 +514,20 @@ mod tests {
515 () => {}; 514 () => {};
516 } 515 }
517 ", 516 ",
517 expect![[r#"
518 main:
519 - m (t)
520 - m::pub_macro (m)
521 lib:
522 - pub_macro (m)
523 "#]],
518 ); 524 );
519
520 assert_snapshot!(map, @r###"
521 main:
522 - m (t)
523 - m::pub_macro (m)
524 lib:
525 - pub_macro (m)
526 "###);
527 } 525 }
528 526
529 #[test] 527 #[test]
530 fn module_reexport() { 528 fn module_reexport() {
531 // Reexporting modules from a dependency adds all contents to the import map. 529 // Reexporting modules from a dependency adds all contents to the import map.
532 let map = import_map( 530 check(
533 r" 531 r"
534 //- /main.rs crate:main deps:lib 532 //- /main.rs crate:main deps:lib
535 pub use lib::module as reexported_module; 533 pub use lib::module as reexported_module;
@@ -538,24 +536,23 @@ mod tests {
538 pub struct S; 536 pub struct S;
539 } 537 }
540 ", 538 ",
539 expect![[r#"
540 main:
541 - reexported_module (t)
542 - reexported_module::S (t)
543 - reexported_module::S (v)
544 lib:
545 - module (t)
546 - module::S (t)
547 - module::S (v)
548 "#]],
541 ); 549 );
542
543 assert_snapshot!(map, @r###"
544 main:
545 - reexported_module (t)
546 - reexported_module::S (t)
547 - reexported_module::S (v)
548 lib:
549 - module (t)
550 - module::S (t)
551 - module::S (v)
552 "###);
553 } 550 }
554 551
555 #[test] 552 #[test]
556 fn cyclic_module_reexport() { 553 fn cyclic_module_reexport() {
557 // A cyclic reexport does not hang. 554 // A cyclic reexport does not hang.
558 let map = import_map( 555 check(
559 r" 556 r"
560 //- /lib.rs crate:lib 557 //- /lib.rs crate:lib
561 pub mod module { 558 pub mod module {
@@ -567,36 +564,35 @@ mod tests {
567 pub use super::module; 564 pub use super::module;
568 } 565 }
569 ", 566 ",
567 expect![[r#"
568 lib:
569 - module (t)
570 - module::S (t)
571 - module::S (v)
572 - sub (t)
573 "#]],
570 ); 574 );
571
572 assert_snapshot!(map, @r###"
573 lib:
574 - module (t)
575 - module::S (t)
576 - module::S (v)
577 - sub (t)
578 "###);
579 } 575 }
580 576
581 #[test] 577 #[test]
582 fn private_macro() { 578 fn private_macro() {
583 let map = import_map( 579 check(
584 r" 580 r"
585 //- /lib.rs crate:lib 581 //- /lib.rs crate:lib
586 macro_rules! private_macro { 582 macro_rules! private_macro {
587 () => {}; 583 () => {};
588 } 584 }
589 ", 585 ",
590 ); 586 expect![[r#"
587 lib:
591 588
592 assert_snapshot!(map, @r###" 589 "#]],
593 lib: 590 );
594 "###);
595 } 591 }
596 592
597 #[test] 593 #[test]
598 fn namespacing() { 594 fn namespacing() {
599 let map = import_map( 595 check(
600 r" 596 r"
601 //- /lib.rs crate:lib 597 //- /lib.rs crate:lib
602 pub struct Thing; // t + v 598 pub struct Thing; // t + v
@@ -605,16 +601,15 @@ mod tests {
605 () => {}; 601 () => {};
606 } 602 }
607 ", 603 ",
604 expect![[r#"
605 lib:
606 - Thing (m)
607 - Thing (t)
608 - Thing (v)
609 "#]],
608 ); 610 );
609 611
610 assert_snapshot!(map, @r###" 612 check(
611 lib:
612 - Thing (m)
613 - Thing (t)
614 - Thing (v)
615 "###);
616
617 let map = import_map(
618 r" 613 r"
619 //- /lib.rs crate:lib 614 //- /lib.rs crate:lib
620 pub mod Thing {} // t 615 pub mod Thing {} // t
@@ -623,13 +618,12 @@ mod tests {
623 () => {}; 618 () => {};
624 } 619 }
625 ", 620 ",
621 expect![[r#"
622 lib:
623 - Thing (m)
624 - Thing (t)
625 "#]],
626 ); 626 );
627
628 assert_snapshot!(map, @r###"
629 lib:
630 - Thing (m)
631 - Thing (t)
632 "###);
633 } 627 }
634 628
635 #[test] 629 #[test]
@@ -658,25 +652,33 @@ mod tests {
658 } 652 }
659 "#; 653 "#;
660 654
661 let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt")); 655 check_search(
662 assert_snapshot!(res, @r###" 656 ra_fixture,
663 dep::fmt (t) 657 "main",
664 dep::Fmt (t) 658 Query::new("fmt"),
665 dep::Fmt (v) 659 expect![[r#"
666 dep::Fmt (m) 660 dep::fmt (t)
667 dep::fmt::Display (t) 661 dep::Fmt (t)
668 dep::format (v) 662 dep::Fmt (v)
669 dep::fmt::Display (t) 663 dep::Fmt (m)
670 "###); 664 dep::fmt::Display (t)
671 665 dep::format (v)
672 let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt").anchor_end()); 666 dep::fmt::Display (t)
673 assert_snapshot!(res, @r###" 667 "#]],
674 dep::fmt (t) 668 );
675 dep::Fmt (t) 669
676 dep::Fmt (v) 670 check_search(
677 dep::Fmt (m) 671 ra_fixture,
678 dep::fmt::Display (t) 672 "main",
679 "###); 673 Query::new("fmt").anchor_end(),
674 expect![[r#"
675 dep::fmt (t)
676 dep::Fmt (t)
677 dep::Fmt (v)
678 dep::Fmt (m)
679 dep::fmt::Display (t)
680 "#]],
681 );
680 } 682 }
681 683
682 #[test] 684 #[test]
@@ -689,26 +691,32 @@ mod tests {
689 pub struct FMT; 691 pub struct FMT;
690 "#; 692 "#;
691 693
692 let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT")); 694 check_search(
693 695 ra_fixture,
694 assert_snapshot!(res, @r###" 696 "main",
695 dep::fmt (t) 697 Query::new("FMT"),
696 dep::fmt (v) 698 expect![[r#"
697 dep::FMT (t) 699 dep::fmt (t)
698 dep::FMT (v) 700 dep::fmt (v)
699 "###); 701 dep::FMT (t)
700 702 dep::FMT (v)
701 let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT").case_sensitive()); 703 "#]],
704 );
702 705
703 assert_snapshot!(res, @r###" 706 check_search(
704 dep::FMT (t) 707 ra_fixture,
705 dep::FMT (v) 708 "main",
706 "###); 709 Query::new("FMT").case_sensitive(),
710 expect![[r#"
711 dep::FMT (t)
712 dep::FMT (v)
713 "#]],
714 );
707 } 715 }
708 716
709 #[test] 717 #[test]
710 fn search_limit() { 718 fn search_limit() {
711 let res = search_dependencies_of( 719 check_search(
712 r#" 720 r#"
713 //- /main.rs crate:main deps:dep 721 //- /main.rs crate:main deps:dep
714 //- /dep.rs crate:dep 722 //- /dep.rs crate:dep
@@ -728,10 +736,10 @@ mod tests {
728 "#, 736 "#,
729 "main", 737 "main",
730 Query::new("").limit(2), 738 Query::new("").limit(2),
739 expect![[r#"
740 dep::fmt (t)
741 dep::Fmt (t)
742 "#]],
731 ); 743 );
732 assert_snapshot!(res, @r###"
733 dep::fmt (t)
734 dep::Fmt (t)
735 "###);
736 } 744 }
737} 745}
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index 3e603bd55..da79d8ffd 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -503,6 +503,7 @@ pub struct Function {
503 pub has_self_param: bool, 503 pub has_self_param: bool,
504 pub is_unsafe: bool, 504 pub is_unsafe: bool,
505 pub params: Box<[TypeRef]>, 505 pub params: Box<[TypeRef]>,
506 pub is_varargs: bool,
506 pub ret_type: TypeRef, 507 pub ret_type: TypeRef,
507 pub ast_id: FileAstId<ast::FnDef>, 508 pub ast_id: FileAstId<ast::FnDef>,
508} 509}
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index 06743d7fc..f79b8fca3 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -219,21 +219,20 @@ impl Ctx {
219 fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldDefList) -> IdRange<Field> { 219 fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldDefList) -> IdRange<Field> {
220 let start = self.next_field_idx(); 220 let start = self.next_field_idx();
221 for (i, field) in fields.fields().enumerate() { 221 for (i, field) in fields.fields().enumerate() {
222 if let Some(data) = self.lower_tuple_field(i, &field) { 222 let data = self.lower_tuple_field(i, &field);
223 let idx = self.data().fields.alloc(data); 223 let idx = self.data().fields.alloc(data);
224 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); 224 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
225 }
226 } 225 }
227 let end = self.next_field_idx(); 226 let end = self.next_field_idx();
228 IdRange::new(start..end) 227 IdRange::new(start..end)
229 } 228 }
230 229
231 fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleFieldDef) -> Option<Field> { 230 fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleFieldDef) -> Field {
232 let name = Name::new_tuple_field(idx); 231 let name = Name::new_tuple_field(idx);
233 let visibility = self.lower_visibility(field); 232 let visibility = self.lower_visibility(field);
234 let type_ref = self.lower_type_ref(&field.type_ref()?); 233 let type_ref = self.lower_type_ref_opt(field.type_ref());
235 let res = Field { name, type_ref, visibility }; 234 let res = Field { name, type_ref, visibility };
236 Some(res) 235 res
237 } 236 }
238 237
239 fn lower_union(&mut self, union: &ast::UnionDef) -> Option<FileItemTreeId<Union>> { 238 fn lower_union(&mut self, union: &ast::UnionDef) -> Option<FileItemTreeId<Union>> {
@@ -314,6 +313,14 @@ impl Ctx {
314 params.push(type_ref); 313 params.push(type_ref);
315 } 314 }
316 } 315 }
316
317 let mut is_varargs = false;
318 if let Some(params) = func.param_list() {
319 if let Some(last) = params.params().last() {
320 is_varargs = last.dotdotdot_token().is_some();
321 }
322 }
323
317 let ret_type = match func.ret_type().and_then(|rt| rt.type_ref()) { 324 let ret_type = match func.ret_type().and_then(|rt| rt.type_ref()) {
318 Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), 325 Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
319 _ => TypeRef::unit(), 326 _ => TypeRef::unit(),
@@ -335,6 +342,7 @@ impl Ctx {
335 has_self_param, 342 has_self_param,
336 is_unsafe: func.unsafe_token().is_some(), 343 is_unsafe: func.unsafe_token().is_some(),
337 params: params.into_boxed_slice(), 344 params: params.into_boxed_slice(),
345 is_varargs,
338 ret_type, 346 ret_type,
339 ast_id, 347 ast_id,
340 }; 348 };
@@ -450,8 +458,9 @@ impl Ctx {
450 458
451 // We cannot use `assoc_items()` here as that does not include macro calls. 459 // We cannot use `assoc_items()` here as that does not include macro calls.
452 let items = impl_def 460 let items = impl_def
453 .item_list()? 461 .item_list()
454 .items() 462 .into_iter()
463 .flat_map(|it| it.items())
455 .filter_map(|item| { 464 .filter_map(|item| {
456 self.collect_inner_items(item.syntax()); 465 self.collect_inner_items(item.syntax());
457 let assoc = self.lower_assoc_item(&item)?; 466 let assoc = self.lower_assoc_item(&item)?;
@@ -545,6 +554,7 @@ impl Ctx {
545 let id: ModItem = match item { 554 let id: ModItem = match item {
546 ast::ExternItem::FnDef(ast) => { 555 ast::ExternItem::FnDef(ast) => {
547 let func = self.lower_function(&ast)?; 556 let func = self.lower_function(&ast)?;
557 self.data().functions[func.index].is_unsafe = true;
548 func.into() 558 func.into()
549 } 559 }
550 ast::ExternItem::StaticDef(ast) => { 560 ast::ExternItem::StaticDef(ast) => {
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs
index 08559fb92..f26982985 100644
--- a/crates/ra_hir_def/src/item_tree/tests.rs
+++ b/crates/ra_hir_def/src/item_tree/tests.rs
@@ -1,13 +1,15 @@
1use super::{ItemTree, ModItem, ModKind}; 1use expect::{expect, Expect};
2use crate::{db::DefDatabase, test_db::TestDB};
3use hir_expand::{db::AstDatabase, HirFileId, InFile}; 2use hir_expand::{db::AstDatabase, HirFileId, InFile};
4use insta::assert_snapshot;
5use ra_db::fixture::WithFixture; 3use ra_db::fixture::WithFixture;
6use ra_syntax::{ast, AstNode}; 4use ra_syntax::{ast, AstNode};
7use rustc_hash::FxHashSet; 5use rustc_hash::FxHashSet;
8use std::sync::Arc; 6use std::sync::Arc;
9use stdx::format_to; 7use stdx::format_to;
10 8
9use crate::{db::DefDatabase, test_db::TestDB};
10
11use super::{ItemTree, ModItem, ModKind};
12
11fn test_inner_items(ra_fixture: &str) { 13fn test_inner_items(ra_fixture: &str) {
12 let (db, file_id) = TestDB::with_single_file(ra_fixture); 14 let (db, file_id) = TestDB::with_single_file(ra_fixture);
13 let file_id = HirFileId::from(file_id); 15 let file_id = HirFileId::from(file_id);
@@ -162,9 +164,15 @@ fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) {
162 } 164 }
163} 165}
164 166
167fn check(ra_fixture: &str, expect: Expect) {
168 let actual = print_item_tree(ra_fixture);
169 expect.assert_eq(&actual);
170}
171
165#[test] 172#[test]
166fn smoke() { 173fn smoke() {
167 assert_snapshot!(print_item_tree(r" 174 check(
175 r"
168 #![attr] 176 #![attr]
169 177
170 #[attr_on_use] 178 #[attr_on_use]
@@ -214,42 +222,44 @@ fn smoke() {
214 #[union_fld] 222 #[union_fld]
215 fld: u16, 223 fld: u16,
216 } 224 }
217 "), @r###" 225 ",
218inner attrs: Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr"))] }, input: None }]) } 226 expect![[r##"
219 227 inner attrs: Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr"))] }, input: None }]) }
220top-level items: 228
221#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }] 229 top-level items:
222Import { path: ModPath { kind: Plain, segments: [Name(Text("a"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_glob: false, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } 230 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }]
223#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }] 231 Import { path: ModPath { kind: Plain, segments: [Name(Text("a"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_glob: false, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) }
224Import { path: ModPath { kind: Plain, segments: [Name(Text("b"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_glob: true, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } 232 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }]
225#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("ext_crate"))] }, input: None }]) }] 233 Import { path: ModPath { kind: Plain, segments: [Name(Text("b"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_glob: true, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) }
226ExternCrate { path: ModPath { kind: Plain, segments: [Name(Text("krate"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_macro_use: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ExternCrateItem>(1) } 234 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("ext_crate"))] }, input: None }]) }]
227#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_trait"))] }, input: None }]) }] 235 ExternCrate { path: ModPath { kind: Plain, segments: [Name(Text("krate"))] }, alias: None, visibility: RawVisibilityId("pub(self)"), is_macro_use: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ExternCrateItem>(1) }
228Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [TypeAlias(Idx::<TypeAlias>(0)), Const(Idx::<Const>(0)), Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(2) } 236 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_trait"))] }, input: None }]) }]
229> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_ty"))] }, input: None }]) }] 237 Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [TypeAlias(Idx::<TypeAlias>(0)), Const(Idx::<Const>(0)), Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(2) }
230> TypeAlias { name: Name(Text("AssocTy")), visibility: RawVisibilityId("pub(self)"), bounds: [Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Tr"))] }, generic_args: [Some(GenericArgs { args: [Type(Tuple([]))], has_self_type: false, bindings: [] })] })], generic_params: GenericParamsId(4294967295), type_ref: None, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TypeAliasDef>(8) } 238 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_ty"))] }, input: None }]) }]
231> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }] 239 > TypeAlias { name: Name(Text("AssocTy")), visibility: RawVisibilityId("pub(self)"), bounds: [Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Tr"))] }, generic_args: [Some(GenericArgs { args: [Type(Tuple([]))], has_self_type: false, bindings: [] })] })], generic_params: GenericParamsId(4294967295), type_ref: None, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TypeAliasDef>(8) }
232> Const { name: Some(Name(Text("CONST"))), visibility: RawVisibilityId("pub(self)"), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ConstDef>(9) } 240 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }]
233> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }] 241 > Const { name: Some(Name(Text("CONST"))), visibility: RawVisibilityId("pub(self)"), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ConstDef>(9) }
234> Function { name: Name(Text("method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Shared)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(10) } 242 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }]
235> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_dfl_method"))] }, input: None }]) }] 243 > Function { name: Name(Text("method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Shared)], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(10) }
236> Function { name: Name(Text("dfl_method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Mut)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(11) } 244 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_dfl_method"))] }, input: None }]) }]
237#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }] 245 > Function { name: Name(Text("dfl_method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Mut)], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(11) }
238Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } 246 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }]
239#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }] 247 Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit }
240Struct { name: Name(Text("Struct1")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(2), fields: Tuple(IdRange::<ra_hir_def::item_tree::Field>(0..1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple } 248 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }]
241#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct2"))] }, input: None }]) }] 249 Struct { name: Name(Text("Struct1")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(2), fields: Tuple(IdRange::<ra_hir_def::item_tree::Field>(0..1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple }
242Struct { name: Name(Text("Struct2")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(3), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(1..2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record } 250 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct2"))] }, input: None }]) }]
243#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("en"))] }, input: None }]) }] 251 Struct { name: Name(Text("Struct2")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(3), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(1..2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record }
244Enum { name: Name(Text("En")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), variants: IdRange::<ra_hir_def::item_tree::Variant>(0..1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) } 252 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("en"))] }, input: None }]) }]
245#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("un"))] }, input: None }]) }] 253 Enum { name: Name(Text("En")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), variants: IdRange::<ra_hir_def::item_tree::Variant>(0..1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) }
246Union { name: Name(Text("Un")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(3..4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) } 254 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("un"))] }, input: None }]) }]
247 "###); 255 Union { name: Name(Text("Un")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(3..4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) }
256 "##]],
257 );
248} 258}
249 259
250#[test] 260#[test]
251fn simple_inner_items() { 261fn simple_inner_items() {
252 let tree = print_item_tree( 262 check(
253 r" 263 r"
254 impl<T:A> D for Response<T> { 264 impl<T:A> D for Response<T> {
255 fn foo() { 265 fn foo() {
@@ -260,26 +270,25 @@ fn simple_inner_items() {
260 } 270 }
261 } 271 }
262 ", 272 ",
263 ); 273 expect![[r#"
274 inner attrs: Attrs { entries: None }
264 275
265 assert_snapshot!(tree, @r###" 276 top-level items:
266inner attrs: Attrs { entries: None } 277 Impl { generic_params: GenericParamsId(0), target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
278 > Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
267 279
268top-level items: 280 inner items:
269Impl { generic_params: GenericParamsId(0), target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
270> Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
271 281
272inner items: 282 for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2):
283 Function { name: Name(Text("end")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
273 284
274for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): 285 "#]],
275Function { name: Name(Text("end")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } 286 );
276
277 "###);
278} 287}
279 288
280#[test] 289#[test]
281fn extern_attrs() { 290fn extern_attrs() {
282 let tree = print_item_tree( 291 check(
283 r#" 292 r#"
284 #[block_attr] 293 #[block_attr]
285 extern "C" { 294 extern "C" {
@@ -289,22 +298,21 @@ fn extern_attrs() {
289 fn b() {} 298 fn b() {}
290 } 299 }
291 "#, 300 "#,
301 expect![[r##"
302 inner attrs: Attrs { entries: None }
303
304 top-level items:
305 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }]
306 Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
307 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }]
308 Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
309 "##]],
292 ); 310 );
293
294 assert_snapshot!(tree, @r###"
295inner attrs: Attrs { entries: None }
296
297top-level items:
298#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }]
299Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
300#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }]
301Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
302 "###);
303} 311}
304 312
305#[test] 313#[test]
306fn trait_attrs() { 314fn trait_attrs() {
307 let tree = print_item_tree( 315 check(
308 r#" 316 r#"
309 #[trait_attr] 317 #[trait_attr]
310 trait Tr { 318 trait Tr {
@@ -314,24 +322,23 @@ fn trait_attrs() {
314 fn b() {} 322 fn b() {}
315 } 323 }
316 "#, 324 "#,
325 expect![[r##"
326 inner attrs: Attrs { entries: None }
327
328 top-level items:
329 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }]
330 Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(0) }
331 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }]
332 > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
333 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }]
334 > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
335 "##]],
317 ); 336 );
318
319 assert_snapshot!(tree, @r###"
320inner attrs: Attrs { entries: None }
321
322top-level items:
323#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }]
324Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(0) }
325> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }]
326> Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
327> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }]
328> Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
329 "###);
330} 337}
331 338
332#[test] 339#[test]
333fn impl_attrs() { 340fn impl_attrs() {
334 let tree = print_item_tree( 341 check(
335 r#" 342 r#"
336 #[impl_attr] 343 #[impl_attr]
337 impl Ty { 344 impl Ty {
@@ -341,19 +348,18 @@ fn impl_attrs() {
341 fn b() {} 348 fn b() {}
342 } 349 }
343 "#, 350 "#,
351 expect![[r##"
352 inner attrs: Attrs { entries: None }
353
354 top-level items:
355 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }]
356 Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Ty"))] }, generic_args: [None] }), is_negative: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
357 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }]
358 > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
359 > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }]
360 > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
361 "##]],
344 ); 362 );
345
346 assert_snapshot!(tree, @r###"
347inner attrs: Attrs { entries: None }
348
349top-level items:
350#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }]
351Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Ty"))] }, generic_args: [None] }), is_negative: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
352> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }]
353> Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
354> #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }]
355> Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) }
356 "###);
357} 363}
358 364
359#[test] 365#[test]
@@ -391,45 +397,43 @@ fn cursed_inner_items() {
391 397
392#[test] 398#[test]
393fn inner_item_attrs() { 399fn inner_item_attrs() {
394 let tree = print_item_tree( 400 check(
395 r" 401 r"
396 fn foo() { 402 fn foo() {
397 #[on_inner] 403 #[on_inner]
398 fn inner() {} 404 fn inner() {}
399 } 405 }
400 ", 406 ",
401 ); 407 expect![[r##"
402 408 inner attrs: Attrs { entries: None }
403 assert_snapshot!(tree, @r###"
404inner attrs: Attrs { entries: None }
405 409
406top-level items: 410 top-level items:
407Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(0) } 411 Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(0) }
408 412
409inner items: 413 inner items:
410 414
411for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(1): 415 for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(1):
412#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_inner"))] }, input: None }]) }] 416 #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_inner"))] }, input: None }]) }]
413Function { name: Name(Text("inner")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } 417 Function { name: Name(Text("inner")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) }
414 418
415 "###); 419 "##]],
420 );
416} 421}
417 422
418#[test] 423#[test]
419fn assoc_item_macros() { 424fn assoc_item_macros() {
420 let tree = print_item_tree( 425 check(
421 r" 426 r"
422 impl S { 427 impl S {
423 items!(); 428 items!();
424 } 429 }
425 ", 430 ",
426 ); 431 expect![[r#"
427 432 inner attrs: Attrs { entries: None }
428 assert_snapshot!(tree, @r###"
429inner attrs: Attrs { entries: None }
430 433
431top-level items: 434 top-level items:
432Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("S"))] }, generic_args: [None] }), is_negative: false, items: [MacroCall(Idx::<MacroCall>(0))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } 435 Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("S"))] }, generic_args: [None] }), is_negative: false, items: [MacroCall(Idx::<MacroCall>(0))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
433> MacroCall { name: None, path: ModPath { kind: Plain, segments: [Name(Text("items"))] }, is_export: false, is_local_inner: false, is_builtin: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::MacroCall>(1) } 436 > MacroCall { name: None, path: ModPath { kind: Plain, segments: [Name(Text("items"))] }, is_export: false, is_local_inner: false, is_builtin: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::MacroCall>(1) }
434 "###); 437 "#]],
438 );
435} 439}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 564434ccc..87000fe98 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -65,6 +65,7 @@ use item_tree::{
65 Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, 65 Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
66 TypeAlias, Union, 66 TypeAlias, Union,
67}; 67};
68use stdx::impl_from;
68 69
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70pub struct ModuleId { 71pub struct ModuleId {
@@ -158,17 +159,17 @@ pub struct FunctionId(salsa::InternId);
158type FunctionLoc = AssocItemLoc<Function>; 159type FunctionLoc = AssocItemLoc<Function>;
159impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); 160impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
160 161
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
162pub struct StructId(salsa::InternId); 163pub struct StructId(salsa::InternId);
163type StructLoc = ItemLoc<Struct>; 164type StructLoc = ItemLoc<Struct>;
164impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); 165impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
165 166
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
167pub struct UnionId(salsa::InternId); 168pub struct UnionId(salsa::InternId);
168pub type UnionLoc = ItemLoc<Union>; 169pub type UnionLoc = ItemLoc<Union>;
169impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); 170impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
170 171
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
172pub struct EnumId(salsa::InternId); 173pub struct EnumId(salsa::InternId);
173pub type EnumLoc = ItemLoc<Enum>; 174pub type EnumLoc = ItemLoc<Enum>;
174impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); 175impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
@@ -223,25 +224,6 @@ pub struct TypeParamId {
223 224
224pub type LocalTypeParamId = Idx<generics::TypeParamData>; 225pub type LocalTypeParamId = Idx<generics::TypeParamData>;
225 226
226macro_rules! impl_froms {
227 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
228 $(
229 impl From<$v> for $e {
230 fn from(it: $v) -> $e {
231 $e::$v(it)
232 }
233 }
234 $($(
235 impl From<$sv> for $e {
236 fn from(it: $sv) -> $e {
237 $e::$v($v::$sv(it))
238 }
239 }
240 )*)?
241 )*
242 }
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 227#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
246pub enum ContainerId { 228pub enum ContainerId {
247 ModuleId(ModuleId), 229 ModuleId(ModuleId),
@@ -254,16 +236,16 @@ pub enum AssocContainerId {
254 ImplId(ImplId), 236 ImplId(ImplId),
255 TraitId(TraitId), 237 TraitId(TraitId),
256} 238}
257impl_froms!(AssocContainerId: ContainerId); 239impl_from!(ContainerId for AssocContainerId);
258 240
259/// A Data Type 241/// A Data Type
260#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 242#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
261pub enum AdtId { 243pub enum AdtId {
262 StructId(StructId), 244 StructId(StructId),
263 UnionId(UnionId), 245 UnionId(UnionId),
264 EnumId(EnumId), 246 EnumId(EnumId),
265} 247}
266impl_froms!(AdtId: StructId, UnionId, EnumId); 248impl_from!(StructId, UnionId, EnumId for AdtId);
267 249
268/// The defs which can be visible in the module. 250/// The defs which can be visible in the module.
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -279,8 +261,8 @@ pub enum ModuleDefId {
279 TypeAliasId(TypeAliasId), 261 TypeAliasId(TypeAliasId),
280 BuiltinType(BuiltinType), 262 BuiltinType(BuiltinType),
281} 263}
282impl_froms!( 264impl_from!(
283 ModuleDefId: ModuleId, 265 ModuleId,
284 FunctionId, 266 FunctionId,
285 AdtId(StructId, EnumId, UnionId), 267 AdtId(StructId, EnumId, UnionId),
286 EnumVariantId, 268 EnumVariantId,
@@ -289,6 +271,7 @@ impl_froms!(
289 TraitId, 271 TraitId,
290 TypeAliasId, 272 TypeAliasId,
291 BuiltinType 273 BuiltinType
274 for ModuleDefId
292); 275);
293 276
294/// The defs which have a body. 277/// The defs which have a body.
@@ -299,7 +282,7 @@ pub enum DefWithBodyId {
299 ConstId(ConstId), 282 ConstId(ConstId),
300} 283}
301 284
302impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); 285impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
303 286
304#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 287#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
305pub enum AssocItemId { 288pub enum AssocItemId {
@@ -311,7 +294,7 @@ pub enum AssocItemId {
311// sure that you can only turn actual assoc items into AssocItemIds. This would 294// sure that you can only turn actual assoc items into AssocItemIds. This would
312// require not implementing From, and instead having some checked way of 295// require not implementing From, and instead having some checked way of
313// casting them, and somehow making the constructors private, which would be annoying. 296// casting them, and somehow making the constructors private, which would be annoying.
314impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); 297impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
315 298
316#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 299#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
317pub enum GenericDefId { 300pub enum GenericDefId {
@@ -326,14 +309,15 @@ pub enum GenericDefId {
326 // consts can have type parameters from their parents (i.e. associated consts of traits) 309 // consts can have type parameters from their parents (i.e. associated consts of traits)
327 ConstId(ConstId), 310 ConstId(ConstId),
328} 311}
329impl_froms!( 312impl_from!(
330 GenericDefId: FunctionId, 313 FunctionId,
331 AdtId(StructId, EnumId, UnionId), 314 AdtId(StructId, EnumId, UnionId),
332 TraitId, 315 TraitId,
333 TypeAliasId, 316 TypeAliasId,
334 ImplId, 317 ImplId,
335 EnumVariantId, 318 EnumVariantId,
336 ConstId 319 ConstId
320 for GenericDefId
337); 321);
338 322
339impl From<AssocItemId> for GenericDefId { 323impl From<AssocItemId> for GenericDefId {
@@ -361,8 +345,8 @@ pub enum AttrDefId {
361 ImplId(ImplId), 345 ImplId(ImplId),
362} 346}
363 347
364impl_froms!( 348impl_from!(
365 AttrDefId: ModuleId, 349 ModuleId,
366 FieldId, 350 FieldId,
367 AdtId(StructId, EnumId, UnionId), 351 AdtId(StructId, EnumId, UnionId),
368 EnumVariantId, 352 EnumVariantId,
@@ -373,6 +357,7 @@ impl_froms!(
373 TypeAliasId, 357 TypeAliasId,
374 MacroDefId, 358 MacroDefId,
375 ImplId 359 ImplId
360 for AttrDefId
376); 361);
377 362
378#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 363#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -381,7 +366,7 @@ pub enum VariantId {
381 StructId(StructId), 366 StructId(StructId),
382 UnionId(UnionId), 367 UnionId(UnionId),
383} 368}
384impl_froms!(VariantId: EnumVariantId, StructId, UnionId); 369impl_from!(EnumVariantId, StructId, UnionId for VariantId);
385 370
386trait Intern { 371trait Intern {
387 type ID; 372 type ID;
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index b279bdeef..5a9de3d3e 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -229,12 +229,11 @@ impl CrateDefMap {
229 // even), as this should be a great debugging aid. 229 // even), as this should be a great debugging aid.
230 pub fn dump(&self) -> String { 230 pub fn dump(&self) -> String {
231 let mut buf = String::new(); 231 let mut buf = String::new();
232 go(&mut buf, self, "\ncrate", self.root); 232 go(&mut buf, self, "crate", self.root);
233 return buf.trim().to_string(); 233 return buf;
234 234
235 fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) { 235 fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) {
236 *buf += path; 236 format_to!(buf, "{}\n", path);
237 *buf += "\n";
238 237
239 let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect(); 238 let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect();
240 entries.sort_by_key(|(name, _)| name.clone()); 239 entries.sort_by_key(|(name, _)| name.clone());
@@ -243,23 +242,24 @@ impl CrateDefMap {
243 format_to!(buf, "{}:", name); 242 format_to!(buf, "{}:", name);
244 243
245 if def.types.is_some() { 244 if def.types.is_some() {
246 *buf += " t"; 245 buf.push_str(" t");
247 } 246 }
248 if def.values.is_some() { 247 if def.values.is_some() {
249 *buf += " v"; 248 buf.push_str(" v");
250 } 249 }
251 if def.macros.is_some() { 250 if def.macros.is_some() {
252 *buf += " m"; 251 buf.push_str(" m");
253 } 252 }
254 if def.is_none() { 253 if def.is_none() {
255 *buf += " _"; 254 buf.push_str(" _");
256 } 255 }
257 256
258 *buf += "\n"; 257 buf.push_str("\n");
259 } 258 }
260 259
261 for (name, child) in map.modules[module].children.iter() { 260 for (name, child) in map.modules[module].children.iter() {
262 let path = &format!("{}::{}", path, name); 261 let path = format!("{}::{}", path, name);
262 buf.push('\n');
263 go(buf, map, &path, *child); 263 go(buf, map, &path, *child);
264 } 264 }
265 } 265 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index a35ac1024..d85a86c0a 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -36,6 +36,10 @@ use crate::{
36 TraitLoc, TypeAliasLoc, UnionLoc, 36 TraitLoc, TypeAliasLoc, UnionLoc,
37}; 37};
38 38
39const GLOB_RECURSION_LIMIT: usize = 100;
40const EXPANSION_DEPTH_LIMIT: usize = 128;
41const FIXED_POINT_LIMIT: usize = 8192;
42
39pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 43pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
40 let crate_graph = db.crate_graph(); 44 let crate_graph = db.crate_graph();
41 45
@@ -217,7 +221,7 @@ impl DefCollector<'_> {
217 ReachedFixedPoint::Yes => break, 221 ReachedFixedPoint::Yes => break,
218 ReachedFixedPoint::No => i += 1, 222 ReachedFixedPoint::No => i += 1,
219 } 223 }
220 if i == 10000 { 224 if i == FIXED_POINT_LIMIT {
221 log::error!("name resolution is stuck"); 225 log::error!("name resolution is stuck");
222 break; 226 break;
223 } 227 }
@@ -573,6 +577,7 @@ impl DefCollector<'_> {
573 vis: Visibility, 577 vis: Visibility,
574 import_type: ImportType, 578 import_type: ImportType,
575 ) { 579 ) {
580 self.db.check_canceled();
576 self.update_recursive(module_id, resolutions, vis, import_type, 0) 581 self.update_recursive(module_id, resolutions, vis, import_type, 0)
577 } 582 }
578 583
@@ -586,7 +591,7 @@ impl DefCollector<'_> {
586 import_type: ImportType, 591 import_type: ImportType,
587 depth: usize, 592 depth: usize,
588 ) { 593 ) {
589 if depth > 100 { 594 if depth > GLOB_RECURSION_LIMIT {
590 // prevent stack overflows (but this shouldn't be possible) 595 // prevent stack overflows (but this shouldn't be possible)
591 panic!("infinite recursion in glob imports!"); 596 panic!("infinite recursion in glob imports!");
592 } 597 }
@@ -609,14 +614,15 @@ impl DefCollector<'_> {
609 .get(&module_id) 614 .get(&module_id)
610 .into_iter() 615 .into_iter()
611 .flat_map(|v| v.iter()) 616 .flat_map(|v| v.iter())
617 .filter(|(glob_importing_module, _)| {
618 // we know all resolutions have the same visibility (`vis`), so we
619 // just need to check that once
620 vis.is_visible_from_def_map(&self.def_map, *glob_importing_module)
621 })
612 .cloned() 622 .cloned()
613 .collect::<Vec<_>>(); 623 .collect::<Vec<_>>();
624
614 for (glob_importing_module, glob_import_vis) in glob_imports { 625 for (glob_importing_module, glob_import_vis) in glob_imports {
615 // we know all resolutions have the same visibility (`vis`), so we
616 // just need to check that once
617 if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) {
618 continue;
619 }
620 self.update_recursive( 626 self.update_recursive(
621 glob_importing_module, 627 glob_importing_module,
622 resolutions, 628 resolutions,
@@ -677,10 +683,6 @@ impl DefCollector<'_> {
677 self.unexpanded_attribute_macros = attribute_macros; 683 self.unexpanded_attribute_macros = attribute_macros;
678 684
679 for (module_id, macro_call_id, depth) in resolved { 685 for (module_id, macro_call_id, depth) in resolved {
680 if depth > 1024 {
681 log::debug!("Max macro expansion depth reached");
682 continue;
683 }
684 self.collect_macro_expansion(module_id, macro_call_id, depth); 686 self.collect_macro_expansion(module_id, macro_call_id, depth);
685 } 687 }
686 688
@@ -717,6 +719,11 @@ impl DefCollector<'_> {
717 macro_call_id: MacroCallId, 719 macro_call_id: MacroCallId,
718 depth: usize, 720 depth: usize,
719 ) { 721 ) {
722 if depth > EXPANSION_DEPTH_LIMIT {
723 mark::hit!(macro_expansion_overflow);
724 log::warn!("macro expansion is too deep");
725 return;
726 }
720 let file_id: HirFileId = macro_call_id.as_file(); 727 let file_id: HirFileId = macro_call_id.as_file();
721 let item_tree = self.db.item_tree(file_id); 728 let item_tree = self.db.item_tree(file_id);
722 let mod_dir = self.mod_dirs[&module_id].clone(); 729 let mod_dir = self.mod_dirs[&module_id].clone();
diff --git a/crates/ra_hir_def/src/nameres/mod_resolution.rs b/crates/ra_hir_def/src/nameres/mod_resolution.rs
index 39e9a6d97..953961632 100644
--- a/crates/ra_hir_def/src/nameres/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/mod_resolution.rs
@@ -1,23 +1,24 @@
1//! This module resolves `mod foo;` declaration to file. 1//! This module resolves `mod foo;` declaration to file.
2use hir_expand::name::Name; 2use hir_expand::name::Name;
3use ra_db::{FileId, RelativePathBuf}; 3use ra_db::FileId;
4use ra_syntax::SmolStr; 4use ra_syntax::SmolStr;
5 5
6use crate::{db::DefDatabase, HirFileId}; 6use crate::{db::DefDatabase, HirFileId};
7 7
8#[derive(Clone, Debug)] 8#[derive(Clone, Debug)]
9pub(super) struct ModDir { 9pub(super) struct ModDir {
10 /// `.` for `mod.rs`, `lib.rs` 10 /// `` for `mod.rs`, `lib.rs`
11 /// `./foo` for `foo.rs` 11 /// `foo/` for `foo.rs`
12 /// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs` 12 /// `foo/bar/` for `mod bar { mod x; }` nested in `foo.rs`
13 path: RelativePathBuf, 13 /// Invariant: path.is_empty() || path.ends_with('/')
14 dir_path: DirPath,
14 /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/` 15 /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/`
15 root_non_dir_owner: bool, 16 root_non_dir_owner: bool,
16} 17}
17 18
18impl ModDir { 19impl ModDir {
19 pub(super) fn root() -> ModDir { 20 pub(super) fn root() -> ModDir {
20 ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false } 21 ModDir { dir_path: DirPath::empty(), root_non_dir_owner: false }
21 } 22 }
22 23
23 pub(super) fn descend_into_definition( 24 pub(super) fn descend_into_definition(
@@ -25,17 +26,21 @@ impl ModDir {
25 name: &Name, 26 name: &Name,
26 attr_path: Option<&SmolStr>, 27 attr_path: Option<&SmolStr>,
27 ) -> ModDir { 28 ) -> ModDir {
28 let mut path = self.path.clone(); 29 let path = match attr_path.map(|it| it.as_str()) {
29 match attr_to_path(attr_path) { 30 None => {
30 None => path.push(&name.to_string()), 31 let mut path = self.dir_path.clone();
32 path.push(&name.to_string());
33 path
34 }
31 Some(attr_path) => { 35 Some(attr_path) => {
32 if self.root_non_dir_owner { 36 let mut path = self.dir_path.join_attr(attr_path, self.root_non_dir_owner);
33 assert!(path.pop()); 37 if !(path.is_empty() || path.ends_with('/')) {
38 path.push('/')
34 } 39 }
35 path.push(attr_path); 40 DirPath::new(path)
36 } 41 }
37 } 42 };
38 ModDir { path, root_non_dir_owner: false } 43 ModDir { dir_path: path, root_non_dir_owner: false }
39 } 44 }
40 45
41 pub(super) fn resolve_declaration( 46 pub(super) fn resolve_declaration(
@@ -48,34 +53,87 @@ impl ModDir {
48 let file_id = file_id.original_file(db.upcast()); 53 let file_id = file_id.original_file(db.upcast());
49 54
50 let mut candidate_files = Vec::new(); 55 let mut candidate_files = Vec::new();
51 match attr_to_path(attr_path) { 56 match attr_path {
52 Some(attr_path) => { 57 Some(attr_path) => {
53 let base = 58 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
54 if self.root_non_dir_owner { self.path.parent().unwrap() } else { &self.path };
55 candidate_files.push(base.join(attr_path).to_string())
56 } 59 }
57 None => { 60 None => {
58 candidate_files.push(self.path.join(&format!("{}.rs", name)).to_string()); 61 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
59 candidate_files.push(self.path.join(&format!("{}/mod.rs", name)).to_string()); 62 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
60 } 63 }
61 }; 64 };
62 65
63 for candidate in candidate_files.iter() { 66 for candidate in candidate_files.iter() {
64 if let Some(file_id) = db.resolve_path(file_id, candidate.as_str()) { 67 if let Some(file_id) = db.resolve_path(file_id, candidate.as_str()) {
65 let mut root_non_dir_owner = false;
66 let mut mod_path = RelativePathBuf::new();
67 let is_mod_rs = candidate.ends_with("mod.rs"); 68 let is_mod_rs = candidate.ends_with("mod.rs");
68 if !(is_mod_rs || attr_path.is_some()) { 69
69 root_non_dir_owner = true; 70 let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() {
70 mod_path.push(&name.to_string()); 71 (DirPath::empty(), false)
71 } 72 } else {
72 return Ok((file_id, is_mod_rs, ModDir { path: mod_path, root_non_dir_owner })); 73 (DirPath::new(format!("{}/", name)), true)
74 };
75 return Ok((file_id, is_mod_rs, ModDir { dir_path, root_non_dir_owner }));
73 } 76 }
74 } 77 }
75 Err(candidate_files.remove(0)) 78 Err(candidate_files.remove(0))
76 } 79 }
77} 80}
78 81
79fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> { 82#[derive(Clone, Debug)]
80 attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) 83struct DirPath(String);
84
85impl DirPath {
86 fn assert_invariant(&self) {
87 assert!(self.0.is_empty() || self.0.ends_with('/'));
88 }
89 fn new(repr: String) -> DirPath {
90 let res = DirPath(repr);
91 res.assert_invariant();
92 res
93 }
94 fn empty() -> DirPath {
95 DirPath::new(String::new())
96 }
97 fn push(&mut self, name: &str) {
98 self.0.push_str(name);
99 self.0.push('/');
100 self.assert_invariant();
101 }
102 fn parent(&self) -> Option<&str> {
103 if self.0.is_empty() {
104 return None;
105 };
106 let idx =
107 self.0[..self.0.len() - '/'.len_utf8()].rfind('/').map_or(0, |it| it + '/'.len_utf8());
108 Some(&self.0[..idx])
109 }
110 /// So this is the case which doesn't really work I think if we try to be
111 /// 100% platform agnostic:
112 ///
113 /// ```
114 /// mod a {
115 /// #[path="C://sad/face"]
116 /// mod b { mod c; }
117 /// }
118 /// ```
119 ///
120 /// Here, we need to join logical dir path to a string path from an
121 /// attribute. Ideally, we should somehow losslessly communicate the whole
122 /// construction to `FileLoader`.
123 fn join_attr(&self, mut attr: &str, relative_to_parent: bool) -> String {
124 let base = if relative_to_parent { self.parent().unwrap() } else { &self.0 };
125
126 if attr.starts_with("./") {
127 attr = &attr["./".len()..];
128 }
129 let tmp;
130 let attr = if attr.contains('\\') {
131 tmp = attr.replace('\\', "/");
132 &tmp
133 } else {
134 attr
135 };
136 let res = format!("{}{}", base, attr);
137 res
138 }
81} 139}
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 19692e70c..dbfa7fccb 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -226,7 +226,15 @@ impl CrateDefMap {
226 match enum_data.variant(&segment) { 226 match enum_data.variant(&segment) {
227 Some(local_id) => { 227 Some(local_id) => {
228 let variant = EnumVariantId { parent: e, local_id }; 228 let variant = EnumVariantId { parent: e, local_id };
229 PerNs::both(variant.into(), variant.into(), Visibility::Public) 229 match &*enum_data.variants[local_id].variant_data {
230 crate::adt::VariantData::Record(_) => {
231 PerNs::types(variant.into(), Visibility::Public)
232 }
233 crate::adt::VariantData::Tuple(_)
234 | crate::adt::VariantData::Unit => {
235 PerNs::both(variant.into(), variant.into(), Visibility::Public)
236 }
237 }
230 } 238 }
231 None => { 239 None => {
232 return ResolvePathResult::with( 240 return ResolvePathResult::with(
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 503099fb7..205d3528b 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -6,558 +6,531 @@ mod primitives;
6 6
7use std::sync::Arc; 7use std::sync::Arc;
8 8
9use insta::assert_snapshot; 9use expect::{expect, Expect};
10use ra_db::{fixture::WithFixture, SourceDatabase}; 10use ra_db::{fixture::WithFixture, SourceDatabase};
11use test_utils::mark; 11use test_utils::mark;
12 12
13use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; 13use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
14 14
15fn def_map(ra_fixture: &str) -> String {
16 compute_crate_def_map(ra_fixture).dump()
17}
18
19fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { 15fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
20 let db = TestDB::with_files(fixture); 16 let db = TestDB::with_files(fixture);
21 let krate = db.crate_graph().iter().next().unwrap(); 17 let krate = db.crate_graph().iter().next().unwrap();
22 db.crate_def_map(krate) 18 db.crate_def_map(krate)
23} 19}
24 20
21fn check(ra_fixture: &str, expect: Expect) {
22 let db = TestDB::with_files(ra_fixture);
23 let krate = db.crate_graph().iter().next().unwrap();
24 let actual = db.crate_def_map(krate).dump();
25 expect.assert_eq(&actual);
26}
27
25#[test] 28#[test]
26fn crate_def_map_smoke_test() { 29fn crate_def_map_smoke_test() {
27 let map = def_map( 30 check(
28 r" 31 r#"
29 //- /lib.rs 32//- /lib.rs
30 mod foo; 33mod foo;
31 struct S; 34struct S;
32 use crate::foo::bar::E; 35use crate::foo::bar::E;
33 use self::E::V; 36use self::E::V;
34
35 //- /foo/mod.rs
36 pub mod bar;
37 fn f() {}
38
39 //- /foo/bar.rs
40 pub struct Baz;
41
42 union U {
43 to_be: bool,
44 not_to_be: u8,
45 }
46 37
47 enum E { V } 38//- /foo/mod.rs
39pub mod bar;
40fn f() {}
48 41
49 extern { 42//- /foo/bar.rs
50 static EXT: u8; 43pub struct Baz;
51 fn ext(); 44
52 } 45union U { to_be: bool, not_to_be: u8 }
53 ", 46enum E { V }
47
48extern {
49 static EXT: u8;
50 fn ext();
51}
52"#,
53 expect![[r#"
54 crate
55 E: t
56 S: t v
57 V: t v
58 foo: t
59
60 crate::foo
61 bar: t
62 f: v
63
64 crate::foo::bar
65 Baz: t v
66 E: t
67 EXT: v
68 U: t
69 ext: v
70 "#]],
54 ); 71 );
55 assert_snapshot!(map, @r###"
56 ⋮crate
57 ⋮E: t
58 ⋮S: t v
59 ⋮V: t v
60 ⋮foo: t
61
62 ⋮crate::foo
63 ⋮bar: t
64 ⋮f: v
65
66 ⋮crate::foo::bar
67 ⋮Baz: t v
68 ⋮E: t
69 ⋮EXT: v
70 ⋮U: t
71 ⋮ext: v
72 "###)
73} 72}
74 73
75#[test] 74#[test]
76fn crate_def_map_super_super() { 75fn crate_def_map_super_super() {
77 let map = def_map( 76 check(
78 " 77 r#"
79 //- /lib.rs 78mod a {
80 mod a { 79 const A: usize = 0;
81 const A: usize = 0; 80 mod b {
82 81 const B: usize = 0;
83 mod b { 82 mod c {
84 const B: usize = 0; 83 use super::super::*;
85
86 mod c {
87 use super::super::*;
88 }
89 }
90 } 84 }
91 ", 85 }
86}
87"#,
88 expect![[r#"
89 crate
90 a: t
91
92 crate::a
93 A: v
94 b: t
95
96 crate::a::b
97 B: v
98 c: t
99
100 crate::a::b::c
101 A: v
102 b: t
103 "#]],
92 ); 104 );
93 assert_snapshot!(map, @r###"
94 ⋮crate
95 ⋮a: t
96
97 ⋮crate::a
98 ⋮A: v
99 ⋮b: t
100
101 ⋮crate::a::b
102 ⋮B: v
103 ⋮c: t
104
105 ⋮crate::a::b::c
106 ⋮A: v
107 ⋮b: t
108 "###)
109} 105}
110 106
111#[test] 107#[test]
112fn crate_def_map_fn_mod_same_name() { 108fn crate_def_map_fn_mod_same_name() {
113 let map = def_map( 109 check(
114 " 110 r#"
115 //- /lib.rs 111mod m {
116 mod m { 112 pub mod z {}
117 pub mod z {} 113 pub fn z() {}
118 pub fn z() {} 114}
119 } 115"#,
120 ", 116 expect![[r#"
117 crate
118 m: t
119
120 crate::m
121 z: t v
122
123 crate::m::z
124 "#]],
121 ); 125 );
122 assert_snapshot!(map, @r###"
123 ⋮crate
124 ⋮m: t
125
126 ⋮crate::m
127 ⋮z: t v
128
129 ⋮crate::m::z
130 "###)
131} 126}
132 127
133#[test] 128#[test]
134fn bogus_paths() { 129fn bogus_paths() {
135 mark::check!(bogus_paths); 130 mark::check!(bogus_paths);
136 let map = def_map( 131 check(
137 " 132 r#"
138 //- /lib.rs 133//- /lib.rs
139 mod foo; 134mod foo;
140 struct S; 135struct S;
141 use self; 136use self;
142 137
143 //- /foo/mod.rs 138//- /foo/mod.rs
144 use super; 139use super;
145 use crate; 140use crate;
146 141"#,
147 ", 142 expect![[r#"
143 crate
144 S: t v
145 foo: t
146
147 crate::foo
148 "#]],
148 ); 149 );
149 assert_snapshot!(map, @r###"
150 ⋮crate
151 ⋮S: t v
152 ⋮foo: t
153
154 ⋮crate::foo
155 "###
156 )
157} 150}
158 151
159#[test] 152#[test]
160fn use_as() { 153fn use_as() {
161 let map = def_map( 154 check(
162 " 155 r#"
163 //- /lib.rs 156//- /lib.rs
164 mod foo; 157mod foo;
165 158use crate::foo::Baz as Foo;
166 use crate::foo::Baz as Foo;
167 159
168 //- /foo/mod.rs 160//- /foo/mod.rs
169 pub struct Baz; 161pub struct Baz;
170 ", 162"#,
171 ); 163 expect![[r#"
172 assert_snapshot!(map, 164 crate
173 @r###" 165 Foo: t v
174 ⋮crate 166 foo: t
175 ⋮Foo: t v 167
176 ⋮foo: t 168 crate::foo
177 169 Baz: t v
178 ⋮crate::foo 170 "#]],
179 ⋮Baz: t v
180 "###
181 ); 171 );
182} 172}
183 173
184#[test] 174#[test]
185fn use_trees() { 175fn use_trees() {
186 let map = def_map( 176 check(
187 " 177 r#"
188 //- /lib.rs 178//- /lib.rs
189 mod foo; 179mod foo;
190 180use crate::foo::bar::{Baz, Quux};
191 use crate::foo::bar::{Baz, Quux};
192 181
193 //- /foo/mod.rs 182//- /foo/mod.rs
194 pub mod bar; 183pub mod bar;
195 184
196 //- /foo/bar.rs 185//- /foo/bar.rs
197 pub struct Baz; 186pub struct Baz;
198 pub enum Quux {}; 187pub enum Quux {};
199 ", 188"#,
189 expect![[r#"
190 crate
191 Baz: t v
192 Quux: t
193 foo: t
194
195 crate::foo
196 bar: t
197
198 crate::foo::bar
199 Baz: t v
200 Quux: t
201 "#]],
200 ); 202 );
201 assert_snapshot!(map, @r###"
202 ⋮crate
203 ⋮Baz: t v
204 ⋮Quux: t
205 ⋮foo: t
206
207 ⋮crate::foo
208 ⋮bar: t
209
210 ⋮crate::foo::bar
211 ⋮Baz: t v
212 ⋮Quux: t
213 "###);
214} 203}
215 204
216#[test] 205#[test]
217fn re_exports() { 206fn re_exports() {
218 let map = def_map( 207 check(
219 " 208 r#"
220 //- /lib.rs 209//- /lib.rs
221 mod foo; 210mod foo;
222 211use self::foo::Baz;
223 use self::foo::Baz;
224
225 //- /foo/mod.rs
226 pub mod bar;
227 212
228 pub use self::bar::Baz; 213//- /foo/mod.rs
214pub mod bar;
215pub use self::bar::Baz;
229 216
230 //- /foo/bar.rs 217//- /foo/bar.rs
231 pub struct Baz; 218pub struct Baz;
232 ", 219"#,
220 expect![[r#"
221 crate
222 Baz: t v
223 foo: t
224
225 crate::foo
226 Baz: t v
227 bar: t
228
229 crate::foo::bar
230 Baz: t v
231 "#]],
233 ); 232 );
234 assert_snapshot!(map, @r###"
235 ⋮crate
236 ⋮Baz: t v
237 ⋮foo: t
238
239 ⋮crate::foo
240 ⋮Baz: t v
241 ⋮bar: t
242
243 ⋮crate::foo::bar
244 ⋮Baz: t v
245 "###);
246} 233}
247 234
248#[test] 235#[test]
249fn std_prelude() { 236fn std_prelude() {
250 mark::check!(std_prelude); 237 mark::check!(std_prelude);
251 let map = def_map( 238 check(
252 " 239 r#"
253 //- /main.rs crate:main deps:test_crate 240//- /main.rs crate:main deps:test_crate
254 use Foo::*; 241use Foo::*;
255 242
256 //- /lib.rs crate:test_crate 243//- /lib.rs crate:test_crate
257 mod prelude; 244mod prelude;
258 #[prelude_import] 245#[prelude_import]
259 use prelude::*; 246use prelude::*;
260 247
261 //- /prelude.rs 248//- /prelude.rs
262 pub enum Foo { Bar, Baz }; 249pub enum Foo { Bar, Baz };
263 ", 250"#,
251 expect![[r#"
252 crate
253 Bar: t v
254 Baz: t v
255 "#]],
264 ); 256 );
265 assert_snapshot!(map, @r###"
266 ⋮crate
267 ⋮Bar: t v
268 ⋮Baz: t v
269 "###);
270} 257}
271 258
272#[test] 259#[test]
273fn can_import_enum_variant() { 260fn can_import_enum_variant() {
274 mark::check!(can_import_enum_variant); 261 mark::check!(can_import_enum_variant);
275 let map = def_map( 262 check(
276 " 263 r#"
277 //- /lib.rs 264enum E { V }
278 enum E { V } 265use self::E::V;
279 use self::E::V; 266"#,
280 ", 267 expect![[r#"
281 ); 268 crate
282 assert_snapshot!(map, @r###" 269 E: t
283 ⋮crate 270 V: t v
284 ⋮E: t 271 "#]],
285 ⋮V: t v
286 "###
287 ); 272 );
288} 273}
289 274
290#[test] 275#[test]
291fn edition_2015_imports() { 276fn edition_2015_imports() {
292 let map = def_map( 277 check(
293 " 278 r#"
294 //- /main.rs crate:main deps:other_crate edition:2015 279//- /main.rs crate:main deps:other_crate edition:2015
295 mod foo; 280mod foo;
296 mod bar; 281mod bar;
297 282
298 //- /bar.rs 283//- /bar.rs
299 struct Bar; 284struct Bar;
300
301 //- /foo.rs
302 use bar::Bar;
303 use other_crate::FromLib;
304
305 //- /lib.rs crate:other_crate edition:2018
306 struct FromLib;
307 ",
308 );
309 285
310 assert_snapshot!(map, @r###" 286//- /foo.rs
311 ⋮crate 287use bar::Bar;
312 ⋮bar: t 288use other_crate::FromLib;
313 ⋮foo: t 289
314 290//- /lib.rs crate:other_crate edition:2018
315 ⋮crate::bar 291struct FromLib;
316 ⋮Bar: t v 292"#,
317 293 expect![[r#"
318 ⋮crate::foo 294 crate
319 ⋮Bar: t v 295 bar: t
320 ⋮FromLib: t v 296 foo: t
321 "###); 297
298 crate::bar
299 Bar: t v
300
301 crate::foo
302 Bar: t v
303 FromLib: t v
304 "#]],
305 );
322} 306}
323 307
324#[test] 308#[test]
325fn item_map_using_self() { 309fn item_map_using_self() {
326 let map = def_map( 310 check(
327 " 311 r#"
328 //- /lib.rs 312//- /lib.rs
329 mod foo; 313mod foo;
330 use crate::foo::bar::Baz::{self}; 314use crate::foo::bar::Baz::{self};
331 //- /foo/mod.rs 315
332 pub mod bar; 316//- /foo/mod.rs
333 //- /foo/bar.rs 317pub mod bar;
334 pub struct Baz; 318
335 ", 319//- /foo/bar.rs
320pub struct Baz;
321"#,
322 expect![[r#"
323 crate
324 Baz: t v
325 foo: t
326
327 crate::foo
328 bar: t
329
330 crate::foo::bar
331 Baz: t v
332 "#]],
336 ); 333 );
337 assert_snapshot!(map, @r###"
338 ⋮crate
339 ⋮Baz: t v
340 ⋮foo: t
341
342 ⋮crate::foo
343 ⋮bar: t
344
345 ⋮crate::foo::bar
346 ⋮Baz: t v
347 "###);
348} 334}
349 335
350#[test] 336#[test]
351fn item_map_across_crates() { 337fn item_map_across_crates() {
352 let map = def_map( 338 check(
353 " 339 r#"
354 //- /main.rs crate:main deps:test_crate 340//- /main.rs crate:main deps:test_crate
355 use test_crate::Baz; 341use test_crate::Baz;
356
357 //- /lib.rs crate:test_crate
358 pub struct Baz;
359 ",
360 );
361 342
362 assert_snapshot!(map, @r###" 343//- /lib.rs crate:test_crate
363 ⋮crate 344pub struct Baz;
364 ⋮Baz: t v 345"#,
365 "###); 346 expect![[r#"
347 crate
348 Baz: t v
349 "#]],
350 );
366} 351}
367 352
368#[test] 353#[test]
369fn extern_crate_rename() { 354fn extern_crate_rename() {
370 let map = def_map( 355 check(
371 " 356 r#"
372 //- /main.rs crate:main deps:alloc 357//- /main.rs crate:main deps:alloc
373 extern crate alloc as alloc_crate; 358extern crate alloc as alloc_crate;
374 359mod alloc;
375 mod alloc; 360mod sync;
376 mod sync;
377 361
378 //- /sync.rs 362//- /sync.rs
379 use alloc_crate::Arc; 363use alloc_crate::Arc;
380 364
381 //- /lib.rs crate:alloc 365//- /lib.rs crate:alloc
382 struct Arc; 366struct Arc;
383 ", 367"#,
368 expect![[r#"
369 crate
370 alloc_crate: t
371 sync: t
372
373 crate::sync
374 Arc: t v
375 "#]],
384 ); 376 );
385
386 assert_snapshot!(map, @r###"
387 ⋮crate
388 ⋮alloc_crate: t
389 ⋮sync: t
390
391 ⋮crate::sync
392 ⋮Arc: t v
393 "###);
394} 377}
395 378
396#[test] 379#[test]
397fn extern_crate_rename_2015_edition() { 380fn extern_crate_rename_2015_edition() {
398 let map = def_map( 381 check(
399 " 382 r#"
400 //- /main.rs crate:main deps:alloc edition:2015 383//- /main.rs crate:main deps:alloc edition:2015
401 extern crate alloc as alloc_crate; 384extern crate alloc as alloc_crate;
402 385mod alloc;
403 mod alloc; 386mod sync;
404 mod sync;
405
406 //- /sync.rs
407 use alloc_crate::Arc;
408 387
409 //- /lib.rs crate:alloc 388//- /sync.rs
410 struct Arc; 389use alloc_crate::Arc;
411 ",
412 );
413 390
414 assert_snapshot!(map, 391//- /lib.rs crate:alloc
415 @r###" 392struct Arc;
416 ⋮crate 393"#,
417 ⋮alloc_crate: t 394 expect![[r#"
418 ⋮sync: t 395 crate
419 396 alloc_crate: t
420 ⋮crate::sync 397 sync: t
421 ⋮Arc: t v 398
422 "### 399 crate::sync
400 Arc: t v
401 "#]],
423 ); 402 );
424} 403}
425 404
426#[test] 405#[test]
427fn reexport_across_crates() { 406fn reexport_across_crates() {
428 let map = def_map( 407 check(
429 " 408 r#"
430 //- /main.rs crate:main deps:test_crate 409//- /main.rs crate:main deps:test_crate
431 use test_crate::Baz; 410use test_crate::Baz;
432
433 //- /lib.rs crate:test_crate
434 pub use foo::Baz;
435 411
436 mod foo; 412//- /lib.rs crate:test_crate
413pub use foo::Baz;
414mod foo;
437 415
438 //- /foo.rs 416//- /foo.rs
439 pub struct Baz; 417pub struct Baz;
440 ", 418"#,
419 expect![[r#"
420 crate
421 Baz: t v
422 "#]],
441 ); 423 );
442
443 assert_snapshot!(map, @r###"
444 ⋮crate
445 ⋮Baz: t v
446 "###);
447} 424}
448 425
449#[test] 426#[test]
450fn values_dont_shadow_extern_crates() { 427fn values_dont_shadow_extern_crates() {
451 let map = def_map( 428 check(
452 " 429 r#"
453 //- /main.rs crate:main deps:foo 430//- /main.rs crate:main deps:foo
454 fn foo() {} 431fn foo() {}
455 use foo::Bar; 432use foo::Bar;
456
457 //- /foo/lib.rs crate:foo
458 pub struct Bar;
459 ",
460 );
461 433
462 assert_snapshot!(map, @r###" 434//- /foo/lib.rs crate:foo
463 ⋮crate 435pub struct Bar;
464 ⋮Bar: t v 436"#,
465 ⋮foo: v 437 expect![[r#"
466 "###); 438 crate
439 Bar: t v
440 foo: v
441 "#]],
442 );
467} 443}
468 444
469#[test] 445#[test]
470fn std_prelude_takes_precedence_above_core_prelude() { 446fn std_prelude_takes_precedence_above_core_prelude() {
471 let map = def_map( 447 check(
472 r#" 448 r#"
473 //- /main.rs crate:main deps:core,std 449//- /main.rs crate:main deps:core,std
474 use {Foo, Bar}; 450use {Foo, Bar};
475 451
476 //- /std.rs crate:std deps:core 452//- /std.rs crate:std deps:core
477 #[prelude_import] 453#[prelude_import]
478 pub use self::prelude::*; 454pub use self::prelude::*;
479 mod prelude { 455mod prelude {
480 pub struct Foo; 456 pub struct Foo;
481 pub use core::prelude::Bar; 457 pub use core::prelude::Bar;
482 } 458}
483 459
484 //- /core.rs crate:core 460//- /core.rs crate:core
485 #[prelude_import] 461#[prelude_import]
486 pub use self::prelude::*; 462pub use self::prelude::*;
487 mod prelude { 463mod prelude {
488 pub struct Bar; 464 pub struct Bar;
489 } 465}
490 "#, 466"#,
467 expect![[r#"
468 crate
469 Bar: t v
470 Foo: t v
471 "#]],
491 ); 472 );
492
493 assert_snapshot!(map, @r###"
494 ⋮crate
495 ⋮Bar: t v
496 ⋮Foo: t v
497 "###);
498} 473}
499 474
500#[test] 475#[test]
501fn cfg_not_test() { 476fn cfg_not_test() {
502 let map = def_map( 477 check(
503 r#" 478 r#"
504 //- /main.rs crate:main deps:std 479//- /main.rs crate:main deps:std
505 use {Foo, Bar, Baz}; 480use {Foo, Bar, Baz};
506 481
507 //- /lib.rs crate:std 482//- /lib.rs crate:std
508 #[prelude_import] 483#[prelude_import]
509 pub use self::prelude::*; 484pub use self::prelude::*;
510 mod prelude { 485mod prelude {
511 #[cfg(test)] 486 #[cfg(test)]
512 pub struct Foo; 487 pub struct Foo;
513 #[cfg(not(test))] 488 #[cfg(not(test))]
514 pub struct Bar; 489 pub struct Bar;
515 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] 490 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
516 pub struct Baz; 491 pub struct Baz;
517 } 492}
518 "#, 493"#,
494 expect![[r#"
495 crate
496 Bar: t v
497 Baz: _
498 Foo: _
499 "#]],
519 ); 500 );
520
521 assert_snapshot!(map, @r###"
522 ⋮crate
523 ⋮Bar: t v
524 ⋮Baz: _
525 ⋮Foo: _
526 "###);
527} 501}
528 502
529#[test] 503#[test]
530fn cfg_test() { 504fn cfg_test() {
531 let map = def_map( 505 check(
532 r#" 506 r#"
533 //- /main.rs crate:main deps:std 507//- /main.rs crate:main deps:std
534 use {Foo, Bar, Baz}; 508use {Foo, Bar, Baz};
535 509
536 //- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42 510//- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
537 #[prelude_import] 511#[prelude_import]
538 pub use self::prelude::*; 512pub use self::prelude::*;
539 mod prelude { 513mod prelude {
540 #[cfg(test)] 514 #[cfg(test)]
541 pub struct Foo; 515 pub struct Foo;
542 #[cfg(not(test))] 516 #[cfg(not(test))]
543 pub struct Bar; 517 pub struct Bar;
544 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))] 518 #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
545 pub struct Baz; 519 pub struct Baz;
546 } 520}
547 "#, 521"#,
522 expect![[r#"
523 crate
524 Bar: _
525 Baz: t v
526 Foo: t v
527 "#]],
548 ); 528 );
549
550 assert_snapshot!(map, @r###"
551 ⋮crate
552 ⋮Bar: _
553 ⋮Baz: t v
554 ⋮Foo: t v
555 "###);
556} 529}
557 530
558#[test] 531#[test]
559fn infer_multiple_namespace() { 532fn infer_multiple_namespace() {
560 let map = def_map( 533 check(
561 r#" 534 r#"
562//- /main.rs 535//- /main.rs
563mod a { 536mod a {
@@ -571,18 +544,17 @@ mod b {
571 pub const T: () = (); 544 pub const T: () = ();
572} 545}
573"#, 546"#,
547 expect![[r#"
548 crate
549 T: t v
550 a: t
551 b: t
552
553 crate::b
554 T: v
555
556 crate::a
557 T: t v
558 "#]],
574 ); 559 );
575
576 assert_snapshot!(map, @r###"
577 ⋮crate
578 ⋮T: t v
579 ⋮a: t
580 ⋮b: t
581
582 ⋮crate::b
583 ⋮T: v
584
585 ⋮crate::a
586 ⋮T: t v
587"###);
588} 560}
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
index 7f3d7509c..2ae836e3c 100644
--- a/crates/ra_hir_def/src/nameres/tests/globs.rs
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -2,367 +2,337 @@ use super::*;
2 2
3#[test] 3#[test]
4fn glob_1() { 4fn glob_1() {
5 let map = def_map( 5 check(
6 r" 6 r#"
7 //- /lib.rs 7//- /lib.rs
8 mod foo; 8mod foo;
9 use foo::*; 9use foo::*;
10 10
11 //- /foo/mod.rs 11//- /foo/mod.rs
12 pub mod bar; 12pub mod bar;
13 pub use self::bar::Baz; 13pub use self::bar::Baz;
14 pub struct Foo; 14pub struct Foo;
15 15
16 //- /foo/bar.rs 16//- /foo/bar.rs
17 pub struct Baz; 17pub struct Baz;
18 ", 18"#,
19 ); 19 expect![[r#"
20 assert_snapshot!(map, @r###" 20 crate
21 ⋮crate 21 Baz: t v
22 ⋮Baz: t v 22 Foo: t v
23 ⋮Foo: t v 23 bar: t
24 ⋮bar: t 24 foo: t
25 ⋮foo: t 25
26 26 crate::foo
27 ⋮crate::foo 27 Baz: t v
28 ⋮Baz: t v 28 Foo: t v
29 ⋮Foo: t v 29 bar: t
30 ⋮bar: t 30
31 31 crate::foo::bar
32 ⋮crate::foo::bar 32 Baz: t v
33 ⋮Baz: t v 33 "#]],
34 "###
35 ); 34 );
36} 35}
37 36
38#[test] 37#[test]
39fn glob_2() { 38fn glob_2() {
40 let map = def_map( 39 check(
41 " 40 r#"
42 //- /lib.rs 41//- /lib.rs
43 mod foo; 42mod foo;
44 use foo::*; 43use foo::*;
45 44
46 //- /foo/mod.rs 45//- /foo/mod.rs
47 pub mod bar; 46pub mod bar;
48 pub use self::bar::*; 47pub use self::bar::*;
49 pub struct Foo; 48pub struct Foo;
50 49
51 //- /foo/bar.rs 50//- /foo/bar.rs
52 pub struct Baz; 51pub struct Baz;
53 pub use super::*; 52pub use super::*;
54 ", 53"#,
55 ); 54 expect![[r#"
56 assert_snapshot!(map, @r###" 55 crate
57 ⋮crate 56 Baz: t v
58 ⋮Baz: t v 57 Foo: t v
59 ⋮Foo: t v 58 bar: t
60 ⋮bar: t 59 foo: t
61 ⋮foo: t 60
62 61 crate::foo
63 ⋮crate::foo 62 Baz: t v
64 ⋮Baz: t v 63 Foo: t v
65 ⋮Foo: t v 64 bar: t
66 ⋮bar: t 65
67 66 crate::foo::bar
68 ⋮crate::foo::bar 67 Baz: t v
69 ⋮Baz: t v 68 Foo: t v
70 ⋮Foo: t v 69 bar: t
71 ⋮bar: t 70 "#]],
72 "###
73 ); 71 );
74} 72}
75 73
76#[test] 74#[test]
77fn glob_privacy_1() { 75fn glob_privacy_1() {
78 let map = def_map( 76 check(
79 r" 77 r"
80 //- /lib.rs 78//- /lib.rs
81 mod foo; 79mod foo;
82 use foo::*; 80use foo::*;
83 81
84 //- /foo/mod.rs 82//- /foo/mod.rs
85 pub mod bar; 83pub mod bar;
86 pub use self::bar::*; 84pub use self::bar::*;
87 struct PrivateStructFoo; 85struct PrivateStructFoo;
88 86
89 //- /foo/bar.rs 87//- /foo/bar.rs
90 pub struct Baz; 88pub struct Baz;
91 struct PrivateStructBar; 89struct PrivateStructBar;
92 pub use super::*; 90pub use super::*;
93 ", 91",
94 ); 92 expect![[r#"
95 assert_snapshot!(map, @r###" 93 crate
96 ⋮crate 94 Baz: t v
97 ⋮Baz: t v 95 bar: t
98 ⋮bar: t 96 foo: t
99 ⋮foo: t 97
100 98 crate::foo
101 ⋮crate::foo 99 Baz: t v
102 ⋮Baz: t v 100 PrivateStructFoo: t v
103 ⋮PrivateStructFoo: t v 101 bar: t
104 ⋮bar: t 102
105 103 crate::foo::bar
106 ⋮crate::foo::bar 104 Baz: t v
107 ⋮Baz: t v 105 PrivateStructBar: t v
108 ⋮PrivateStructBar: t v 106 PrivateStructFoo: t v
109 ⋮PrivateStructFoo: t v 107 bar: t
110 ⋮bar: t 108 "#]],
111 "###
112 ); 109 );
113} 110}
114 111
115#[test] 112#[test]
116fn glob_privacy_2() { 113fn glob_privacy_2() {
117 let map = def_map( 114 check(
118 r" 115 r"
119 //- /lib.rs 116//- /lib.rs
120 mod foo; 117mod foo;
121 use foo::*; 118use foo::*;
122 use foo::bar::*; 119use foo::bar::*;
123 120
124 //- /foo/mod.rs 121//- /foo/mod.rs
125 mod bar; 122mod bar;
126 fn Foo() {}; 123fn Foo() {};
127 pub struct Foo {}; 124pub struct Foo {};
128 125
129 //- /foo/bar.rs 126//- /foo/bar.rs
130 pub(super) struct PrivateBaz; 127pub(super) struct PrivateBaz;
131 struct PrivateBar; 128struct PrivateBar;
132 pub(crate) struct PubCrateStruct; 129pub(crate) struct PubCrateStruct;
133 ", 130",
134 ); 131 expect![[r#"
135 assert_snapshot!(map, @r###" 132 crate
136 ⋮crate 133 Foo: t
137 ⋮Foo: t 134 PubCrateStruct: t v
138 ⋮PubCrateStruct: t v 135 foo: t
139 ⋮foo: t 136
140 137 crate::foo
141 ⋮crate::foo 138 Foo: t v
142 ⋮Foo: t v 139 bar: t
143 ⋮bar: t 140
144 141 crate::foo::bar
145 ⋮crate::foo::bar 142 PrivateBar: t v
146 ⋮PrivateBar: t v 143 PrivateBaz: t v
147 ⋮PrivateBaz: t v 144 PubCrateStruct: t v
148 ⋮PubCrateStruct: t v 145 "#]],
149 "###
150 ); 146 );
151} 147}
152 148
153#[test] 149#[test]
154fn glob_across_crates() { 150fn glob_across_crates() {
155 mark::check!(glob_across_crates); 151 mark::check!(glob_across_crates);
156 let map = def_map( 152 check(
157 r" 153 r#"
158 //- /main.rs crate:main deps:test_crate 154//- /main.rs crate:main deps:test_crate
159 use test_crate::*; 155use test_crate::*;
160 156
161 //- /lib.rs crate:test_crate 157//- /lib.rs crate:test_crate
162 pub struct Baz; 158pub struct Baz;
163 ", 159"#,
164 ); 160 expect![[r#"
165 assert_snapshot!(map, @r###" 161 crate
166 ⋮crate 162 Baz: t v
167 ⋮Baz: t v 163 "#]],
168 "###
169 ); 164 );
170} 165}
171 166
172#[test] 167#[test]
173fn glob_privacy_across_crates() { 168fn glob_privacy_across_crates() {
174 let map = def_map( 169 check(
175 r" 170 r#"
176 //- /main.rs crate:main deps:test_crate 171//- /main.rs crate:main deps:test_crate
177 use test_crate::*; 172use test_crate::*;
178 173
179 //- /lib.rs crate:test_crate 174//- /lib.rs crate:test_crate
180 pub struct Baz; 175pub struct Baz;
181 struct Foo; 176struct Foo;
182 ", 177"#,
183 ); 178 expect![[r#"
184 assert_snapshot!(map, @r###" 179 crate
185 ⋮crate 180 Baz: t v
186 ⋮Baz: t v 181 "#]],
187 "###
188 ); 182 );
189} 183}
190 184
191#[test] 185#[test]
192fn glob_enum() { 186fn glob_enum() {
193 mark::check!(glob_enum); 187 mark::check!(glob_enum);
194 let map = def_map( 188 check(
195 " 189 r#"
196 //- /lib.rs 190enum Foo { Bar, Baz }
197 enum Foo { 191use self::Foo::*;
198 Bar, Baz 192"#,
199 } 193 expect![[r#"
200 use self::Foo::*; 194 crate
201 ", 195 Bar: t v
202 ); 196 Baz: t v
203 assert_snapshot!(map, @r###" 197 Foo: t
204 ⋮crate 198 "#]],
205 ⋮Bar: t v
206 ⋮Baz: t v
207 ⋮Foo: t
208 "###
209 ); 199 );
210} 200}
211 201
212#[test] 202#[test]
213fn glob_enum_group() { 203fn glob_enum_group() {
214 mark::check!(glob_enum_group); 204 mark::check!(glob_enum_group);
215 let map = def_map( 205 check(
216 r" 206 r#"
217 //- /lib.rs 207enum Foo { Bar, Baz }
218 enum Foo { 208use self::Foo::{*};
219 Bar, Baz 209"#,
220 } 210 expect![[r#"
221 use self::Foo::{*}; 211 crate
222 ", 212 Bar: t v
223 ); 213 Baz: t v
224 assert_snapshot!(map, @r###" 214 Foo: t
225 ⋮crate 215 "#]],
226 ⋮Bar: t v
227 ⋮Baz: t v
228 ⋮Foo: t
229 "###
230 ); 216 );
231} 217}
232 218
233#[test] 219#[test]
234fn glob_shadowed_def() { 220fn glob_shadowed_def() {
235 mark::check!(import_shadowed); 221 mark::check!(import_shadowed);
236 let map = def_map( 222 check(
237 r###" 223 r#"
238 //- /lib.rs 224//- /lib.rs
239 mod foo; 225mod foo;
240 mod bar; 226mod bar;
241 227use foo::*;
242 use foo::*; 228use bar::baz;
243 use bar::baz; 229use baz::Bar;
244 230
245 use baz::Bar; 231//- /foo.rs
246 232pub mod baz { pub struct Foo; }
247 //- /foo.rs 233
248 pub mod baz { 234//- /bar.rs
249 pub struct Foo; 235pub mod baz { pub struct Bar; }
250 } 236"#,
251 237 expect![[r#"
252 //- /bar.rs 238 crate
253 pub mod baz { 239 Bar: t v
254 pub struct Bar; 240 bar: t
255 } 241 baz: t
256 "###, 242 foo: t
257 ); 243
258 assert_snapshot!(map, @r###" 244 crate::bar
259 ⋮crate 245 baz: t
260 ⋮Bar: t v 246
261 ⋮bar: t 247 crate::bar::baz
262 ⋮baz: t 248 Bar: t v
263 ⋮foo: t 249
264 250 crate::foo
265 ⋮crate::bar 251 baz: t
266 ⋮baz: t 252
267 253 crate::foo::baz
268 ⋮crate::bar::baz 254 Foo: t v
269 ⋮Bar: t v 255 "#]],
270
271 ⋮crate::foo
272 ⋮baz: t
273
274 ⋮crate::foo::baz
275 ⋮Foo: t v
276 "###
277 ); 256 );
278} 257}
279 258
280#[test] 259#[test]
281fn glob_shadowed_def_reversed() { 260fn glob_shadowed_def_reversed() {
282 let map = def_map( 261 check(
283 r###" 262 r#"
284 //- /lib.rs 263//- /lib.rs
285 mod foo; 264mod foo;
286 mod bar; 265mod bar;
287 266use bar::baz;
288 use bar::baz; 267use foo::*;
289 use foo::*; 268use baz::Bar;
290 269
291 use baz::Bar; 270//- /foo.rs
292 271pub mod baz { pub struct Foo; }
293 //- /foo.rs 272
294 pub mod baz { 273//- /bar.rs
295 pub struct Foo; 274pub mod baz { pub struct Bar; }
296 } 275"#,
297 276 expect![[r#"
298 //- /bar.rs 277 crate
299 pub mod baz { 278 Bar: t v
300 pub struct Bar; 279 bar: t
301 } 280 baz: t
302 "###, 281 foo: t
303 ); 282
304 assert_snapshot!(map, @r###" 283 crate::bar
305 ⋮crate 284 baz: t
306 ⋮Bar: t v 285
307 ⋮bar: t 286 crate::bar::baz
308 ⋮baz: t 287 Bar: t v
309 ⋮foo: t 288
310 289 crate::foo
311 ⋮crate::bar 290 baz: t
312 ⋮baz: t 291
313 292 crate::foo::baz
314 ⋮crate::bar::baz 293 Foo: t v
315 ⋮Bar: t v 294 "#]],
316
317 ⋮crate::foo
318 ⋮baz: t
319
320 ⋮crate::foo::baz
321 ⋮Foo: t v
322 "###
323 ); 295 );
324} 296}
325 297
326#[test] 298#[test]
327fn glob_shadowed_def_dependencies() { 299fn glob_shadowed_def_dependencies() {
328 let map = def_map( 300 check(
329 r###" 301 r#"
330 //- /lib.rs 302mod a { pub mod foo { pub struct X; } }
331 mod a { pub mod foo { pub struct X; } } 303mod b { pub use super::a::foo; }
332 mod b { pub use super::a::foo; } 304mod c { pub mod foo { pub struct Y; } }
333 mod c { pub mod foo { pub struct Y; } } 305mod d {
334 mod d { 306 use super::c::foo;
335 use super::c::foo; 307 use super::b::*;
336 use super::b::*; 308 use foo::Y;
337 use foo::Y; 309}
338 } 310"#,
339 "###, 311 expect![[r#"
340 ); 312 crate
341 assert_snapshot!(map, @r###" 313 a: t
342 ⋮crate 314 b: t
343 ⋮a: t 315 c: t
344 ⋮b: t 316 d: t
345 ⋮c: t 317
346 ⋮d: t 318 crate::d
347 319 Y: t v
348 ⋮crate::d 320 foo: t
349 ⋮Y: t v 321
350 ⋮foo: t 322 crate::c
351 323 foo: t
352 ⋮crate::c 324
353 ⋮foo: t 325 crate::c::foo
354 326 Y: t v
355 ⋮crate::c::foo 327
356 ⋮Y: t v 328 crate::b
357 329 foo: t
358 ⋮crate::b 330
359 ⋮foo: t 331 crate::a
360 332 foo: t
361 ⋮crate::a 333
362 ⋮foo: t 334 crate::a::foo
363 335 X: t v
364 ⋮crate::a::foo 336 "#]],
365 ⋮X: t v
366 "###
367 ); 337 );
368} 338}
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs
index 84480d9f6..e0fb8bdef 100644
--- a/crates/ra_hir_def/src/nameres/tests/macros.rs
+++ b/crates/ra_hir_def/src/nameres/tests/macros.rs
@@ -2,639 +2,631 @@ use super::*;
2 2
3#[test] 3#[test]
4fn macro_rules_are_globally_visible() { 4fn macro_rules_are_globally_visible() {
5 let map = def_map( 5 check(
6 r" 6 r#"
7 //- /lib.rs 7//- /lib.rs
8 macro_rules! structs { 8macro_rules! structs {
9 ($($i:ident),*) => { 9 ($($i:ident),*) => {
10 $(struct $i { field: u32 } )* 10 $(struct $i { field: u32 } )*
11 } 11 }
12 } 12}
13 structs!(Foo); 13structs!(Foo);
14 mod nested; 14mod nested;
15 15
16 //- /nested.rs 16//- /nested.rs
17 structs!(Bar, Baz); 17structs!(Bar, Baz);
18 ", 18"#,
19 expect![[r#"
20 crate
21 Foo: t
22 nested: t
23
24 crate::nested
25 Bar: t
26 Baz: t
27 "#]],
19 ); 28 );
20 assert_snapshot!(map, @r###"
21 ⋮crate
22 ⋮Foo: t
23 ⋮nested: t
24
25 ⋮crate::nested
26 ⋮Bar: t
27 ⋮Baz: t
28 "###);
29} 29}
30 30
31#[test] 31#[test]
32fn macro_rules_can_define_modules() { 32fn macro_rules_can_define_modules() {
33 let map = def_map( 33 check(
34 r" 34 r#"
35 //- /lib.rs 35//- /lib.rs
36 macro_rules! m { 36macro_rules! m {
37 ($name:ident) => { mod $name; } 37 ($name:ident) => { mod $name; }
38 } 38}
39 m!(n1); 39m!(n1);
40 40mod m { m!(n3) }
41 mod m { 41
42 m!(n3) 42//- /n1.rs
43 } 43m!(n2)
44 44//- /n1/n2.rs
45 //- /n1.rs 45struct X;
46 m!(n2) 46//- /m/n3.rs
47 //- /n1/n2.rs 47struct Y;
48 struct X; 48"#,
49 //- /m/n3.rs 49 expect![[r#"
50 struct Y; 50 crate
51 ", 51 m: t
52 n1: t
53
54 crate::m
55 n3: t
56
57 crate::m::n3
58 Y: t v
59
60 crate::n1
61 n2: t
62
63 crate::n1::n2
64 X: t v
65 "#]],
52 ); 66 );
53 assert_snapshot!(map, @r###"
54 ⋮crate
55 ⋮m: t
56 ⋮n1: t
57
58 ⋮crate::m
59 ⋮n3: t
60
61 ⋮crate::m::n3
62 ⋮Y: t v
63
64 ⋮crate::n1
65 ⋮n2: t
66
67 ⋮crate::n1::n2
68 ⋮X: t v
69 "###);
70} 67}
71 68
72#[test] 69#[test]
73fn macro_rules_from_other_crates_are_visible() { 70fn macro_rules_from_other_crates_are_visible() {
74 let map = def_map( 71 check(
75 " 72 r#"
76 //- /main.rs crate:main deps:foo 73//- /main.rs crate:main deps:foo
77 foo::structs!(Foo, Bar) 74foo::structs!(Foo, Bar)
78 mod bar; 75mod bar;
79 76
80 //- /bar.rs 77//- /bar.rs
81 use crate::*; 78use crate::*;
82 79
83 //- /lib.rs crate:foo 80//- /lib.rs crate:foo
84 #[macro_export] 81#[macro_export]
85 macro_rules! structs { 82macro_rules! structs {
86 ($($i:ident),*) => { 83 ($($i:ident),*) => {
87 $(struct $i { field: u32 } )* 84 $(struct $i { field: u32 } )*
88 } 85 }
89 } 86}
90 ", 87"#,
88 expect![[r#"
89 crate
90 Bar: t
91 Foo: t
92 bar: t
93
94 crate::bar
95 Bar: t
96 Foo: t
97 bar: t
98 "#]],
91 ); 99 );
92 assert_snapshot!(map, @r###"
93 ⋮crate
94 ⋮Bar: t
95 ⋮Foo: t
96 ⋮bar: t
97
98 ⋮crate::bar
99 ⋮Bar: t
100 ⋮Foo: t
101 ⋮bar: t
102 "###);
103} 100}
104 101
105#[test] 102#[test]
106fn macro_rules_export_with_local_inner_macros_are_visible() { 103fn macro_rules_export_with_local_inner_macros_are_visible() {
107 let map = def_map( 104 check(
108 " 105 r#"
109 //- /main.rs crate:main deps:foo 106//- /main.rs crate:main deps:foo
110 foo::structs!(Foo, Bar) 107foo::structs!(Foo, Bar)
111 mod bar; 108mod bar;
112 109
113 //- /bar.rs 110//- /bar.rs
114 use crate::*; 111use crate::*;
115 112
116 //- /lib.rs crate:foo 113//- /lib.rs crate:foo
117 #[macro_export(local_inner_macros)] 114#[macro_export(local_inner_macros)]
118 macro_rules! structs { 115macro_rules! structs {
119 ($($i:ident),*) => { 116 ($($i:ident),*) => {
120 $(struct $i { field: u32 } )* 117 $(struct $i { field: u32 } )*
121 } 118 }
122 } 119}
123 ", 120"#,
121 expect![[r#"
122 crate
123 Bar: t
124 Foo: t
125 bar: t
126
127 crate::bar
128 Bar: t
129 Foo: t
130 bar: t
131 "#]],
124 ); 132 );
125 assert_snapshot!(map, @r###"
126 ⋮crate
127 ⋮Bar: t
128 ⋮Foo: t
129 ⋮bar: t
130
131 ⋮crate::bar
132 ⋮Bar: t
133 ⋮Foo: t
134 ⋮bar: t
135 "###);
136} 133}
137 134
138#[test] 135#[test]
139fn local_inner_macros_makes_local_macros_usable() { 136fn local_inner_macros_makes_local_macros_usable() {
140 let map = def_map( 137 check(
141 " 138 r#"
142 //- /main.rs crate:main deps:foo 139//- /main.rs crate:main deps:foo
143 foo::structs!(Foo, Bar); 140foo::structs!(Foo, Bar);
144 mod bar; 141mod bar;
145 //- /bar.rs 142
146 use crate::*; 143//- /bar.rs
147 //- /lib.rs crate:foo 144use crate::*;
148 #[macro_export(local_inner_macros)] 145
149 macro_rules! structs { 146//- /lib.rs crate:foo
150 ($($i:ident),*) => { 147#[macro_export(local_inner_macros)]
151 inner!($($i),*); 148macro_rules! structs {
152 } 149 ($($i:ident),*) => {
153 } 150 inner!($($i),*);
154 #[macro_export] 151 }
155 macro_rules! inner { 152}
156 ($($i:ident),*) => { 153#[macro_export]
157 $(struct $i { field: u32 } )* 154macro_rules! inner {
158 } 155 ($($i:ident),*) => {
159 } 156 $(struct $i { field: u32 } )*
160 ", 157 }
158}
159"#,
160 expect![[r#"
161 crate
162 Bar: t
163 Foo: t
164 bar: t
165
166 crate::bar
167 Bar: t
168 Foo: t
169 bar: t
170 "#]],
161 ); 171 );
162 assert_snapshot!(map, @r###"
163 ⋮crate
164 ⋮Bar: t
165 ⋮Foo: t
166 ⋮bar: t
167
168 ⋮crate::bar
169 ⋮Bar: t
170 ⋮Foo: t
171 ⋮bar: t
172 "###);
173} 172}
174 173
175#[test] 174#[test]
176fn unexpanded_macro_should_expand_by_fixedpoint_loop() { 175fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
177 let map = def_map( 176 check(
178 " 177 r#"
179 //- /main.rs crate:main deps:foo 178//- /main.rs crate:main deps:foo
180 macro_rules! baz { 179macro_rules! baz {
181 () => { 180 () => {
182 use foo::bar; 181 use foo::bar;
183 } 182 }
184 } 183}
185 184foo!();
186 foo!(); 185bar!();
187 bar!(); 186baz!();
188 baz!(); 187
189 188//- /lib.rs crate:foo
190 //- /lib.rs crate:foo 189#[macro_export]
191 #[macro_export] 190macro_rules! foo {
192 macro_rules! foo { 191 () => {
193 () => { 192 struct Foo { field: u32 }
194 struct Foo { field: u32 } 193 }
195 } 194}
196 } 195#[macro_export]
197 #[macro_export] 196macro_rules! bar {
198 macro_rules! bar { 197 () => {
199 () => { 198 use foo::foo;
200 use foo::foo; 199 }
201 } 200}
202 } 201"#,
203 ", 202 expect![[r#"
203 crate
204 Foo: t
205 bar: m
206 foo: m
207 "#]],
204 ); 208 );
205 assert_snapshot!(map, @r###"
206 ⋮crate
207 ⋮Foo: t
208 ⋮bar: m
209 ⋮foo: m
210 "###);
211} 209}
212 210
213#[test] 211#[test]
214fn macro_rules_from_other_crates_are_visible_with_macro_use() { 212fn macro_rules_from_other_crates_are_visible_with_macro_use() {
215 mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use); 213 mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use);
216 let map = def_map( 214 check(
217 " 215 r#"
218 //- /main.rs crate:main deps:foo 216//- /main.rs crate:main deps:foo
219 structs!(Foo); 217structs!(Foo);
220 structs_priv!(Bar); 218structs_priv!(Bar);
221 structs_not_exported!(MacroNotResolved1); 219structs_not_exported!(MacroNotResolved1);
222 crate::structs!(MacroNotResolved2); 220crate::structs!(MacroNotResolved2);
223 221
224 mod bar; 222mod bar;
225 223
226 #[macro_use] 224#[macro_use]
227 extern crate foo; 225extern crate foo;
228 226
229 //- /bar.rs 227//- /bar.rs
230 structs!(Baz); 228structs!(Baz);
231 crate::structs!(MacroNotResolved3); 229crate::structs!(MacroNotResolved3);
232 230
233 //- /lib.rs crate:foo 231//- /lib.rs crate:foo
234 #[macro_export] 232#[macro_export]
235 macro_rules! structs { 233macro_rules! structs {
236 ($i:ident) => { struct $i; } 234 ($i:ident) => { struct $i; }
237 } 235}
238 236
239 macro_rules! structs_not_exported { 237macro_rules! structs_not_exported {
240 ($i:ident) => { struct $i; } 238 ($i:ident) => { struct $i; }
241 } 239}
242 240
243 mod priv_mod { 241mod priv_mod {
244 #[macro_export] 242 #[macro_export]
245 macro_rules! structs_priv { 243 macro_rules! structs_priv {
246 ($i:ident) => { struct $i; } 244 ($i:ident) => { struct $i; }
247 } 245 }
248 } 246}
249 ", 247"#,
248 expect![[r#"
249 crate
250 Bar: t v
251 Foo: t v
252 bar: t
253 foo: t
254
255 crate::bar
256 Baz: t v
257 "#]],
250 ); 258 );
251 assert_snapshot!(map, @r###"
252 ⋮crate
253 ⋮Bar: t v
254 ⋮Foo: t v
255 ⋮bar: t
256 ⋮foo: t
257
258 ⋮crate::bar
259 ⋮Baz: t v
260 "###);
261} 259}
262 260
263#[test] 261#[test]
264fn prelude_is_macro_use() { 262fn prelude_is_macro_use() {
265 mark::check!(prelude_is_macro_use); 263 mark::check!(prelude_is_macro_use);
266 let map = def_map( 264 check(
267 " 265 r#"
268 //- /main.rs crate:main deps:foo 266//- /main.rs crate:main deps:foo
269 structs!(Foo); 267structs!(Foo);
270 structs_priv!(Bar); 268structs_priv!(Bar);
271 structs_outside!(Out); 269structs_outside!(Out);
272 crate::structs!(MacroNotResolved2); 270crate::structs!(MacroNotResolved2);
273 271
274 mod bar; 272mod bar;
275
276 //- /bar.rs
277 structs!(Baz);
278 crate::structs!(MacroNotResolved3);
279
280 //- /lib.rs crate:foo
281 #[prelude_import]
282 use self::prelude::*;
283
284 mod prelude {
285 #[macro_export]
286 macro_rules! structs {
287 ($i:ident) => { struct $i; }
288 }
289
290 mod priv_mod {
291 #[macro_export]
292 macro_rules! structs_priv {
293 ($i:ident) => { struct $i; }
294 }
295 }
296 }
297 273
274//- /bar.rs
275structs!(Baz);
276crate::structs!(MacroNotResolved3);
277
278//- /lib.rs crate:foo
279#[prelude_import]
280use self::prelude::*;
281
282mod prelude {
283 #[macro_export]
284 macro_rules! structs {
285 ($i:ident) => { struct $i; }
286 }
287
288 mod priv_mod {
298 #[macro_export] 289 #[macro_export]
299 macro_rules! structs_outside { 290 macro_rules! structs_priv {
300 ($i:ident) => { struct $i; } 291 ($i:ident) => { struct $i; }
301 } 292 }
302 ", 293 }
294}
295
296#[macro_export]
297macro_rules! structs_outside {
298 ($i:ident) => { struct $i; }
299}
300"#,
301 expect![[r#"
302 crate
303 Bar: t v
304 Foo: t v
305 Out: t v
306 bar: t
307
308 crate::bar
309 Baz: t v
310 "#]],
303 ); 311 );
304 assert_snapshot!(map, @r###"
305 ⋮crate
306 ⋮Bar: t v
307 ⋮Foo: t v
308 ⋮Out: t v
309 ⋮bar: t
310
311 ⋮crate::bar
312 ⋮Baz: t v
313 "###);
314} 312}
315 313
316#[test] 314#[test]
317fn prelude_cycle() { 315fn prelude_cycle() {
318 let map = def_map( 316 check(
319 " 317 r#"
320 //- /lib.rs 318#[prelude_import]
321 #[prelude_import] 319use self::prelude::*;
322 use self::prelude::*;
323 320
324 declare_mod!(); 321declare_mod!();
325 322
326 mod prelude { 323mod prelude {
327 macro_rules! declare_mod { 324 macro_rules! declare_mod {
328 () => (mod foo {}) 325 () => (mod foo {})
329 } 326 }
330 } 327}
331 ", 328"#,
329 expect![[r#"
330 crate
331 prelude: t
332
333 crate::prelude
334 "#]],
332 ); 335 );
333 assert_snapshot!(map, @r###"
334 ⋮crate
335 ⋮prelude: t
336
337 ⋮crate::prelude
338 "###);
339} 336}
340 337
341#[test] 338#[test]
342fn plain_macros_are_legacy_textual_scoped() { 339fn plain_macros_are_legacy_textual_scoped() {
343 let map = def_map( 340 check(
344 r#" 341 r#"
345 //- /main.rs 342//- /main.rs
346 mod m1; 343mod m1;
347 bar!(NotFoundNotMacroUse); 344bar!(NotFoundNotMacroUse);
348 345
349 mod m2 { 346mod m2 { foo!(NotFoundBeforeInside2); }
350 foo!(NotFoundBeforeInside2);
351 }
352 347
353 macro_rules! foo { 348macro_rules! foo {
354 ($x:ident) => { struct $x; } 349 ($x:ident) => { struct $x; }
355 } 350}
356 foo!(Ok); 351foo!(Ok);
357
358 mod m3;
359 foo!(OkShadowStop);
360 bar!(NotFoundMacroUseStop);
361
362 #[macro_use]
363 mod m5 {
364 #[macro_use]
365 mod m6 {
366 macro_rules! foo {
367 ($x:ident) => { fn $x() {} }
368 }
369 }
370 }
371 foo!(ok_double_macro_use_shadow);
372
373 baz!(NotFoundBefore);
374 #[macro_use]
375 mod m7 {
376 macro_rules! baz {
377 ($x:ident) => { struct $x; }
378 }
379 }
380 baz!(OkAfter);
381 352
382 //- /m1.rs 353mod m3;
383 foo!(NotFoundBeforeInside1); 354foo!(OkShadowStop);
384 macro_rules! bar { 355bar!(NotFoundMacroUseStop);
385 ($x:ident) => { struct $x; }
386 }
387 356
388 //- /m3/mod.rs 357#[macro_use]
389 foo!(OkAfterInside); 358mod m5 {
359 #[macro_use]
360 mod m6 {
390 macro_rules! foo { 361 macro_rules! foo {
391 ($x:ident) => { fn $x() {} } 362 ($x:ident) => { fn $x() {} }
392 } 363 }
393 foo!(ok_shadow); 364 }
365}
366foo!(ok_double_macro_use_shadow);
367
368baz!(NotFoundBefore);
369#[macro_use]
370mod m7 {
371 macro_rules! baz {
372 ($x:ident) => { struct $x; }
373 }
374}
375baz!(OkAfter);
394 376
395 #[macro_use] 377//- /m1.rs
396 mod m4; 378foo!(NotFoundBeforeInside1);
397 bar!(OkMacroUse); 379macro_rules! bar {
380 ($x:ident) => { struct $x; }
381}
398 382
399 //- /m3/m4.rs 383//- /m3/mod.rs
400 foo!(ok_shadow_deep); 384foo!(OkAfterInside);
401 macro_rules! bar { 385macro_rules! foo {
402 ($x:ident) => { struct $x; } 386 ($x:ident) => { fn $x() {} }
403 } 387}
404 "#, 388foo!(ok_shadow);
389
390#[macro_use]
391mod m4;
392bar!(OkMacroUse);
393
394//- /m3/m4.rs
395foo!(ok_shadow_deep);
396macro_rules! bar {
397 ($x:ident) => { struct $x; }
398}
399"#,
400 expect![[r#"
401 crate
402 Ok: t v
403 OkAfter: t v
404 OkShadowStop: t v
405 m1: t
406 m2: t
407 m3: t
408 m5: t
409 m7: t
410 ok_double_macro_use_shadow: v
411
412 crate::m7
413
414 crate::m1
415
416 crate::m5
417 m6: t
418
419 crate::m5::m6
420
421 crate::m2
422
423 crate::m3
424 OkAfterInside: t v
425 OkMacroUse: t v
426 m4: t
427 ok_shadow: v
428
429 crate::m3::m4
430 ok_shadow_deep: v
431 "#]],
405 ); 432 );
406 assert_snapshot!(map, @r###"
407 ⋮crate
408 ⋮Ok: t v
409 ⋮OkAfter: t v
410 ⋮OkShadowStop: t v
411 ⋮m1: t
412 ⋮m2: t
413 ⋮m3: t
414 ⋮m5: t
415 ⋮m7: t
416 ⋮ok_double_macro_use_shadow: v
417
418 ⋮crate::m7
419
420 ⋮crate::m1
421
422 ⋮crate::m5
423 ⋮m6: t
424
425 ⋮crate::m5::m6
426
427 ⋮crate::m2
428
429 ⋮crate::m3
430 ⋮OkAfterInside: t v
431 ⋮OkMacroUse: t v
432 ⋮m4: t
433 ⋮ok_shadow: v
434
435 ⋮crate::m3::m4
436 ⋮ok_shadow_deep: v
437 "###);
438} 433}
439 434
440#[test] 435#[test]
441fn type_value_macro_live_in_different_scopes() { 436fn type_value_macro_live_in_different_scopes() {
442 let map = def_map( 437 check(
443 " 438 r#"
444 //- /main.rs 439#[macro_export]
445 #[macro_export] 440macro_rules! foo {
446 macro_rules! foo { 441 ($x:ident) => { type $x = (); }
447 ($x:ident) => { type $x = (); } 442}
448 }
449
450 foo!(foo);
451 use foo as bar;
452 443
453 use self::foo as baz; 444foo!(foo);
454 fn baz() {} 445use foo as bar;
455 ", 446
447use self::foo as baz;
448fn baz() {}
449"#,
450 expect![[r#"
451 crate
452 bar: t m
453 baz: t v m
454 foo: t m
455 "#]],
456 ); 456 );
457 assert_snapshot!(map, @r###"
458 ⋮crate
459 ⋮bar: t m
460 ⋮baz: t v m
461 ⋮foo: t m
462 "###);
463} 457}
464 458
465#[test] 459#[test]
466fn macro_use_can_be_aliased() { 460fn macro_use_can_be_aliased() {
467 let map = def_map( 461 check(
468 " 462 r#"
469 //- /main.rs crate:main deps:foo 463//- /main.rs crate:main deps:foo
470 #[macro_use] 464#[macro_use]
471 extern crate foo; 465extern crate foo;
472 466
473 foo!(Direct); 467foo!(Direct);
474 bar!(Alias); 468bar!(Alias);
475 469
476 //- /lib.rs crate:foo 470//- /lib.rs crate:foo
477 use crate::foo as bar; 471use crate::foo as bar;
478 472
479 mod m { 473mod m {
480 #[macro_export] 474 #[macro_export]
481 macro_rules! foo { 475 macro_rules! foo {
482 ($x:ident) => { struct $x; } 476 ($x:ident) => { struct $x; }
483 } 477 }
484 } 478}
485 ", 479"#,
480 expect![[r#"
481 crate
482 Alias: t v
483 Direct: t v
484 foo: t
485 "#]],
486 ); 486 );
487 assert_snapshot!(map, @r###"
488 ⋮crate
489 ⋮Alias: t v
490 ⋮Direct: t v
491 ⋮foo: t
492 "###);
493} 487}
494 488
495#[test] 489#[test]
496fn path_qualified_macros() { 490fn path_qualified_macros() {
497 let map = def_map( 491 check(
498 " 492 r#"
499 //- /main.rs 493macro_rules! foo {
500 macro_rules! foo { 494 ($x:ident) => { struct $x; }
501 ($x:ident) => { struct $x; } 495}
502 }
503 496
504 crate::foo!(NotResolved); 497crate::foo!(NotResolved);
505 498
506 crate::bar!(OkCrate); 499crate::bar!(OkCrate);
507 bar!(OkPlain); 500bar!(OkPlain);
508 alias1!(NotHere); 501alias1!(NotHere);
509 m::alias1!(OkAliasPlain); 502m::alias1!(OkAliasPlain);
510 m::alias2!(OkAliasSuper); 503m::alias2!(OkAliasSuper);
511 m::alias3!(OkAliasCrate); 504m::alias3!(OkAliasCrate);
512 not_found!(NotFound); 505not_found!(NotFound);
513 506
514 mod m { 507mod m {
515 #[macro_export] 508 #[macro_export]
516 macro_rules! bar { 509 macro_rules! bar {
517 ($x:ident) => { struct $x; } 510 ($x:ident) => { struct $x; }
518 } 511 }
519 512 pub use bar as alias1;
520 pub use bar as alias1; 513 pub use super::bar as alias2;
521 pub use super::bar as alias2; 514 pub use crate::bar as alias3;
522 pub use crate::bar as alias3; 515 pub use self::bar as not_found;
523 pub use self::bar as not_found; 516}
524 } 517"#,
525 ", 518 expect![[r#"
519 crate
520 OkAliasCrate: t v
521 OkAliasPlain: t v
522 OkAliasSuper: t v
523 OkCrate: t v
524 OkPlain: t v
525 bar: m
526 m: t
527
528 crate::m
529 alias1: m
530 alias2: m
531 alias3: m
532 not_found: _
533 "#]],
526 ); 534 );
527 assert_snapshot!(map, @r###"
528 ⋮crate
529 ⋮OkAliasCrate: t v
530 ⋮OkAliasPlain: t v
531 ⋮OkAliasSuper: t v
532 ⋮OkCrate: t v
533 ⋮OkPlain: t v
534 ⋮bar: m
535 ⋮m: t
536
537 ⋮crate::m
538 ⋮alias1: m
539 ⋮alias2: m
540 ⋮alias3: m
541 ⋮not_found: _
542 "###);
543} 535}
544 536
545#[test] 537#[test]
546fn macro_dollar_crate_is_correct_in_item() { 538fn macro_dollar_crate_is_correct_in_item() {
547 mark::check!(macro_dollar_crate_self); 539 mark::check!(macro_dollar_crate_self);
548 let map = def_map( 540 check(
549 " 541 r#"
550 //- /main.rs crate:main deps:foo 542//- /main.rs crate:main deps:foo
551 #[macro_use] 543#[macro_use]
552 extern crate foo; 544extern crate foo;
553 545
554 #[macro_use] 546#[macro_use]
555 mod m { 547mod m {
556 macro_rules! current { 548 macro_rules! current {
557 () => { 549 () => {
558 use $crate::Foo as FooSelf; 550 use $crate::Foo as FooSelf;
559 }
560 }
561 } 551 }
552 }
553}
562 554
563 struct Foo; 555struct Foo;
564 556
565 current!(); 557current!();
566 not_current1!(); 558not_current1!();
567 foo::not_current2!(); 559foo::not_current2!();
568
569 //- /lib.rs crate:foo
570 mod m {
571 #[macro_export]
572 macro_rules! not_current1 {
573 () => {
574 use $crate::Bar;
575 }
576 }
577 }
578 560
579 #[macro_export] 561//- /lib.rs crate:foo
580 macro_rules! not_current2 { 562mod m {
581 () => { 563 #[macro_export]
582 use $crate::Baz; 564 macro_rules! not_current1 {
583 } 565 () => {
566 use $crate::Bar;
584 } 567 }
568 }
569}
585 570
586 struct Bar; 571#[macro_export]
587 struct Baz; 572macro_rules! not_current2 {
588 ", 573 () => {
574 use $crate::Baz;
575 }
576}
577
578struct Bar;
579struct Baz;
580"#,
581 expect![[r#"
582 crate
583 Bar: t v
584 Baz: t v
585 Foo: t v
586 FooSelf: t v
587 foo: t
588 m: t
589
590 crate::m
591 "#]],
589 ); 592 );
590 assert_snapshot!(map, @r###"
591 ⋮crate
592 ⋮Bar: t v
593 ⋮Baz: t v
594 ⋮Foo: t v
595 ⋮FooSelf: t v
596 ⋮foo: t
597 ⋮m: t
598
599 ⋮crate::m
600 "###);
601} 593}
602 594
603#[test] 595#[test]
604fn macro_dollar_crate_is_correct_in_indirect_deps() { 596fn macro_dollar_crate_is_correct_in_indirect_deps() {
605 mark::check!(macro_dollar_crate_other); 597 mark::check!(macro_dollar_crate_other);
606 // From std 598 // From std
607 let map = def_map( 599 check(
608 r#" 600 r#"
609 //- /main.rs crate:main deps:std 601//- /main.rs crate:main deps:std
610 foo!(); 602foo!();
611 603
612 //- /std.rs crate:std deps:core 604//- /std.rs crate:std deps:core
613 #[prelude_import] 605#[prelude_import]
614 use self::prelude::*; 606use self::prelude::*;
615 607
616 pub use core::foo; 608pub use core::foo;
617 609
618 mod prelude {} 610mod prelude {}
619 611
620 #[macro_use] 612#[macro_use]
621 mod std_macros; 613mod std_macros;
622 614
623 //- /core.rs crate:core 615//- /core.rs crate:core
624 #[macro_export] 616#[macro_export]
625 macro_rules! foo { 617macro_rules! foo {
626 () => { 618 () => {
627 use $crate::bar; 619 use $crate::bar;
628 } 620 }
629 } 621}
630 622
631 pub struct bar; 623pub struct bar;
632 "#, 624"#,
625 expect![[r#"
626 crate
627 bar: t v
628 "#]],
633 ); 629 );
634 assert_snapshot!(map, @r###"
635 ⋮crate
636 ⋮bar: t v
637 "###);
638} 630}
639 631
640#[test] 632#[test]
@@ -642,21 +634,36 @@ fn expand_derive() {
642 let map = compute_crate_def_map( 634 let map = compute_crate_def_map(
643 " 635 "
644 //- /main.rs 636 //- /main.rs
645 #[derive(Clone)] 637 #[derive(Copy, Clone)]
646 struct Foo; 638 struct Foo;
647 ", 639 ",
648 ); 640 );
649 assert_eq!(map.modules[map.root].scope.impls().len(), 1); 641 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
650} 642}
651 643
652#[test] 644#[test]
653fn expand_multiple_derive() { 645fn macro_expansion_overflow() {
654 let map = compute_crate_def_map( 646 mark::check!(macro_expansion_overflow);
655 " 647 check(
656 //- /main.rs 648 r#"
657 #[derive(Copy, Clone)] 649macro_rules! a {
658 struct Foo; 650 ($e:expr; $($t:tt)*) => {
659 ", 651 b!($($t)*);
652 };
653 () => {};
654}
655
656macro_rules! b {
657 (static = $e:expr; $($t:tt)*) => {
658 a!($e; $($t)*);
659 };
660 () => {};
661}
662
663b! { static = #[] (); }
664"#,
665 expect![[r#"
666 crate
667 "#]],
660 ); 668 );
661 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
662} 669}
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 753684201..ae58948c4 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -3,710 +3,672 @@ use super::*;
3#[test] 3#[test]
4fn name_res_works_for_broken_modules() { 4fn name_res_works_for_broken_modules() {
5 mark::check!(name_res_works_for_broken_modules); 5 mark::check!(name_res_works_for_broken_modules);
6 let map = def_map( 6 check(
7 r" 7 r"
8 //- /lib.rs 8//- /lib.rs
9 mod foo // no `;`, no body 9mod foo // no `;`, no body
10 10use self::foo::Baz;
11 use self::foo::Baz; 11
12 12//- /foo/mod.rs
13 //- /foo/mod.rs 13pub mod bar;
14 pub mod bar; 14pub use self::bar::Baz;
15 15
16 pub use self::bar::Baz; 16//- /foo/bar.rs
17 17pub struct Baz;
18 //- /foo/bar.rs 18",
19 pub struct Baz; 19 expect![[r#"
20 ", 20 crate
21 Baz: _
22 foo: t
23
24 crate::foo
25 "#]],
21 ); 26 );
22 assert_snapshot!(map, @r###"
23crate
24Baz: _
25foo: t
26
27crate::foo
28 "###);
29} 27}
30 28
31#[test] 29#[test]
32fn nested_module_resolution() { 30fn nested_module_resolution() {
33 let map = def_map( 31 check(
34 r" 32 r#"
35 //- /lib.rs 33//- /lib.rs
36 mod n1; 34mod n1;
37 35
38 //- /n1.rs 36//- /n1.rs
39 mod n2; 37mod n2;
40 38
41 //- /n1/n2.rs 39//- /n1/n2.rs
42 struct X; 40struct X;
43 ", 41"#,
42 expect![[r#"
43 crate
44 n1: t
45
46 crate::n1
47 n2: t
48
49 crate::n1::n2
50 X: t v
51 "#]],
44 ); 52 );
45
46 assert_snapshot!(map, @r###"
47 ⋮crate
48 ⋮n1: t
49
50 ⋮crate::n1
51 ⋮n2: t
52
53 ⋮crate::n1::n2
54 ⋮X: t v
55 "###);
56} 53}
57 54
58#[test] 55#[test]
59fn nested_module_resolution_2() { 56fn nested_module_resolution_2() {
60 let map = def_map( 57 check(
61 r" 58 r#"
62 //- /lib.rs 59//- /lib.rs
63 mod prelude; 60mod prelude;
64 mod iter; 61mod iter;
65 62
66 //- /prelude.rs 63//- /prelude.rs
67 pub use crate::iter::Iterator; 64pub use crate::iter::Iterator;
68 65
69 //- /iter.rs 66//- /iter.rs
70 pub use self::traits::Iterator; 67pub use self::traits::Iterator;
71 mod traits; 68mod traits;
72 69
73 //- /iter/traits.rs 70//- /iter/traits.rs
74 pub use self::iterator::Iterator; 71pub use self::iterator::Iterator;
75 mod iterator; 72mod iterator;
76 73
77 //- /iter/traits/iterator.rs 74//- /iter/traits/iterator.rs
78 pub trait Iterator; 75pub trait Iterator;
79 ", 76"#,
77 expect![[r#"
78 crate
79 iter: t
80 prelude: t
81
82 crate::iter
83 Iterator: t
84 traits: t
85
86 crate::iter::traits
87 Iterator: t
88 iterator: t
89
90 crate::iter::traits::iterator
91 Iterator: t
92
93 crate::prelude
94 Iterator: t
95 "#]],
80 ); 96 );
81
82 assert_snapshot!(map, @r###"
83 ⋮crate
84 ⋮iter: t
85 ⋮prelude: t
86
87 ⋮crate::iter
88 ⋮Iterator: t
89 ⋮traits: t
90
91 ⋮crate::iter::traits
92 ⋮Iterator: t
93 ⋮iterator: t
94
95 ⋮crate::iter::traits::iterator
96 ⋮Iterator: t
97
98 ⋮crate::prelude
99 ⋮Iterator: t
100 "###);
101} 97}
102 98
103#[test] 99#[test]
104fn module_resolution_works_for_non_standard_filenames() { 100fn module_resolution_works_for_non_standard_filenames() {
105 let map = def_map( 101 check(
106 " 102 r#"
107 //- /my_library.rs crate:my_library 103//- /my_library.rs crate:my_library
108 mod foo; 104mod foo;
109 use self::foo::Bar; 105use self::foo::Bar;
110 106
111 //- /foo/mod.rs 107//- /foo/mod.rs
112 pub struct Bar; 108pub struct Bar;
113 ", 109"#,
110 expect![[r#"
111 crate
112 Bar: t v
113 foo: t
114
115 crate::foo
116 Bar: t v
117 "#]],
114 ); 118 );
115
116 assert_snapshot!(map, @r###"
117 ⋮crate
118 ⋮Bar: t v
119 ⋮foo: t
120
121 ⋮crate::foo
122 ⋮Bar: t v
123 "###);
124} 119}
125 120
126#[test] 121#[test]
127fn module_resolution_works_for_raw_modules() { 122fn module_resolution_works_for_raw_modules() {
128 let map = def_map( 123 check(
129 " 124 r#"
130 //- /lib.rs 125//- /lib.rs
131 mod r#async; 126mod r#async;
132 use self::r#async::Bar; 127use self::r#async::Bar;
133 128
134 //- /async.rs 129//- /async.rs
135 pub struct Bar; 130pub struct Bar;
136 ", 131"#,
132 expect![[r#"
133 crate
134 Bar: t v
135 async: t
136
137 crate::async
138 Bar: t v
139 "#]],
137 ); 140 );
138
139 assert_snapshot!(map, @r###"
140 ⋮crate
141 ⋮Bar: t v
142 ⋮async: t
143
144 ⋮crate::async
145 ⋮Bar: t v
146 "###);
147} 141}
148 142
149#[test] 143#[test]
150fn module_resolution_decl_path() { 144fn module_resolution_decl_path() {
151 let map = def_map( 145 check(
152 r###" 146 r#"
153 //- /lib.rs 147//- /lib.rs
154 #[path = "bar/baz/foo.rs"] 148#[path = "bar/baz/foo.rs"]
155 mod foo; 149mod foo;
156 use self::foo::Bar; 150use self::foo::Bar;
157 151
158 //- /bar/baz/foo.rs 152//- /bar/baz/foo.rs
159 pub struct Bar; 153pub struct Bar;
160 "###, 154"#,
155 expect![[r#"
156 crate
157 Bar: t v
158 foo: t
159
160 crate::foo
161 Bar: t v
162 "#]],
161 ); 163 );
162
163 assert_snapshot!(map, @r###"
164 ⋮crate
165 ⋮Bar: t v
166 ⋮foo: t
167
168 ⋮crate::foo
169 ⋮Bar: t v
170 "###);
171} 164}
172 165
173#[test] 166#[test]
174fn module_resolution_module_with_path_in_mod_rs() { 167fn module_resolution_module_with_path_in_mod_rs() {
175 let map = def_map( 168 check(
176 r###" 169 r#"
177 //- /main.rs 170//- /main.rs
178 mod foo; 171mod foo;
179 172
180 //- /foo/mod.rs 173//- /foo/mod.rs
181 #[path = "baz.rs"] 174#[path = "baz.rs"]
182 pub mod bar; 175pub mod bar;
183 176use self::bar::Baz;
184 use self::bar::Baz; 177
185 178//- /foo/baz.rs
186 //- /foo/baz.rs 179pub struct Baz;
187 pub struct Baz; 180"#,
188 "###, 181 expect![[r#"
182 crate
183 foo: t
184
185 crate::foo
186 Baz: t v
187 bar: t
188
189 crate::foo::bar
190 Baz: t v
191 "#]],
189 ); 192 );
190
191 assert_snapshot!(map, @r###"
192 ⋮crate
193 ⋮foo: t
194
195 ⋮crate::foo
196 ⋮Baz: t v
197 ⋮bar: t
198
199 ⋮crate::foo::bar
200 ⋮Baz: t v
201 "###);
202} 193}
203 194
204#[test] 195#[test]
205fn module_resolution_module_with_path_non_crate_root() { 196fn module_resolution_module_with_path_non_crate_root() {
206 let map = def_map( 197 check(
207 r###" 198 r#"
208 //- /main.rs 199//- /main.rs
209 mod foo; 200mod foo;
210 201
211 //- /foo.rs 202//- /foo.rs
212 #[path = "baz.rs"] 203#[path = "baz.rs"]
213 pub mod bar; 204pub mod bar;
214 205use self::bar::Baz;
215 use self::bar::Baz; 206
216 207//- /baz.rs
217 //- /baz.rs 208pub struct Baz;
218 pub struct Baz; 209"#,
219 "###, 210 expect![[r#"
211 crate
212 foo: t
213
214 crate::foo
215 Baz: t v
216 bar: t
217
218 crate::foo::bar
219 Baz: t v
220 "#]],
220 ); 221 );
221
222 assert_snapshot!(map, @r###"
223 ⋮crate
224 ⋮foo: t
225
226 ⋮crate::foo
227 ⋮Baz: t v
228 ⋮bar: t
229
230 ⋮crate::foo::bar
231 ⋮Baz: t v
232 "###);
233} 222}
234 223
235#[test] 224#[test]
236fn module_resolution_module_decl_path_super() { 225fn module_resolution_module_decl_path_super() {
237 let map = def_map( 226 check(
238 r###" 227 r#"
239 //- /main.rs 228//- /main.rs
240 #[path = "bar/baz/module.rs"] 229#[path = "bar/baz/module.rs"]
241 mod foo; 230mod foo;
242 pub struct Baz; 231pub struct Baz;
243 232
244 //- /bar/baz/module.rs 233//- /bar/baz/module.rs
245 use super::Baz; 234use super::Baz;
246 "###, 235"#,
236 expect![[r#"
237 crate
238 Baz: t v
239 foo: t
240
241 crate::foo
242 Baz: t v
243 "#]],
247 ); 244 );
248
249 assert_snapshot!(map, @r###"
250 ⋮crate
251 ⋮Baz: t v
252 ⋮foo: t
253
254 ⋮crate::foo
255 ⋮Baz: t v
256 "###);
257} 245}
258 246
259#[test] 247#[test]
260fn module_resolution_explicit_path_mod_rs() { 248fn module_resolution_explicit_path_mod_rs() {
261 let map = def_map( 249 check(
262 r###" 250 r#"
263 //- /main.rs 251//- /main.rs
264 #[path = "module/mod.rs"] 252#[path = "module/mod.rs"]
265 mod foo; 253mod foo;
266 254
267 //- /module/mod.rs 255//- /module/mod.rs
268 pub struct Baz; 256pub struct Baz;
269 "###, 257"#,
258 expect![[r#"
259 crate
260 foo: t
261
262 crate::foo
263 Baz: t v
264 "#]],
270 ); 265 );
271
272 assert_snapshot!(map, @r###"
273 ⋮crate
274 ⋮foo: t
275
276 ⋮crate::foo
277 ⋮Baz: t v
278 "###);
279} 266}
280 267
281#[test] 268#[test]
282fn module_resolution_relative_path() { 269fn module_resolution_relative_path() {
283 let map = def_map( 270 check(
284 r###" 271 r#"
285 //- /main.rs 272//- /main.rs
286 mod foo; 273mod foo;
287 274
288 //- /foo.rs 275//- /foo.rs
289 #[path = "./sub.rs"] 276#[path = "./sub.rs"]
290 pub mod foo_bar; 277pub mod foo_bar;
291 278
292 //- /sub.rs 279//- /sub.rs
293 pub struct Baz; 280pub struct Baz;
294 "###, 281"#,
282 expect![[r#"
283 crate
284 foo: t
285
286 crate::foo
287 foo_bar: t
288
289 crate::foo::foo_bar
290 Baz: t v
291 "#]],
295 ); 292 );
296
297 assert_snapshot!(map, @r###"
298 ⋮crate
299 ⋮foo: t
300
301 ⋮crate::foo
302 ⋮foo_bar: t
303
304 ⋮crate::foo::foo_bar
305 ⋮Baz: t v
306 "###);
307} 293}
308 294
309#[test] 295#[test]
310fn module_resolution_relative_path_2() { 296fn module_resolution_relative_path_2() {
311 let map = def_map( 297 check(
312 r###" 298 r#"
313 //- /main.rs 299//- /main.rs
314 mod foo; 300mod foo;
315 301
316 //- /foo/mod.rs 302//- /foo/mod.rs
317 #[path="../sub.rs"] 303#[path="../sub.rs"]
318 pub mod foo_bar; 304pub mod foo_bar;
319 305
320 //- /sub.rs 306//- /sub.rs
321 pub struct Baz; 307pub struct Baz;
322 "###, 308"#,
309 expect![[r#"
310 crate
311 foo: t
312
313 crate::foo
314 foo_bar: t
315
316 crate::foo::foo_bar
317 Baz: t v
318 "#]],
323 ); 319 );
324
325 assert_snapshot!(map, @r###"
326 ⋮crate
327 ⋮foo: t
328
329 ⋮crate::foo
330 ⋮foo_bar: t
331
332 ⋮crate::foo::foo_bar
333 ⋮Baz: t v
334 "###);
335} 320}
336 321
337#[test] 322#[test]
338fn module_resolution_relative_path_outside_root() { 323fn module_resolution_relative_path_outside_root() {
339 let map = def_map( 324 check(
340 r###" 325 r#"
341 //- /main.rs 326//- /main.rs
342 327#[path="../../../../../outside.rs"]
343 #[path="../../../../../outside.rs"] 328mod foo;
344 mod foo; 329"#,
345 "###, 330 expect![[r#"
331 crate
332 "#]],
346 ); 333 );
347
348 assert_snapshot!(map, @r###"
349 ⋮crate
350 "###);
351} 334}
352 335
353#[test] 336#[test]
354fn module_resolution_explicit_path_mod_rs_2() { 337fn module_resolution_explicit_path_mod_rs_2() {
355 let map = def_map( 338 check(
356 r###" 339 r#"
357 //- /main.rs 340//- /main.rs
358 #[path = "module/bar/mod.rs"] 341#[path = "module/bar/mod.rs"]
359 mod foo; 342mod foo;
360 343
361 //- /module/bar/mod.rs 344//- /module/bar/mod.rs
362 pub struct Baz; 345pub struct Baz;
363 "###, 346"#,
347 expect![[r#"
348 crate
349 foo: t
350
351 crate::foo
352 Baz: t v
353 "#]],
364 ); 354 );
365
366 assert_snapshot!(map, @r###"
367 ⋮crate
368 ⋮foo: t
369
370 ⋮crate::foo
371 ⋮Baz: t v
372 "###);
373} 355}
374 356
375#[test] 357#[test]
376fn module_resolution_explicit_path_mod_rs_with_win_separator() { 358fn module_resolution_explicit_path_mod_rs_with_win_separator() {
377 let map = def_map( 359 check(
378 r###" 360 r#"
379 //- /main.rs 361//- /main.rs
380 #[path = "module\bar\mod.rs"] 362#[path = "module\bar\mod.rs"]
381 mod foo; 363mod foo;
382 364
383 //- /module/bar/mod.rs 365//- /module/bar/mod.rs
384 pub struct Baz; 366pub struct Baz;
385 "###, 367"#,
368 expect![[r#"
369 crate
370 foo: t
371
372 crate::foo
373 Baz: t v
374 "#]],
386 ); 375 );
387
388 assert_snapshot!(map, @r###"
389 ⋮crate
390 ⋮foo: t
391
392 ⋮crate::foo
393 ⋮Baz: t v
394 "###);
395} 376}
396 377
397#[test] 378#[test]
398fn module_resolution_decl_inside_inline_module_with_path_attribute() { 379fn module_resolution_decl_inside_inline_module_with_path_attribute() {
399 let map = def_map( 380 check(
400 r###" 381 r#"
401 //- /main.rs 382//- /main.rs
402 #[path = "models"] 383#[path = "models"]
403 mod foo { 384mod foo { mod bar; }
404 mod bar; 385
405 } 386//- /models/bar.rs
406 387pub struct Baz;
407 //- /models/bar.rs 388"#,
408 pub struct Baz; 389 expect![[r#"
409 "###, 390 crate
391 foo: t
392
393 crate::foo
394 bar: t
395
396 crate::foo::bar
397 Baz: t v
398 "#]],
410 ); 399 );
411
412 assert_snapshot!(map, @r###"
413 ⋮crate
414 ⋮foo: t
415
416 ⋮crate::foo
417 ⋮bar: t
418
419 ⋮crate::foo::bar
420 ⋮Baz: t v
421 "###);
422} 400}
423 401
424#[test] 402#[test]
425fn module_resolution_decl_inside_inline_module() { 403fn module_resolution_decl_inside_inline_module() {
426 let map = def_map( 404 check(
427 r###" 405 r#"
428 //- /main.rs 406//- /main.rs
429 mod foo { 407mod foo { mod bar; }
430 mod bar; 408
431 } 409//- /foo/bar.rs
432 410pub struct Baz;
433 //- /foo/bar.rs 411"#,
434 pub struct Baz; 412 expect![[r#"
435 "###, 413 crate
414 foo: t
415
416 crate::foo
417 bar: t
418
419 crate::foo::bar
420 Baz: t v
421 "#]],
436 ); 422 );
437
438 assert_snapshot!(map, @r###"
439 ⋮crate
440 ⋮foo: t
441
442 ⋮crate::foo
443 ⋮bar: t
444
445 ⋮crate::foo::bar
446 ⋮Baz: t v
447 "###);
448} 423}
449 424
450#[test] 425#[test]
451fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { 426fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
452 let map = def_map( 427 check(
453 r###" 428 r#"
454 //- /main.rs 429//- /main.rs
455 #[path = "models/db"] 430#[path = "models/db"]
456 mod foo { 431mod foo { mod bar; }
457 mod bar; 432
458 } 433//- /models/db/bar.rs
459 434pub struct Baz;
460 //- /models/db/bar.rs 435"#,
461 pub struct Baz; 436 expect![[r#"
462 "###, 437 crate
438 foo: t
439
440 crate::foo
441 bar: t
442
443 crate::foo::bar
444 Baz: t v
445 "#]],
463 ); 446 );
464
465 assert_snapshot!(map, @r###"
466 ⋮crate
467 ⋮foo: t
468
469 ⋮crate::foo
470 ⋮bar: t
471
472 ⋮crate::foo::bar
473 ⋮Baz: t v
474 "###);
475} 447}
476 448
477#[test] 449#[test]
478fn module_resolution_decl_inside_inline_module_3() { 450fn module_resolution_decl_inside_inline_module_3() {
479 let map = def_map( 451 check(
480 r###" 452 r#"
481 //- /main.rs 453//- /main.rs
482 #[path = "models/db"] 454#[path = "models/db"]
483 mod foo { 455mod foo {
484 #[path = "users.rs"] 456 #[path = "users.rs"]
485 mod bar; 457 mod bar;
486 } 458}
487 459
488 //- /models/db/users.rs 460//- /models/db/users.rs
489 pub struct Baz; 461pub struct Baz;
490 "###, 462"#,
491 ); 463 expect![[r#"
464 crate
465 foo: t
492 466
493 assert_snapshot!(map, @r###" 467 crate::foo
494 ⋮crate 468 bar: t
495 ⋮foo: t 469
496 470 crate::foo::bar
497 ⋮crate::foo 471 Baz: t v
498 ⋮bar: t 472 "#]],
499 473 );
500 ⋮crate::foo::bar
501 ⋮Baz: t v
502 "###);
503} 474}
504 475
505#[test] 476#[test]
506fn module_resolution_decl_inside_inline_module_empty_path() { 477fn module_resolution_decl_inside_inline_module_empty_path() {
507 let map = def_map( 478 check(
508 r###" 479 r#"
509 //- /main.rs 480//- /main.rs
510 #[path = ""] 481#[path = ""]
511 mod foo { 482mod foo {
512 #[path = "users.rs"] 483 #[path = "users.rs"]
513 mod bar; 484 mod bar;
514 } 485}
515
516 //- /users.rs
517 pub struct Baz;
518 "###,
519 );
520 486
521 assert_snapshot!(map, @r###" 487//- /users.rs
522 ⋮crate 488pub struct Baz;
523 ⋮foo: t 489"#,
524 490 expect![[r#"
525 ⋮crate::foo 491 crate
526 ⋮bar: t 492 foo: t
527 493
528 ⋮crate::foo::bar 494 crate::foo
529 ⋮Baz: t v 495 bar: t
530 "###); 496
497 crate::foo::bar
498 Baz: t v
499 "#]],
500 );
531} 501}
532 502
533#[test] 503#[test]
534fn module_resolution_decl_empty_path() { 504fn module_resolution_decl_empty_path() {
535 let map = def_map( 505 check(
536 r###" 506 r#"
537 //- /main.rs 507//- /main.rs
538 #[path = ""] // Should try to read `/` (a directory) 508#[path = ""] // Should try to read `/` (a directory)
539 mod foo; 509mod foo;
540 510
541 //- /foo.rs 511//- /foo.rs
542 pub struct Baz; 512pub struct Baz;
543 "###, 513"#,
514 expect![[r#"
515 crate
516 "#]],
544 ); 517 );
545
546 assert_snapshot!(map, @r###"
547 ⋮crate
548 "###);
549} 518}
550 519
551#[test] 520#[test]
552fn module_resolution_decl_inside_inline_module_relative_path() { 521fn module_resolution_decl_inside_inline_module_relative_path() {
553 let map = def_map( 522 check(
554 r###" 523 r#"
555 //- /main.rs 524//- /main.rs
556 #[path = "./models"] 525#[path = "./models"]
557 mod foo { 526mod foo { mod bar; }
558 mod bar; 527
559 } 528//- /models/bar.rs
560 529pub struct Baz;
561 //- /models/bar.rs 530"#,
562 pub struct Baz; 531 expect![[r#"
563 "###, 532 crate
533 foo: t
534
535 crate::foo
536 bar: t
537
538 crate::foo::bar
539 Baz: t v
540 "#]],
564 ); 541 );
565
566 assert_snapshot!(map, @r###"
567 ⋮crate
568 ⋮foo: t
569
570 ⋮crate::foo
571 ⋮bar: t
572
573 ⋮crate::foo::bar
574 ⋮Baz: t v
575 "###);
576} 542}
577 543
578#[test] 544#[test]
579fn module_resolution_decl_inside_inline_module_in_crate_root() { 545fn module_resolution_decl_inside_inline_module_in_crate_root() {
580 let map = def_map( 546 check(
581 r###" 547 r#"
582 //- /main.rs 548//- /main.rs
583 mod foo { 549mod foo {
584 #[path = "baz.rs"] 550 #[path = "baz.rs"]
585 mod bar; 551 mod bar;
586 } 552}
587 use self::foo::bar::Baz; 553use self::foo::bar::Baz;
588 554
589 //- /foo/baz.rs 555//- /foo/baz.rs
590 pub struct Baz; 556pub struct Baz;
591 "###, 557"#,
558 expect![[r#"
559 crate
560 Baz: t v
561 foo: t
562
563 crate::foo
564 bar: t
565
566 crate::foo::bar
567 Baz: t v
568 "#]],
592 ); 569 );
593
594 assert_snapshot!(map, @r###"
595 ⋮crate
596 ⋮Baz: t v
597 ⋮foo: t
598
599 ⋮crate::foo
600 ⋮bar: t
601
602 ⋮crate::foo::bar
603 ⋮Baz: t v
604 "###);
605} 570}
606 571
607#[test] 572#[test]
608fn module_resolution_decl_inside_inline_module_in_mod_rs() { 573fn module_resolution_decl_inside_inline_module_in_mod_rs() {
609 let map = def_map( 574 check(
610 r###" 575 r#"
611 //- /main.rs 576//- /main.rs
612 mod foo; 577mod foo;
578
579//- /foo/mod.rs
580mod bar {
581 #[path = "qwe.rs"]
582 pub mod baz;
583}
584use self::bar::baz::Baz;
613 585
614 //- /foo/mod.rs 586//- /foo/bar/qwe.rs
615 mod bar { 587pub struct Baz;
616 #[path = "qwe.rs"] 588"#,
617 pub mod baz; 589 expect![[r#"
618 } 590 crate
619 use self::bar::baz::Baz; 591 foo: t
620 592
621 //- /foo/bar/qwe.rs 593 crate::foo
622 pub struct Baz; 594 Baz: t v
623 "###, 595 bar: t
624 ); 596
597 crate::foo::bar
598 baz: t
625 599
626 assert_snapshot!(map, @r###" 600 crate::foo::bar::baz
627 ⋮crate 601 Baz: t v
628 ⋮foo: t 602 "#]],
629 603 );
630 ⋮crate::foo
631 ⋮Baz: t v
632 ⋮bar: t
633
634 ⋮crate::foo::bar
635 ⋮baz: t
636
637 ⋮crate::foo::bar::baz
638 ⋮Baz: t v
639 "###);
640} 604}
641 605
642#[test] 606#[test]
643fn module_resolution_decl_inside_inline_module_in_non_crate_root() { 607fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
644 let map = def_map( 608 check(
645 r###" 609 r#"
646 //- /main.rs 610//- /main.rs
647 mod foo; 611mod foo;
612
613//- /foo.rs
614mod bar {
615 #[path = "qwe.rs"]
616 pub mod baz;
617}
618use self::bar::baz::Baz;
648 619
649 //- /foo.rs 620//- /foo/bar/qwe.rs
650 mod bar { 621pub struct Baz;
651 #[path = "qwe.rs"] 622"#,
652 pub mod baz; 623 expect![[r#"
653 } 624 crate
654 use self::bar::baz::Baz; 625 foo: t
655
656 //- /foo/bar/qwe.rs
657 pub struct Baz;
658 "###,
659 );
660 626
661 assert_snapshot!(map, @r###" 627 crate::foo
662 ⋮crate 628 Baz: t v
663 ⋮foo: t 629 bar: t
664 630
665 ⋮crate::foo 631 crate::foo::bar
666 ⋮Baz: t v 632 baz: t
667 ⋮bar: t 633
668 634 crate::foo::bar::baz
669 ⋮crate::foo::bar 635 Baz: t v
670 ⋮baz: t 636 "#]],
671 637 );
672 ⋮crate::foo::bar::baz
673 ⋮Baz: t v
674 "###);
675} 638}
676 639
677#[test] 640#[test]
678fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { 641fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
679 let map = def_map( 642 check(
680 r###" 643 r#"
681 //- /main.rs 644//- /main.rs
682 mod foo; 645mod foo;
646
647//- /foo.rs
648#[path = "bar"]
649mod bar {
650 pub mod baz;
651}
652use self::bar::baz::Baz;
683 653
684 //- /foo.rs 654//- /bar/baz.rs
685 #[path = "bar"] 655pub struct Baz;
686 mod bar { 656"#,
687 pub mod baz; 657 expect![[r#"
688 } 658 crate
689 use self::bar::baz::Baz; 659 foo: t
690 660
691 //- /bar/baz.rs 661 crate::foo
692 pub struct Baz; 662 Baz: t v
693 "###, 663 bar: t
694 );
695 664
696 assert_snapshot!(map, @r###" 665 crate::foo::bar
697 ⋮crate 666 baz: t
698 ⋮foo: t 667
699 668 crate::foo::bar::baz
700 ⋮crate::foo 669 Baz: t v
701 ⋮Baz: t v 670 "#]],
702 ⋮bar: t 671 );
703
704 ⋮crate::foo::bar
705 ⋮baz: t
706
707 ⋮crate::foo::bar::baz
708 ⋮Baz: t v
709 "###);
710} 672}
711 673
712#[test] 674#[test]
@@ -724,116 +686,111 @@ fn unresolved_module_diagnostics() {
724 686
725 let crate_def_map = db.crate_def_map(krate); 687 let crate_def_map = db.crate_def_map(krate);
726 688
727 insta::assert_debug_snapshot!( 689 expect![[r#"
728 crate_def_map.diagnostics, 690 [
729 @r###" 691 UnresolvedModule {
730 [ 692 module: Idx::<ModuleData>(0),
731 UnresolvedModule { 693 declaration: InFile {
732 module: Idx::<ModuleData>(0), 694 file_id: HirFileId(
733 declaration: InFile {
734 file_id: HirFileId(
735 FileId(
736 FileId( 695 FileId(
737 0, 696 FileId(
697 0,
698 ),
738 ), 699 ),
739 ), 700 ),
740 ), 701 value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1),
741 value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1), 702 },
703 candidate: "bar.rs",
742 }, 704 },
743 candidate: "bar.rs", 705 ]
744 }, 706 "#]]
745 ] 707 .assert_debug_eq(&crate_def_map.diagnostics);
746 "###
747 );
748} 708}
749 709
750#[test] 710#[test]
751fn module_resolution_decl_inside_module_in_non_crate_root_2() { 711fn module_resolution_decl_inside_module_in_non_crate_root_2() {
752 let map = def_map( 712 check(
753 r###" 713 r#"
754 //- /main.rs 714//- /main.rs
755 #[path="module/m2.rs"] 715#[path="module/m2.rs"]
756 mod module; 716mod module;
757 717
758 //- /module/m2.rs 718//- /module/m2.rs
759 pub mod submod; 719pub mod submod;
760 720
761 //- /module/submod.rs 721//- /module/submod.rs
762 pub struct Baz; 722pub struct Baz;
763 "###, 723"#,
724 expect![[r#"
725 crate
726 module: t
727
728 crate::module
729 submod: t
730
731 crate::module::submod
732 Baz: t v
733 "#]],
764 ); 734 );
765
766 assert_snapshot!(map, @r###"
767 ⋮crate
768 ⋮module: t
769
770 ⋮crate::module
771 ⋮submod: t
772
773 ⋮crate::module::submod
774 ⋮Baz: t v
775 "###);
776} 735}
777 736
778#[test] 737#[test]
779fn nested_out_of_line_module() { 738fn nested_out_of_line_module() {
780 let map = def_map( 739 check(
781 r###" 740 r#"
782 //- /lib.rs 741//- /lib.rs
783 mod a { 742mod a {
784 mod b { 743 mod b {
785 mod c; 744 mod c;
786 } 745 }
787 } 746}
788
789 //- /a/b/c.rs
790 struct X;
791 "###,
792 );
793 747
794 assert_snapshot!(map, @r###" 748//- /a/b/c.rs
795 ⋮crate 749struct X;
796 ⋮a: t 750"#,
797 751 expect![[r#"
798 ⋮crate::a 752 crate
799 ⋮b: t 753 a: t
800 754
801 ⋮crate::a::b 755 crate::a
802 ⋮c: t 756 b: t
803 757
804 ⋮crate::a::b::c 758 crate::a::b
805 ⋮X: t v 759 c: t
806 "###); 760
761 crate::a::b::c
762 X: t v
763 "#]],
764 );
807} 765}
808 766
809#[test] 767#[test]
810fn nested_out_of_line_module_with_path() { 768fn nested_out_of_line_module_with_path() {
811 let map = def_map( 769 check(
812 r###" 770 r#"
813 //- /lib.rs 771//- /lib.rs
814 mod a { 772mod a {
815 #[path = "d/e"] 773 #[path = "d/e"]
816 mod b { 774 mod b {
817 mod c; 775 mod c;
818 } 776 }
819 } 777}
820 778
821 //- /a/d/e/c.rs 779//- /a/d/e/c.rs
822 struct X; 780struct X;
823 "###, 781"#,
824 ); 782 expect![[r#"
783 crate
784 a: t
825 785
826 assert_snapshot!(map, @r###" 786 crate::a
827 ⋮crate 787 b: t
828 ⋮a: t 788
829 789 crate::a::b
830 ⋮crate::a 790 c: t
831 ⋮b: t 791
832 792 crate::a::b::c
833 ⋮crate::a::b 793 X: t v
834 ⋮c: t 794 "#]],
835 795 );
836 ⋮crate::a::b::c
837 ⋮X: t v
838 "###);
839} 796}
diff --git a/crates/ra_hir_def/src/nameres/tests/primitives.rs b/crates/ra_hir_def/src/nameres/tests/primitives.rs
index 0e2708658..215e8952d 100644
--- a/crates/ra_hir_def/src/nameres/tests/primitives.rs
+++ b/crates/ra_hir_def/src/nameres/tests/primitives.rs
@@ -2,23 +2,22 @@ use super::*;
2 2
3#[test] 3#[test]
4fn primitive_reexport() { 4fn primitive_reexport() {
5 let map = def_map( 5 check(
6 " 6 r#"
7 //- /lib.rs 7//- /lib.rs
8 mod foo; 8mod foo;
9 use foo::int; 9use foo::int;
10 10
11 //- /foo.rs 11//- /foo.rs
12 pub use i32 as int; 12pub use i32 as int;
13 ", 13"#,
14 ); 14 expect![[r#"
15 assert_snapshot!(map, @r###" 15 crate
16 ⋮crate 16 foo: t
17 ⋮foo: t 17 int: t
18 ⋮int: t 18
19 19 crate::foo
20 ⋮crate::foo 20 int: t
21 ⋮int: t 21 "#]],
22 "###
23 ); 22 );
24} 23}
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs
index 4581d8745..339f819b8 100644
--- a/crates/ra_hir_def/src/test_db.rs
+++ b/crates/ra_hir_def/src/test_db.rs
@@ -1,7 +1,7 @@
1//! Database used for testing `hir_def`. 1//! Database used for testing `hir_def`.
2 2
3use std::{ 3use std::{
4 panic, 4 fmt, panic,
5 sync::{Arc, Mutex}, 5 sync::{Arc, Mutex},
6}; 6};
7 7
@@ -18,10 +18,10 @@ use crate::db::DefDatabase;
18 crate::db::InternDatabaseStorage, 18 crate::db::InternDatabaseStorage,
19 crate::db::DefDatabaseStorage 19 crate::db::DefDatabaseStorage
20)] 20)]
21#[derive(Debug, Default)] 21#[derive(Default)]
22pub struct TestDB { 22pub struct TestDB {
23 runtime: salsa::Runtime<TestDB>, 23 storage: salsa::Storage<TestDB>,
24 events: Mutex<Option<Vec<salsa::Event<TestDB>>>>, 24 events: Mutex<Option<Vec<salsa::Event>>>,
25} 25}
26 26
27impl Upcast<dyn AstDatabase> for TestDB { 27impl Upcast<dyn AstDatabase> for TestDB {
@@ -37,20 +37,20 @@ impl Upcast<dyn DefDatabase> for TestDB {
37} 37}
38 38
39impl salsa::Database for TestDB { 39impl salsa::Database for TestDB {
40 fn salsa_runtime(&self) -> &salsa::Runtime<Self> { 40 fn salsa_event(&self, event: salsa::Event) {
41 &self.runtime
42 }
43 fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
44 &mut self.runtime
45 }
46 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
47 let mut events = self.events.lock().unwrap(); 41 let mut events = self.events.lock().unwrap();
48 if let Some(events) = &mut *events { 42 if let Some(events) = &mut *events {
49 events.push(event()); 43 events.push(event);
50 } 44 }
51 } 45 }
52} 46}
53 47
48impl fmt::Debug for TestDB {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("TestDB").finish()
51 }
52}
53
54impl panic::RefUnwindSafe for TestDB {} 54impl panic::RefUnwindSafe for TestDB {}
55 55
56impl FileLoader for TestDB { 56impl FileLoader for TestDB {
@@ -78,7 +78,7 @@ impl TestDB {
78 panic!("Can't find module for file") 78 panic!("Can't find module for file")
79 } 79 }
80 80
81 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> { 81 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> {
82 *self.events.lock().unwrap() = Some(Vec::new()); 82 *self.events.lock().unwrap() = Some(Vec::new());
83 f(); 83 f();
84 self.events.lock().unwrap().take().unwrap() 84 self.events.lock().unwrap().take().unwrap()
@@ -92,7 +92,7 @@ impl TestDB {
92 // This pretty horrible, but `Debug` is the only way to inspect 92 // This pretty horrible, but `Debug` is the only way to inspect
93 // QueryDescriptor at the moment. 93 // QueryDescriptor at the moment.
94 salsa::EventKind::WillExecute { database_key } => { 94 salsa::EventKind::WillExecute { database_key } => {
95 Some(format!("{:?}", database_key)) 95 Some(format!("{:?}", database_key.debug(self)))
96 } 96 }
97 _ => None, 97 _ => None,
98 }) 98 })
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index 86a77b704..e90b2a0b9 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -63,7 +63,7 @@ pub enum TypeRef {
63 Array(Box<TypeRef> /*, Expr*/), 63 Array(Box<TypeRef> /*, Expr*/),
64 Slice(Box<TypeRef>), 64 Slice(Box<TypeRef>),
65 /// A fn pointer. Last element of the vector is the return type. 65 /// A fn pointer. Last element of the vector is the return type.
66 Fn(Vec<TypeRef>), 66 Fn(Vec<TypeRef>, bool /*varargs*/),
67 // For 67 // For
68 ImplTrait(Vec<TypeBound>), 68 ImplTrait(Vec<TypeBound>),
69 DynTrait(Vec<TypeBound>), 69 DynTrait(Vec<TypeBound>),
@@ -118,7 +118,12 @@ impl TypeRef {
118 .and_then(|rt| rt.type_ref()) 118 .and_then(|rt| rt.type_ref())
119 .map(|it| TypeRef::from_ast(ctx, it)) 119 .map(|it| TypeRef::from_ast(ctx, it))
120 .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); 120 .unwrap_or_else(|| TypeRef::Tuple(Vec::new()));
121 let mut is_varargs = false;
121 let mut params = if let Some(pl) = inner.param_list() { 122 let mut params = if let Some(pl) = inner.param_list() {
123 if let Some(param) = pl.params().last() {
124 is_varargs = param.dotdotdot_token().is_some();
125 }
126
122 pl.params() 127 pl.params()
123 .map(|p| p.ascribed_type()) 128 .map(|p| p.ascribed_type())
124 .map(|it| TypeRef::from_ast_opt(&ctx, it)) 129 .map(|it| TypeRef::from_ast_opt(&ctx, it))
@@ -127,7 +132,7 @@ impl TypeRef {
127 Vec::new() 132 Vec::new()
128 }; 133 };
129 params.push(ret_ty); 134 params.push(ret_ty);
130 TypeRef::Fn(params) 135 TypeRef::Fn(params, is_varargs)
131 } 136 }
132 // for types are close enough for our purposes to the inner type for now... 137 // for types are close enough for our purposes to the inner type for now...
133 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), 138 ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()),
@@ -158,7 +163,9 @@ impl TypeRef {
158 fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) { 163 fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
159 f(type_ref); 164 f(type_ref);
160 match type_ref { 165 match type_ref {
161 TypeRef::Fn(types) | TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)), 166 TypeRef::Fn(types, _) | TypeRef::Tuple(types) => {
167 types.iter().for_each(|t| go(t, f))
168 }
162 TypeRef::RawPtr(type_ref, _) 169 TypeRef::RawPtr(type_ref, _)
163 | TypeRef::Reference(type_ref, _) 170 | TypeRef::Reference(type_ref, _)
164 | TypeRef::Array(type_ref) 171 | TypeRef::Array(type_ref)