diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 65 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/import_map.rs | 300 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 214 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/mod_resolution.rs | 116 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests.rs | 844 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/globs.rs | 578 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/macros.rs | 1061 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/mod_resolution.rs | 1289 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/primitives.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir_def/src/test_db.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_def/src/type_ref.rs | 13 |
18 files changed, 2367 insertions, 2319 deletions
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; | |||
14 | use ra_prof::profile; | 14 | use ra_prof::profile; |
15 | use ra_syntax::{ast, AstNode, AstPtr}; | 15 | use ra_syntax::{ast, AstNode, AstPtr}; |
16 | use rustc_hash::FxHashMap; | 16 | use rustc_hash::FxHashMap; |
17 | use test_utils::mark; | ||
17 | 18 | ||
18 | pub(crate) use lower::LowerCtx; | 19 | pub(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)] | ||
50 | const EXPANSION_RECURSION_LIMIT: usize = 32; | ||
51 | |||
52 | #[cfg(not(test))] | ||
53 | const EXPANSION_RECURSION_LIMIT: usize = 128; | ||
54 | |||
48 | impl CfgExpander { | 55 | impl 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)] | ||
323 | mod 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 | " | ||
351 | macro_rules! n_nuple { | ||
352 | ($e:tt) => (); | ||
353 | ($($rest:tt)*) => {{ | ||
354 | (n_nuple!($($rest)*)None,) | ||
355 | }}; | ||
356 | } | ||
357 | fn 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 | ||
33 | impl FunctionData { | 34 | impl 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)] |
329 | mod tests { | 329 | mod 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 @@ | |||
1 | use super::{ItemTree, ModItem, ModKind}; | 1 | use expect::{expect, Expect}; |
2 | use crate::{db::DefDatabase, test_db::TestDB}; | ||
3 | use hir_expand::{db::AstDatabase, HirFileId, InFile}; | 2 | use hir_expand::{db::AstDatabase, HirFileId, InFile}; |
4 | use insta::assert_snapshot; | ||
5 | use ra_db::fixture::WithFixture; | 3 | use ra_db::fixture::WithFixture; |
6 | use ra_syntax::{ast, AstNode}; | 4 | use ra_syntax::{ast, AstNode}; |
7 | use rustc_hash::FxHashSet; | 5 | use rustc_hash::FxHashSet; |
8 | use std::sync::Arc; | 6 | use std::sync::Arc; |
9 | use stdx::format_to; | 7 | use stdx::format_to; |
10 | 8 | ||
9 | use crate::{db::DefDatabase, test_db::TestDB}; | ||
10 | |||
11 | use super::{ItemTree, ModItem, ModKind}; | ||
12 | |||
11 | fn test_inner_items(ra_fixture: &str) { | 13 | fn 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 | ||
167 | fn 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] |
166 | fn smoke() { | 173 | fn 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 | ", |
218 | inner 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 }]) } | |
220 | top-level items: | 228 | |
221 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }] | 229 | top-level items: |
222 | 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) } | 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) } |
224 | 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) } | 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) } |
226 | 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) } | 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) } |
228 | 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) } | 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) } |
238 | 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 } | 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 } |
240 | 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 } | 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 } |
242 | 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 } | 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 } |
244 | 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) } | 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) } |
246 | 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) } | 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] |
251 | fn simple_inner_items() { | 261 | fn 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: |
266 | inner 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 | ||
268 | top-level items: | 280 | inner items: |
269 | 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) } | ||
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 | ||
272 | inner 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 | ||
274 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): | 285 | "#]], |
275 | Function { 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] |
281 | fn extern_attrs() { | 290 | fn 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###" | ||
295 | inner attrs: Attrs { entries: None } | ||
296 | |||
297 | top-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 }]) }] | ||
299 | 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) } | ||
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 }]) }] | ||
301 | 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) } | ||
302 | "###); | ||
303 | } | 311 | } |
304 | 312 | ||
305 | #[test] | 313 | #[test] |
306 | fn trait_attrs() { | 314 | fn 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###" | ||
320 | inner attrs: Attrs { entries: None } | ||
321 | |||
322 | top-level items: | ||
323 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }] | ||
324 | 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) } | ||
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] |
333 | fn impl_attrs() { | 340 | fn 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###" | ||
347 | inner attrs: Attrs { entries: None } | ||
348 | |||
349 | top-level items: | ||
350 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }] | ||
351 | 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) } | ||
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] |
393 | fn inner_item_attrs() { | 399 | fn 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###" | ||
404 | inner attrs: Attrs { entries: None } | ||
405 | 409 | ||
406 | top-level items: | 410 | top-level items: |
407 | 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>(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 | ||
409 | inner items: | 413 | inner items: |
410 | 414 | ||
411 | for 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 }]) }] |
413 | Function { 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] |
419 | fn assoc_item_macros() { | 424 | fn 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###" | ||
429 | inner attrs: Attrs { entries: None } | ||
430 | 433 | ||
431 | top-level items: | 434 | top-level items: |
432 | 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) } | 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 | }; |
68 | use stdx::impl_from; | ||
68 | 69 | ||
69 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 70 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
70 | pub struct ModuleId { | 71 | pub struct ModuleId { |
@@ -158,17 +159,17 @@ pub struct FunctionId(salsa::InternId); | |||
158 | type FunctionLoc = AssocItemLoc<Function>; | 159 | type FunctionLoc = AssocItemLoc<Function>; |
159 | impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); | 160 | impl_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)] |
162 | pub struct StructId(salsa::InternId); | 163 | pub struct StructId(salsa::InternId); |
163 | type StructLoc = ItemLoc<Struct>; | 164 | type StructLoc = ItemLoc<Struct>; |
164 | impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); | 165 | impl_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)] |
167 | pub struct UnionId(salsa::InternId); | 168 | pub struct UnionId(salsa::InternId); |
168 | pub type UnionLoc = ItemLoc<Union>; | 169 | pub type UnionLoc = ItemLoc<Union>; |
169 | impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); | 170 | impl_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)] |
172 | pub struct EnumId(salsa::InternId); | 173 | pub struct EnumId(salsa::InternId); |
173 | pub type EnumLoc = ItemLoc<Enum>; | 174 | pub type EnumLoc = ItemLoc<Enum>; |
174 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); | 175 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); |
@@ -223,25 +224,6 @@ pub struct TypeParamId { | |||
223 | 224 | ||
224 | pub type LocalTypeParamId = Idx<generics::TypeParamData>; | 225 | pub type LocalTypeParamId = Idx<generics::TypeParamData>; |
225 | 226 | ||
226 | macro_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)] |
246 | pub enum ContainerId { | 228 | pub 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 | } |
257 | impl_froms!(AssocContainerId: ContainerId); | 239 | impl_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)] |
261 | pub enum AdtId { | 243 | pub enum AdtId { |
262 | StructId(StructId), | 244 | StructId(StructId), |
263 | UnionId(UnionId), | 245 | UnionId(UnionId), |
264 | EnumId(EnumId), | 246 | EnumId(EnumId), |
265 | } | 247 | } |
266 | impl_froms!(AdtId: StructId, UnionId, EnumId); | 248 | impl_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 | } |
282 | impl_froms!( | 264 | impl_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 | ||
302 | impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); | 285 | impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); |
303 | 286 | ||
304 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 287 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
305 | pub enum AssocItemId { | 288 | pub 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. |
314 | impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); | 297 | impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId); |
315 | 298 | ||
316 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 299 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
317 | pub enum GenericDefId { | 300 | pub 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 | } |
329 | impl_froms!( | 312 | impl_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 | ||
339 | impl From<AssocItemId> for GenericDefId { | 323 | impl From<AssocItemId> for GenericDefId { |
@@ -361,8 +345,8 @@ pub enum AttrDefId { | |||
361 | ImplId(ImplId), | 345 | ImplId(ImplId), |
362 | } | 346 | } |
363 | 347 | ||
364 | impl_froms!( | 348 | impl_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 | } |
384 | impl_froms!(VariantId: EnumVariantId, StructId, UnionId); | 369 | impl_from!(EnumVariantId, StructId, UnionId for VariantId); |
385 | 370 | ||
386 | trait Intern { | 371 | trait 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 | ||
39 | const GLOB_RECURSION_LIMIT: usize = 100; | ||
40 | const EXPANSION_DEPTH_LIMIT: usize = 128; | ||
41 | const FIXED_POINT_LIMIT: usize = 8192; | ||
42 | |||
39 | pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 43 | pub(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. |
2 | use hir_expand::name::Name; | 2 | use hir_expand::name::Name; |
3 | use ra_db::{FileId, RelativePathBuf}; | 3 | use ra_db::FileId; |
4 | use ra_syntax::SmolStr; | 4 | use ra_syntax::SmolStr; |
5 | 5 | ||
6 | use crate::{db::DefDatabase, HirFileId}; | 6 | use crate::{db::DefDatabase, HirFileId}; |
7 | 7 | ||
8 | #[derive(Clone, Debug)] | 8 | #[derive(Clone, Debug)] |
9 | pub(super) struct ModDir { | 9 | pub(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 | ||
18 | impl ModDir { | 19 | impl 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 | ||
79 | fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> { | 82 | #[derive(Clone, Debug)] |
80 | attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) | 83 | struct DirPath(String); |
84 | |||
85 | impl 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 | ||
7 | use std::sync::Arc; | 7 | use std::sync::Arc; |
8 | 8 | ||
9 | use insta::assert_snapshot; | 9 | use expect::{expect, Expect}; |
10 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 10 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
11 | use test_utils::mark; | 11 | use test_utils::mark; |
12 | 12 | ||
13 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; | 13 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; |
14 | 14 | ||
15 | fn def_map(ra_fixture: &str) -> String { | ||
16 | compute_crate_def_map(ra_fixture).dump() | ||
17 | } | ||
18 | |||
19 | fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { | 15 | fn 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 | ||
21 | fn 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] |
26 | fn crate_def_map_smoke_test() { | 29 | fn 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; | 33 | mod foo; |
31 | struct S; | 34 | struct S; |
32 | use crate::foo::bar::E; | 35 | use crate::foo::bar::E; |
33 | use self::E::V; | 36 | use 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 |
39 | pub mod bar; | ||
40 | fn f() {} | ||
48 | 41 | ||
49 | extern { | 42 | //- /foo/bar.rs |
50 | static EXT: u8; | 43 | pub struct Baz; |
51 | fn ext(); | 44 | |
52 | } | 45 | union U { to_be: bool, not_to_be: u8 } |
53 | ", | 46 | enum E { V } |
47 | |||
48 | extern { | ||
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] |
76 | fn crate_def_map_super_super() { | 75 | fn crate_def_map_super_super() { |
77 | let map = def_map( | 76 | check( |
78 | " | 77 | r#" |
79 | //- /lib.rs | 78 | mod 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] |
112 | fn crate_def_map_fn_mod_same_name() { | 108 | fn crate_def_map_fn_mod_same_name() { |
113 | let map = def_map( | 109 | check( |
114 | " | 110 | r#" |
115 | //- /lib.rs | 111 | mod 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] |
134 | fn bogus_paths() { | 129 | fn 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; | 134 | mod foo; |
140 | struct S; | 135 | struct S; |
141 | use self; | 136 | use self; |
142 | 137 | ||
143 | //- /foo/mod.rs | 138 | //- /foo/mod.rs |
144 | use super; | 139 | use super; |
145 | use crate; | 140 | use 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] |
160 | fn use_as() { | 153 | fn use_as() { |
161 | let map = def_map( | 154 | check( |
162 | " | 155 | r#" |
163 | //- /lib.rs | 156 | //- /lib.rs |
164 | mod foo; | 157 | mod foo; |
165 | 158 | use 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; | 161 | pub 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] |
185 | fn use_trees() { | 175 | fn use_trees() { |
186 | let map = def_map( | 176 | check( |
187 | " | 177 | r#" |
188 | //- /lib.rs | 178 | //- /lib.rs |
189 | mod foo; | 179 | mod foo; |
190 | 180 | use 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; | 183 | pub mod bar; |
195 | 184 | ||
196 | //- /foo/bar.rs | 185 | //- /foo/bar.rs |
197 | pub struct Baz; | 186 | pub struct Baz; |
198 | pub enum Quux {}; | 187 | pub 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] |
217 | fn re_exports() { | 206 | fn re_exports() { |
218 | let map = def_map( | 207 | check( |
219 | " | 208 | r#" |
220 | //- /lib.rs | 209 | //- /lib.rs |
221 | mod foo; | 210 | mod foo; |
222 | 211 | use 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 |
214 | pub mod bar; | ||
215 | pub use self::bar::Baz; | ||
229 | 216 | ||
230 | //- /foo/bar.rs | 217 | //- /foo/bar.rs |
231 | pub struct Baz; | 218 | pub 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] |
249 | fn std_prelude() { | 236 | fn 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::*; | 241 | use Foo::*; |
255 | 242 | ||
256 | //- /lib.rs crate:test_crate | 243 | //- /lib.rs crate:test_crate |
257 | mod prelude; | 244 | mod prelude; |
258 | #[prelude_import] | 245 | #[prelude_import] |
259 | use prelude::*; | 246 | use prelude::*; |
260 | 247 | ||
261 | //- /prelude.rs | 248 | //- /prelude.rs |
262 | pub enum Foo { Bar, Baz }; | 249 | pub 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] |
273 | fn can_import_enum_variant() { | 260 | fn 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 | 264 | enum E { V } |
278 | enum E { V } | 265 | use 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] |
291 | fn edition_2015_imports() { | 276 | fn 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; | 280 | mod foo; |
296 | mod bar; | 281 | mod bar; |
297 | 282 | ||
298 | //- /bar.rs | 283 | //- /bar.rs |
299 | struct Bar; | 284 | struct 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 | 287 | use bar::Bar; |
312 | ⋮bar: t | 288 | use other_crate::FromLib; |
313 | ⋮foo: t | 289 | |
314 | ⋮ | 290 | //- /lib.rs crate:other_crate edition:2018 |
315 | ⋮crate::bar | 291 | struct 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] |
325 | fn item_map_using_self() { | 309 | fn item_map_using_self() { |
326 | let map = def_map( | 310 | check( |
327 | " | 311 | r#" |
328 | //- /lib.rs | 312 | //- /lib.rs |
329 | mod foo; | 313 | mod foo; |
330 | use crate::foo::bar::Baz::{self}; | 314 | use crate::foo::bar::Baz::{self}; |
331 | //- /foo/mod.rs | 315 | |
332 | pub mod bar; | 316 | //- /foo/mod.rs |
333 | //- /foo/bar.rs | 317 | pub mod bar; |
334 | pub struct Baz; | 318 | |
335 | ", | 319 | //- /foo/bar.rs |
320 | pub 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] |
351 | fn item_map_across_crates() { | 337 | fn 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; | 341 | use 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 | 344 | pub 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] |
369 | fn extern_crate_rename() { | 354 | fn 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; | 358 | extern crate alloc as alloc_crate; |
374 | 359 | mod alloc; | |
375 | mod alloc; | 360 | mod sync; |
376 | mod sync; | ||
377 | 361 | ||
378 | //- /sync.rs | 362 | //- /sync.rs |
379 | use alloc_crate::Arc; | 363 | use alloc_crate::Arc; |
380 | 364 | ||
381 | //- /lib.rs crate:alloc | 365 | //- /lib.rs crate:alloc |
382 | struct Arc; | 366 | struct 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] |
397 | fn extern_crate_rename_2015_edition() { | 380 | fn 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; | 384 | extern crate alloc as alloc_crate; |
402 | 385 | mod alloc; | |
403 | mod alloc; | 386 | mod 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; | 389 | use alloc_crate::Arc; |
411 | ", | ||
412 | ); | ||
413 | 390 | ||
414 | assert_snapshot!(map, | 391 | //- /lib.rs crate:alloc |
415 | @r###" | 392 | struct 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] |
427 | fn reexport_across_crates() { | 406 | fn 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; | 410 | use 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 |
413 | pub use foo::Baz; | ||
414 | mod foo; | ||
437 | 415 | ||
438 | //- /foo.rs | 416 | //- /foo.rs |
439 | pub struct Baz; | 417 | pub 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] |
450 | fn values_dont_shadow_extern_crates() { | 427 | fn 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() {} | 431 | fn foo() {} |
455 | use foo::Bar; | 432 | use 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 | 435 | pub 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] |
470 | fn std_prelude_takes_precedence_above_core_prelude() { | 446 | fn 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}; | 450 | use {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::*; | 454 | pub use self::prelude::*; |
479 | mod prelude { | 455 | mod 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::*; | 462 | pub use self::prelude::*; |
487 | mod prelude { | 463 | mod 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] |
501 | fn cfg_not_test() { | 476 | fn 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}; | 480 | use {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::*; | 484 | pub use self::prelude::*; |
510 | mod prelude { | 485 | mod 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] |
530 | fn cfg_test() { | 504 | fn 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}; | 508 | use {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::*; | 512 | pub use self::prelude::*; |
539 | mod prelude { | 513 | mod 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] |
559 | fn infer_multiple_namespace() { | 532 | fn infer_multiple_namespace() { |
560 | let map = def_map( | 533 | check( |
561 | r#" | 534 | r#" |
562 | //- /main.rs | 535 | //- /main.rs |
563 | mod a { | 536 | mod 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] |
4 | fn glob_1() { | 4 | fn glob_1() { |
5 | let map = def_map( | 5 | check( |
6 | r" | 6 | r#" |
7 | //- /lib.rs | 7 | //- /lib.rs |
8 | mod foo; | 8 | mod foo; |
9 | use foo::*; | 9 | use foo::*; |
10 | 10 | ||
11 | //- /foo/mod.rs | 11 | //- /foo/mod.rs |
12 | pub mod bar; | 12 | pub mod bar; |
13 | pub use self::bar::Baz; | 13 | pub use self::bar::Baz; |
14 | pub struct Foo; | 14 | pub struct Foo; |
15 | 15 | ||
16 | //- /foo/bar.rs | 16 | //- /foo/bar.rs |
17 | pub struct Baz; | 17 | pub 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] |
39 | fn glob_2() { | 38 | fn glob_2() { |
40 | let map = def_map( | 39 | check( |
41 | " | 40 | r#" |
42 | //- /lib.rs | 41 | //- /lib.rs |
43 | mod foo; | 42 | mod foo; |
44 | use foo::*; | 43 | use foo::*; |
45 | 44 | ||
46 | //- /foo/mod.rs | 45 | //- /foo/mod.rs |
47 | pub mod bar; | 46 | pub mod bar; |
48 | pub use self::bar::*; | 47 | pub use self::bar::*; |
49 | pub struct Foo; | 48 | pub struct Foo; |
50 | 49 | ||
51 | //- /foo/bar.rs | 50 | //- /foo/bar.rs |
52 | pub struct Baz; | 51 | pub struct Baz; |
53 | pub use super::*; | 52 | pub 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] |
77 | fn glob_privacy_1() { | 75 | fn glob_privacy_1() { |
78 | let map = def_map( | 76 | check( |
79 | r" | 77 | r" |
80 | //- /lib.rs | 78 | //- /lib.rs |
81 | mod foo; | 79 | mod foo; |
82 | use foo::*; | 80 | use foo::*; |
83 | 81 | ||
84 | //- /foo/mod.rs | 82 | //- /foo/mod.rs |
85 | pub mod bar; | 83 | pub mod bar; |
86 | pub use self::bar::*; | 84 | pub use self::bar::*; |
87 | struct PrivateStructFoo; | 85 | struct PrivateStructFoo; |
88 | 86 | ||
89 | //- /foo/bar.rs | 87 | //- /foo/bar.rs |
90 | pub struct Baz; | 88 | pub struct Baz; |
91 | struct PrivateStructBar; | 89 | struct PrivateStructBar; |
92 | pub use super::*; | 90 | pub 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] |
116 | fn glob_privacy_2() { | 113 | fn glob_privacy_2() { |
117 | let map = def_map( | 114 | check( |
118 | r" | 115 | r" |
119 | //- /lib.rs | 116 | //- /lib.rs |
120 | mod foo; | 117 | mod foo; |
121 | use foo::*; | 118 | use foo::*; |
122 | use foo::bar::*; | 119 | use foo::bar::*; |
123 | 120 | ||
124 | //- /foo/mod.rs | 121 | //- /foo/mod.rs |
125 | mod bar; | 122 | mod bar; |
126 | fn Foo() {}; | 123 | fn Foo() {}; |
127 | pub struct Foo {}; | 124 | pub struct Foo {}; |
128 | 125 | ||
129 | //- /foo/bar.rs | 126 | //- /foo/bar.rs |
130 | pub(super) struct PrivateBaz; | 127 | pub(super) struct PrivateBaz; |
131 | struct PrivateBar; | 128 | struct PrivateBar; |
132 | pub(crate) struct PubCrateStruct; | 129 | pub(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] |
154 | fn glob_across_crates() { | 150 | fn 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::*; | 155 | use test_crate::*; |
160 | 156 | ||
161 | //- /lib.rs crate:test_crate | 157 | //- /lib.rs crate:test_crate |
162 | pub struct Baz; | 158 | pub 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] |
173 | fn glob_privacy_across_crates() { | 168 | fn 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::*; | 172 | use test_crate::*; |
178 | 173 | ||
179 | //- /lib.rs crate:test_crate | 174 | //- /lib.rs crate:test_crate |
180 | pub struct Baz; | 175 | pub struct Baz; |
181 | struct Foo; | 176 | struct 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] |
192 | fn glob_enum() { | 186 | fn 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 | 190 | enum Foo { Bar, Baz } |
197 | enum Foo { | 191 | use 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] |
213 | fn glob_enum_group() { | 203 | fn 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 | 207 | enum Foo { Bar, Baz } |
218 | enum Foo { | 208 | use 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] |
234 | fn glob_shadowed_def() { | 220 | fn 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; | 225 | mod foo; |
240 | mod bar; | 226 | mod bar; |
241 | 227 | use foo::*; | |
242 | use foo::*; | 228 | use bar::baz; |
243 | use bar::baz; | 229 | use baz::Bar; |
244 | 230 | ||
245 | use baz::Bar; | 231 | //- /foo.rs |
246 | 232 | pub mod baz { pub struct Foo; } | |
247 | //- /foo.rs | 233 | |
248 | pub mod baz { | 234 | //- /bar.rs |
249 | pub struct Foo; | 235 | pub 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] |
281 | fn glob_shadowed_def_reversed() { | 260 | fn glob_shadowed_def_reversed() { |
282 | let map = def_map( | 261 | check( |
283 | r###" | 262 | r#" |
284 | //- /lib.rs | 263 | //- /lib.rs |
285 | mod foo; | 264 | mod foo; |
286 | mod bar; | 265 | mod bar; |
287 | 266 | use bar::baz; | |
288 | use bar::baz; | 267 | use foo::*; |
289 | use foo::*; | 268 | use baz::Bar; |
290 | 269 | ||
291 | use baz::Bar; | 270 | //- /foo.rs |
292 | 271 | pub mod baz { pub struct Foo; } | |
293 | //- /foo.rs | 272 | |
294 | pub mod baz { | 273 | //- /bar.rs |
295 | pub struct Foo; | 274 | pub 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] |
327 | fn glob_shadowed_def_dependencies() { | 299 | fn glob_shadowed_def_dependencies() { |
328 | let map = def_map( | 300 | check( |
329 | r###" | 301 | r#" |
330 | //- /lib.rs | 302 | mod a { pub mod foo { pub struct X; } } |
331 | mod a { pub mod foo { pub struct X; } } | 303 | mod b { pub use super::a::foo; } |
332 | mod b { pub use super::a::foo; } | 304 | mod c { pub mod foo { pub struct Y; } } |
333 | mod c { pub mod foo { pub struct Y; } } | 305 | mod 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] |
4 | fn macro_rules_are_globally_visible() { | 4 | fn 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 { | 8 | macro_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); | 13 | structs!(Foo); |
14 | mod nested; | 14 | mod nested; |
15 | 15 | ||
16 | //- /nested.rs | 16 | //- /nested.rs |
17 | structs!(Bar, Baz); | 17 | structs!(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] |
32 | fn macro_rules_can_define_modules() { | 32 | fn 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 { | 36 | macro_rules! m { |
37 | ($name:ident) => { mod $name; } | 37 | ($name:ident) => { mod $name; } |
38 | } | 38 | } |
39 | m!(n1); | 39 | m!(n1); |
40 | 40 | mod m { m!(n3) } | |
41 | mod m { | 41 | |
42 | m!(n3) | 42 | //- /n1.rs |
43 | } | 43 | m!(n2) |
44 | 44 | //- /n1/n2.rs | |
45 | //- /n1.rs | 45 | struct X; |
46 | m!(n2) | 46 | //- /m/n3.rs |
47 | //- /n1/n2.rs | 47 | struct 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] |
73 | fn macro_rules_from_other_crates_are_visible() { | 70 | fn 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) | 74 | foo::structs!(Foo, Bar) |
78 | mod bar; | 75 | mod bar; |
79 | 76 | ||
80 | //- /bar.rs | 77 | //- /bar.rs |
81 | use crate::*; | 78 | use crate::*; |
82 | 79 | ||
83 | //- /lib.rs crate:foo | 80 | //- /lib.rs crate:foo |
84 | #[macro_export] | 81 | #[macro_export] |
85 | macro_rules! structs { | 82 | macro_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] |
106 | fn macro_rules_export_with_local_inner_macros_are_visible() { | 103 | fn 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) | 107 | foo::structs!(Foo, Bar) |
111 | mod bar; | 108 | mod bar; |
112 | 109 | ||
113 | //- /bar.rs | 110 | //- /bar.rs |
114 | use crate::*; | 111 | use 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 { | 115 | macro_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] |
139 | fn local_inner_macros_makes_local_macros_usable() { | 136 | fn 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); | 140 | foo::structs!(Foo, Bar); |
144 | mod bar; | 141 | mod bar; |
145 | //- /bar.rs | 142 | |
146 | use crate::*; | 143 | //- /bar.rs |
147 | //- /lib.rs crate:foo | 144 | use 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),*); | 148 | macro_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 } )* | 154 | macro_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] |
176 | fn unexpanded_macro_should_expand_by_fixedpoint_loop() { | 175 | fn 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 { | 179 | macro_rules! baz { |
181 | () => { | 180 | () => { |
182 | use foo::bar; | 181 | use foo::bar; |
183 | } | 182 | } |
184 | } | 183 | } |
185 | 184 | foo!(); | |
186 | foo!(); | 185 | bar!(); |
187 | bar!(); | 186 | baz!(); |
188 | baz!(); | 187 | |
189 | 188 | //- /lib.rs crate:foo | |
190 | //- /lib.rs crate:foo | 189 | #[macro_export] |
191 | #[macro_export] | 190 | macro_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] | 196 | macro_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] |
214 | fn macro_rules_from_other_crates_are_visible_with_macro_use() { | 212 | fn 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); | 217 | structs!(Foo); |
220 | structs_priv!(Bar); | 218 | structs_priv!(Bar); |
221 | structs_not_exported!(MacroNotResolved1); | 219 | structs_not_exported!(MacroNotResolved1); |
222 | crate::structs!(MacroNotResolved2); | 220 | crate::structs!(MacroNotResolved2); |
223 | 221 | ||
224 | mod bar; | 222 | mod bar; |
225 | 223 | ||
226 | #[macro_use] | 224 | #[macro_use] |
227 | extern crate foo; | 225 | extern crate foo; |
228 | 226 | ||
229 | //- /bar.rs | 227 | //- /bar.rs |
230 | structs!(Baz); | 228 | structs!(Baz); |
231 | crate::structs!(MacroNotResolved3); | 229 | crate::structs!(MacroNotResolved3); |
232 | 230 | ||
233 | //- /lib.rs crate:foo | 231 | //- /lib.rs crate:foo |
234 | #[macro_export] | 232 | #[macro_export] |
235 | macro_rules! structs { | 233 | macro_rules! structs { |
236 | ($i:ident) => { struct $i; } | 234 | ($i:ident) => { struct $i; } |
237 | } | 235 | } |
238 | 236 | ||
239 | macro_rules! structs_not_exported { | 237 | macro_rules! structs_not_exported { |
240 | ($i:ident) => { struct $i; } | 238 | ($i:ident) => { struct $i; } |
241 | } | 239 | } |
242 | 240 | ||
243 | mod priv_mod { | 241 | mod 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] |
264 | fn prelude_is_macro_use() { | 262 | fn 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); | 267 | structs!(Foo); |
270 | structs_priv!(Bar); | 268 | structs_priv!(Bar); |
271 | structs_outside!(Out); | 269 | structs_outside!(Out); |
272 | crate::structs!(MacroNotResolved2); | 270 | crate::structs!(MacroNotResolved2); |
273 | 271 | ||
274 | mod bar; | 272 | mod 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 | ||
275 | structs!(Baz); | ||
276 | crate::structs!(MacroNotResolved3); | ||
277 | |||
278 | //- /lib.rs crate:foo | ||
279 | #[prelude_import] | ||
280 | use self::prelude::*; | ||
281 | |||
282 | mod 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] | ||
297 | macro_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] |
317 | fn prelude_cycle() { | 315 | fn prelude_cycle() { |
318 | let map = def_map( | 316 | check( |
319 | " | 317 | r#" |
320 | //- /lib.rs | 318 | #[prelude_import] |
321 | #[prelude_import] | 319 | use self::prelude::*; |
322 | use self::prelude::*; | ||
323 | 320 | ||
324 | declare_mod!(); | 321 | declare_mod!(); |
325 | 322 | ||
326 | mod prelude { | 323 | mod 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] |
342 | fn plain_macros_are_legacy_textual_scoped() { | 339 | fn 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; | 343 | mod m1; |
347 | bar!(NotFoundNotMacroUse); | 344 | bar!(NotFoundNotMacroUse); |
348 | 345 | ||
349 | mod m2 { | 346 | mod m2 { foo!(NotFoundBeforeInside2); } |
350 | foo!(NotFoundBeforeInside2); | ||
351 | } | ||
352 | 347 | ||
353 | macro_rules! foo { | 348 | macro_rules! foo { |
354 | ($x:ident) => { struct $x; } | 349 | ($x:ident) => { struct $x; } |
355 | } | 350 | } |
356 | foo!(Ok); | 351 | foo!(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 | 353 | mod m3; |
383 | foo!(NotFoundBeforeInside1); | 354 | foo!(OkShadowStop); |
384 | macro_rules! bar { | 355 | bar!(NotFoundMacroUseStop); |
385 | ($x:ident) => { struct $x; } | ||
386 | } | ||
387 | 356 | ||
388 | //- /m3/mod.rs | 357 | #[macro_use] |
389 | foo!(OkAfterInside); | 358 | mod 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 | } | ||
366 | foo!(ok_double_macro_use_shadow); | ||
367 | |||
368 | baz!(NotFoundBefore); | ||
369 | #[macro_use] | ||
370 | mod m7 { | ||
371 | macro_rules! baz { | ||
372 | ($x:ident) => { struct $x; } | ||
373 | } | ||
374 | } | ||
375 | baz!(OkAfter); | ||
394 | 376 | ||
395 | #[macro_use] | 377 | //- /m1.rs |
396 | mod m4; | 378 | foo!(NotFoundBeforeInside1); |
397 | bar!(OkMacroUse); | 379 | macro_rules! bar { |
380 | ($x:ident) => { struct $x; } | ||
381 | } | ||
398 | 382 | ||
399 | //- /m3/m4.rs | 383 | //- /m3/mod.rs |
400 | foo!(ok_shadow_deep); | 384 | foo!(OkAfterInside); |
401 | macro_rules! bar { | 385 | macro_rules! foo { |
402 | ($x:ident) => { struct $x; } | 386 | ($x:ident) => { fn $x() {} } |
403 | } | 387 | } |
404 | "#, | 388 | foo!(ok_shadow); |
389 | |||
390 | #[macro_use] | ||
391 | mod m4; | ||
392 | bar!(OkMacroUse); | ||
393 | |||
394 | //- /m3/m4.rs | ||
395 | foo!(ok_shadow_deep); | ||
396 | macro_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] |
441 | fn type_value_macro_live_in_different_scopes() { | 436 | fn 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] | 440 | macro_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; | 444 | foo!(foo); |
454 | fn baz() {} | 445 | use foo as bar; |
455 | ", | 446 | |
447 | use self::foo as baz; | ||
448 | fn 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] |
466 | fn macro_use_can_be_aliased() { | 460 | fn 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; | 465 | extern crate foo; |
472 | 466 | ||
473 | foo!(Direct); | 467 | foo!(Direct); |
474 | bar!(Alias); | 468 | bar!(Alias); |
475 | 469 | ||
476 | //- /lib.rs crate:foo | 470 | //- /lib.rs crate:foo |
477 | use crate::foo as bar; | 471 | use crate::foo as bar; |
478 | 472 | ||
479 | mod m { | 473 | mod 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] |
496 | fn path_qualified_macros() { | 490 | fn path_qualified_macros() { |
497 | let map = def_map( | 491 | check( |
498 | " | 492 | r#" |
499 | //- /main.rs | 493 | macro_rules! foo { |
500 | macro_rules! foo { | 494 | ($x:ident) => { struct $x; } |
501 | ($x:ident) => { struct $x; } | 495 | } |
502 | } | ||
503 | 496 | ||
504 | crate::foo!(NotResolved); | 497 | crate::foo!(NotResolved); |
505 | 498 | ||
506 | crate::bar!(OkCrate); | 499 | crate::bar!(OkCrate); |
507 | bar!(OkPlain); | 500 | bar!(OkPlain); |
508 | alias1!(NotHere); | 501 | alias1!(NotHere); |
509 | m::alias1!(OkAliasPlain); | 502 | m::alias1!(OkAliasPlain); |
510 | m::alias2!(OkAliasSuper); | 503 | m::alias2!(OkAliasSuper); |
511 | m::alias3!(OkAliasCrate); | 504 | m::alias3!(OkAliasCrate); |
512 | not_found!(NotFound); | 505 | not_found!(NotFound); |
513 | 506 | ||
514 | mod m { | 507 | mod 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] |
546 | fn macro_dollar_crate_is_correct_in_item() { | 538 | fn 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; | 544 | extern crate foo; |
553 | 545 | ||
554 | #[macro_use] | 546 | #[macro_use] |
555 | mod m { | 547 | mod 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; | 555 | struct Foo; |
564 | 556 | ||
565 | current!(); | 557 | current!(); |
566 | not_current1!(); | 558 | not_current1!(); |
567 | foo::not_current2!(); | 559 | foo::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 { | 562 | mod 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; | 572 | macro_rules! not_current2 { |
588 | ", | 573 | () => { |
574 | use $crate::Baz; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | struct Bar; | ||
579 | struct 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] |
604 | fn macro_dollar_crate_is_correct_in_indirect_deps() { | 596 | fn 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!(); | 602 | foo!(); |
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::*; | 606 | use self::prelude::*; |
615 | 607 | ||
616 | pub use core::foo; | 608 | pub use core::foo; |
617 | 609 | ||
618 | mod prelude {} | 610 | mod prelude {} |
619 | 611 | ||
620 | #[macro_use] | 612 | #[macro_use] |
621 | mod std_macros; | 613 | mod std_macros; |
622 | 614 | ||
623 | //- /core.rs crate:core | 615 | //- /core.rs crate:core |
624 | #[macro_export] | 616 | #[macro_export] |
625 | macro_rules! foo { | 617 | macro_rules! foo { |
626 | () => { | 618 | () => { |
627 | use $crate::bar; | 619 | use $crate::bar; |
628 | } | 620 | } |
629 | } | 621 | } |
630 | 622 | ||
631 | pub struct bar; | 623 | pub 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] |
653 | fn expand_multiple_derive() { | 645 | fn 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)] | 649 | macro_rules! a { |
658 | struct Foo; | 650 | ($e:expr; $($t:tt)*) => { |
659 | ", | 651 | b!($($t)*); |
652 | }; | ||
653 | () => {}; | ||
654 | } | ||
655 | |||
656 | macro_rules! b { | ||
657 | (static = $e:expr; $($t:tt)*) => { | ||
658 | a!($e; $($t)*); | ||
659 | }; | ||
660 | () => {}; | ||
661 | } | ||
662 | |||
663 | b! { 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] |
4 | fn name_res_works_for_broken_modules() { | 4 | fn 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 | 9 | mod foo // no `;`, no body |
10 | 10 | use self::foo::Baz; | |
11 | use self::foo::Baz; | 11 | |
12 | 12 | //- /foo/mod.rs | |
13 | //- /foo/mod.rs | 13 | pub mod bar; |
14 | pub mod bar; | 14 | pub use self::bar::Baz; |
15 | 15 | ||
16 | pub use self::bar::Baz; | 16 | //- /foo/bar.rs |
17 | 17 | pub 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###" | ||
23 | crate | ||
24 | Baz: _ | ||
25 | foo: t | ||
26 | |||
27 | crate::foo | ||
28 | "###); | ||
29 | } | 27 | } |
30 | 28 | ||
31 | #[test] | 29 | #[test] |
32 | fn nested_module_resolution() { | 30 | fn nested_module_resolution() { |
33 | let map = def_map( | 31 | check( |
34 | r" | 32 | r#" |
35 | //- /lib.rs | 33 | //- /lib.rs |
36 | mod n1; | 34 | mod n1; |
37 | 35 | ||
38 | //- /n1.rs | 36 | //- /n1.rs |
39 | mod n2; | 37 | mod n2; |
40 | 38 | ||
41 | //- /n1/n2.rs | 39 | //- /n1/n2.rs |
42 | struct X; | 40 | struct 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] |
59 | fn nested_module_resolution_2() { | 56 | fn nested_module_resolution_2() { |
60 | let map = def_map( | 57 | check( |
61 | r" | 58 | r#" |
62 | //- /lib.rs | 59 | //- /lib.rs |
63 | mod prelude; | 60 | mod prelude; |
64 | mod iter; | 61 | mod iter; |
65 | 62 | ||
66 | //- /prelude.rs | 63 | //- /prelude.rs |
67 | pub use crate::iter::Iterator; | 64 | pub use crate::iter::Iterator; |
68 | 65 | ||
69 | //- /iter.rs | 66 | //- /iter.rs |
70 | pub use self::traits::Iterator; | 67 | pub use self::traits::Iterator; |
71 | mod traits; | 68 | mod traits; |
72 | 69 | ||
73 | //- /iter/traits.rs | 70 | //- /iter/traits.rs |
74 | pub use self::iterator::Iterator; | 71 | pub use self::iterator::Iterator; |
75 | mod iterator; | 72 | mod iterator; |
76 | 73 | ||
77 | //- /iter/traits/iterator.rs | 74 | //- /iter/traits/iterator.rs |
78 | pub trait Iterator; | 75 | pub 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] |
104 | fn module_resolution_works_for_non_standard_filenames() { | 100 | fn 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; | 104 | mod foo; |
109 | use self::foo::Bar; | 105 | use self::foo::Bar; |
110 | 106 | ||
111 | //- /foo/mod.rs | 107 | //- /foo/mod.rs |
112 | pub struct Bar; | 108 | pub 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] |
127 | fn module_resolution_works_for_raw_modules() { | 122 | fn 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; | 126 | mod r#async; |
132 | use self::r#async::Bar; | 127 | use self::r#async::Bar; |
133 | 128 | ||
134 | //- /async.rs | 129 | //- /async.rs |
135 | pub struct Bar; | 130 | pub 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] |
150 | fn module_resolution_decl_path() { | 144 | fn 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; | 149 | mod foo; |
156 | use self::foo::Bar; | 150 | use self::foo::Bar; |
157 | 151 | ||
158 | //- /bar/baz/foo.rs | 152 | //- /bar/baz/foo.rs |
159 | pub struct Bar; | 153 | pub 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] |
174 | fn module_resolution_module_with_path_in_mod_rs() { | 167 | fn 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; | 171 | mod foo; |
179 | 172 | ||
180 | //- /foo/mod.rs | 173 | //- /foo/mod.rs |
181 | #[path = "baz.rs"] | 174 | #[path = "baz.rs"] |
182 | pub mod bar; | 175 | pub mod bar; |
183 | 176 | use self::bar::Baz; | |
184 | use self::bar::Baz; | 177 | |
185 | 178 | //- /foo/baz.rs | |
186 | //- /foo/baz.rs | 179 | pub 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] |
205 | fn module_resolution_module_with_path_non_crate_root() { | 196 | fn 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; | 200 | mod foo; |
210 | 201 | ||
211 | //- /foo.rs | 202 | //- /foo.rs |
212 | #[path = "baz.rs"] | 203 | #[path = "baz.rs"] |
213 | pub mod bar; | 204 | pub mod bar; |
214 | 205 | use self::bar::Baz; | |
215 | use self::bar::Baz; | 206 | |
216 | 207 | //- /baz.rs | |
217 | //- /baz.rs | 208 | pub 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] |
236 | fn module_resolution_module_decl_path_super() { | 225 | fn 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; | 230 | mod foo; |
242 | pub struct Baz; | 231 | pub struct Baz; |
243 | 232 | ||
244 | //- /bar/baz/module.rs | 233 | //- /bar/baz/module.rs |
245 | use super::Baz; | 234 | use 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] |
260 | fn module_resolution_explicit_path_mod_rs() { | 248 | fn 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; | 253 | mod foo; |
266 | 254 | ||
267 | //- /module/mod.rs | 255 | //- /module/mod.rs |
268 | pub struct Baz; | 256 | pub 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] |
282 | fn module_resolution_relative_path() { | 269 | fn module_resolution_relative_path() { |
283 | let map = def_map( | 270 | check( |
284 | r###" | 271 | r#" |
285 | //- /main.rs | 272 | //- /main.rs |
286 | mod foo; | 273 | mod foo; |
287 | 274 | ||
288 | //- /foo.rs | 275 | //- /foo.rs |
289 | #[path = "./sub.rs"] | 276 | #[path = "./sub.rs"] |
290 | pub mod foo_bar; | 277 | pub mod foo_bar; |
291 | 278 | ||
292 | //- /sub.rs | 279 | //- /sub.rs |
293 | pub struct Baz; | 280 | pub 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] |
310 | fn module_resolution_relative_path_2() { | 296 | fn 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; | 300 | mod foo; |
315 | 301 | ||
316 | //- /foo/mod.rs | 302 | //- /foo/mod.rs |
317 | #[path="../sub.rs"] | 303 | #[path="../sub.rs"] |
318 | pub mod foo_bar; | 304 | pub mod foo_bar; |
319 | 305 | ||
320 | //- /sub.rs | 306 | //- /sub.rs |
321 | pub struct Baz; | 307 | pub 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] |
338 | fn module_resolution_relative_path_outside_root() { | 323 | fn 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"] | 328 | mod 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] |
354 | fn module_resolution_explicit_path_mod_rs_2() { | 337 | fn 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; | 342 | mod foo; |
360 | 343 | ||
361 | //- /module/bar/mod.rs | 344 | //- /module/bar/mod.rs |
362 | pub struct Baz; | 345 | pub 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] |
376 | fn module_resolution_explicit_path_mod_rs_with_win_separator() { | 358 | fn 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; | 363 | mod foo; |
382 | 364 | ||
383 | //- /module/bar/mod.rs | 365 | //- /module/bar/mod.rs |
384 | pub struct Baz; | 366 | pub 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] |
398 | fn module_resolution_decl_inside_inline_module_with_path_attribute() { | 379 | fn 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 { | 384 | mod foo { mod bar; } |
404 | mod bar; | 385 | |
405 | } | 386 | //- /models/bar.rs |
406 | 387 | pub 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] |
425 | fn module_resolution_decl_inside_inline_module() { | 403 | fn 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 { | 407 | mod foo { mod bar; } |
430 | mod bar; | 408 | |
431 | } | 409 | //- /foo/bar.rs |
432 | 410 | pub 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] |
451 | fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { | 426 | fn 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 { | 431 | mod foo { mod bar; } |
457 | mod bar; | 432 | |
458 | } | 433 | //- /models/db/bar.rs |
459 | 434 | pub 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] |
478 | fn module_resolution_decl_inside_inline_module_3() { | 450 | fn 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 { | 455 | mod 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; | 461 | pub 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] |
506 | fn module_resolution_decl_inside_inline_module_empty_path() { | 477 | fn 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 { | 482 | mod 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 | 488 | pub 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] |
534 | fn module_resolution_decl_empty_path() { | 504 | fn 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; | 509 | mod foo; |
540 | 510 | ||
541 | //- /foo.rs | 511 | //- /foo.rs |
542 | pub struct Baz; | 512 | pub 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] |
552 | fn module_resolution_decl_inside_inline_module_relative_path() { | 521 | fn 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 { | 526 | mod foo { mod bar; } |
558 | mod bar; | 527 | |
559 | } | 528 | //- /models/bar.rs |
560 | 529 | pub 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] |
579 | fn module_resolution_decl_inside_inline_module_in_crate_root() { | 545 | fn 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 { | 549 | mod foo { |
584 | #[path = "baz.rs"] | 550 | #[path = "baz.rs"] |
585 | mod bar; | 551 | mod bar; |
586 | } | 552 | } |
587 | use self::foo::bar::Baz; | 553 | use self::foo::bar::Baz; |
588 | 554 | ||
589 | //- /foo/baz.rs | 555 | //- /foo/baz.rs |
590 | pub struct Baz; | 556 | pub 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] |
608 | fn module_resolution_decl_inside_inline_module_in_mod_rs() { | 573 | fn 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; | 577 | mod foo; |
578 | |||
579 | //- /foo/mod.rs | ||
580 | mod bar { | ||
581 | #[path = "qwe.rs"] | ||
582 | pub mod baz; | ||
583 | } | ||
584 | use self::bar::baz::Baz; | ||
613 | 585 | ||
614 | //- /foo/mod.rs | 586 | //- /foo/bar/qwe.rs |
615 | mod bar { | 587 | pub 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] |
643 | fn module_resolution_decl_inside_inline_module_in_non_crate_root() { | 607 | fn 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; | 611 | mod foo; |
612 | |||
613 | //- /foo.rs | ||
614 | mod bar { | ||
615 | #[path = "qwe.rs"] | ||
616 | pub mod baz; | ||
617 | } | ||
618 | use self::bar::baz::Baz; | ||
648 | 619 | ||
649 | //- /foo.rs | 620 | //- /foo/bar/qwe.rs |
650 | mod bar { | 621 | pub 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] |
678 | fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { | 641 | fn 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; | 645 | mod foo; |
646 | |||
647 | //- /foo.rs | ||
648 | #[path = "bar"] | ||
649 | mod bar { | ||
650 | pub mod baz; | ||
651 | } | ||
652 | use self::bar::baz::Baz; | ||
683 | 653 | ||
684 | //- /foo.rs | 654 | //- /bar/baz.rs |
685 | #[path = "bar"] | 655 | pub 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] |
751 | fn module_resolution_decl_inside_module_in_non_crate_root_2() { | 711 | fn 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; | 716 | mod module; |
757 | 717 | ||
758 | //- /module/m2.rs | 718 | //- /module/m2.rs |
759 | pub mod submod; | 719 | pub mod submod; |
760 | 720 | ||
761 | //- /module/submod.rs | 721 | //- /module/submod.rs |
762 | pub struct Baz; | 722 | pub 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] |
779 | fn nested_out_of_line_module() { | 738 | fn 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 { | 742 | mod 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 | 749 | struct 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] |
810 | fn nested_out_of_line_module_with_path() { | 768 | fn 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 { | 772 | mod 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; | 780 | struct 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] |
4 | fn primitive_reexport() { | 4 | fn primitive_reexport() { |
5 | let map = def_map( | 5 | check( |
6 | " | 6 | r#" |
7 | //- /lib.rs | 7 | //- /lib.rs |
8 | mod foo; | 8 | mod foo; |
9 | use foo::int; | 9 | use foo::int; |
10 | 10 | ||
11 | //- /foo.rs | 11 | //- /foo.rs |
12 | pub use i32 as int; | 12 | pub 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 | ||
3 | use std::{ | 3 | use 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)] |
22 | pub struct TestDB { | 22 | pub 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 | ||
27 | impl Upcast<dyn AstDatabase> for TestDB { | 27 | impl Upcast<dyn AstDatabase> for TestDB { |
@@ -37,20 +37,20 @@ impl Upcast<dyn DefDatabase> for TestDB { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | impl salsa::Database for TestDB { | 39 | impl 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 | ||
48 | impl fmt::Debug for TestDB { | ||
49 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
50 | f.debug_struct("TestDB").finish() | ||
51 | } | ||
52 | } | ||
53 | |||
54 | impl panic::RefUnwindSafe for TestDB {} | 54 | impl panic::RefUnwindSafe for TestDB {} |
55 | 55 | ||
56 | impl FileLoader for TestDB { | 56 | impl 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) |