diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/mod_resolution.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/mod_resolution.rs | 31 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 18 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0036_partial_use.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0036_partial_use.txt | 51 |
6 files changed, 104 insertions, 9 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index a6b9b41d0..6b253ac40 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::FileId; |
2 | use ra_syntax::ast; | 2 | use ra_syntax::{ast, SmolStr}; |
3 | use rustc_hash::FxHashMap; | 3 | use rustc_hash::FxHashMap; |
4 | use test_utils::tested_by; | 4 | use test_utils::tested_by; |
5 | 5 | ||
@@ -98,6 +98,7 @@ where | |||
98 | self.def_map.modules[module_id].definition = Some(file_id); | 98 | self.def_map.modules[module_id].definition = Some(file_id); |
99 | ModCollector { | 99 | ModCollector { |
100 | def_collector: &mut *self, | 100 | def_collector: &mut *self, |
101 | attr_path: None, | ||
101 | module_id, | 102 | module_id, |
102 | file_id: file_id.into(), | 103 | file_id: file_id.into(), |
103 | raw_items: &raw_items, | 104 | raw_items: &raw_items, |
@@ -474,6 +475,7 @@ where | |||
474 | ModCollector { | 475 | ModCollector { |
475 | def_collector: &mut *self, | 476 | def_collector: &mut *self, |
476 | file_id, | 477 | file_id, |
478 | attr_path: None, | ||
477 | module_id, | 479 | module_id, |
478 | raw_items: &raw_items, | 480 | raw_items: &raw_items, |
479 | parent_module: None, | 481 | parent_module: None, |
@@ -497,6 +499,7 @@ struct ModCollector<'a, D> { | |||
497 | def_collector: D, | 499 | def_collector: D, |
498 | module_id: CrateModuleId, | 500 | module_id: CrateModuleId, |
499 | file_id: HirFileId, | 501 | file_id: HirFileId, |
502 | attr_path: Option<&'a SmolStr>, | ||
500 | raw_items: &'a raw::RawItems, | 503 | raw_items: &'a raw::RawItems, |
501 | parent_module: Option<ParentModule<'a>>, | 504 | parent_module: Option<ParentModule<'a>>, |
502 | } | 505 | } |
@@ -551,6 +554,7 @@ where | |||
551 | ModCollector { | 554 | ModCollector { |
552 | def_collector: &mut *self.def_collector, | 555 | def_collector: &mut *self.def_collector, |
553 | module_id, | 556 | module_id, |
557 | attr_path: attr_path.as_ref(), | ||
554 | file_id: self.file_id, | 558 | file_id: self.file_id, |
555 | raw_items: self.raw_items, | 559 | raw_items: self.raw_items, |
556 | parent_module: Some(parent_module), | 560 | parent_module: Some(parent_module), |
@@ -567,6 +571,7 @@ where | |||
567 | match resolve_submodule( | 571 | match resolve_submodule( |
568 | self.def_collector.db, | 572 | self.def_collector.db, |
569 | self.file_id, | 573 | self.file_id, |
574 | self.attr_path, | ||
570 | name, | 575 | name, |
571 | is_root, | 576 | is_root, |
572 | attr_path.as_ref(), | 577 | attr_path.as_ref(), |
@@ -578,6 +583,7 @@ where | |||
578 | ModCollector { | 583 | ModCollector { |
579 | def_collector: &mut *self.def_collector, | 584 | def_collector: &mut *self.def_collector, |
580 | module_id, | 585 | module_id, |
586 | attr_path: attr_path.as_ref(), | ||
581 | file_id: file_id.into(), | 587 | file_id: file_id.into(), |
582 | raw_items: &raw_items, | 588 | raw_items: &raw_items, |
583 | parent_module: None, | 589 | parent_module: None, |
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs index a9e9eb9e6..3aa32bd66 100644 --- a/crates/ra_hir/src/nameres/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/mod_resolution.rs | |||
@@ -23,6 +23,7 @@ impl<'a> ParentModule<'a> { | |||
23 | pub(super) fn resolve_submodule( | 23 | pub(super) fn resolve_submodule( |
24 | db: &impl DefDatabase, | 24 | db: &impl DefDatabase, |
25 | file_id: HirFileId, | 25 | file_id: HirFileId, |
26 | mod_attr_path: Option<&SmolStr>, | ||
26 | name: &Name, | 27 | name: &Name, |
27 | is_root: bool, | 28 | is_root: bool, |
28 | attr_path: Option<&SmolStr>, | 29 | attr_path: Option<&SmolStr>, |
@@ -80,7 +81,7 @@ pub(super) fn resolve_submodule( | |||
80 | ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) | 81 | ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) |
81 | } | 82 | } |
82 | (None, None) => { | 83 | (None, None) => { |
83 | let is_dir_owner = is_root || mod_name == "mod"; | 84 | let is_dir_owner = is_root || mod_name == "mod" || mod_attr_path.is_some(); |
84 | if is_dir_owner { | 85 | if is_dir_owner { |
85 | let file_mod = dir_path.join(format!("{}.rs", name)); | 86 | let file_mod = dir_path.join(format!("{}.rs", name)); |
86 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); | 87 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); |
diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mod_resolution.rs index 4f8398460..e3e6f1e95 100644 --- a/crates/ra_hir/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/tests/mod_resolution.rs | |||
@@ -706,3 +706,34 @@ fn unresolved_module_diagnostics() { | |||
706 | "### | 706 | "### |
707 | ); | 707 | ); |
708 | } | 708 | } |
709 | |||
710 | #[test] | ||
711 | fn module_resolution_decl_inside_module_in_non_crate_root_2() { | ||
712 | let map = def_map_with_crate_graph( | ||
713 | r###" | ||
714 | //- /main.rs | ||
715 | #[path="module/m2.rs"] | ||
716 | mod module; | ||
717 | |||
718 | //- /module/m2.rs | ||
719 | pub mod submod; | ||
720 | |||
721 | //- /module/submod.rs | ||
722 | pub struct Baz; | ||
723 | "###, | ||
724 | crate_graph! { | ||
725 | "main": ("/main.rs", []), | ||
726 | }, | ||
727 | ); | ||
728 | |||
729 | assert_snapshot!(map, @r###" | ||
730 | ⋮crate | ||
731 | ⋮module: t | ||
732 | ⋮ | ||
733 | ⋮crate::module | ||
734 | ⋮submod: t | ||
735 | ⋮ | ||
736 | ⋮crate::module::submod | ||
737 | ⋮Baz: t v | ||
738 | "###); | ||
739 | } | ||
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs index 2af2ad315..63ac37e9e 100644 --- a/crates/ra_parser/src/grammar/items/use_item.rs +++ b/crates/ra_parser/src/grammar/items/use_item.rs | |||
@@ -3,7 +3,7 @@ use super::*; | |||
3 | pub(super) fn use_item(p: &mut Parser, m: Marker) { | 3 | pub(super) fn use_item(p: &mut Parser, m: Marker) { |
4 | assert!(p.at(T![use])); | 4 | assert!(p.at(T![use])); |
5 | p.bump(T![use]); | 5 | p.bump(T![use]); |
6 | use_tree(p); | 6 | use_tree(p, true); |
7 | p.expect(T![;]); | 7 | p.expect(T![;]); |
8 | m.complete(p, USE_ITEM); | 8 | m.complete(p, USE_ITEM); |
9 | } | 9 | } |
@@ -12,7 +12,7 @@ pub(super) fn use_item(p: &mut Parser, m: Marker) { | |||
12 | /// Note that this is called both by `use_item` and `use_tree_list`, | 12 | /// Note that this is called both by `use_item` and `use_tree_list`, |
13 | /// so handles both `some::path::{inner::path}` and `inner::path` in | 13 | /// so handles both `some::path::{inner::path}` and `inner::path` in |
14 | /// `use some::path::{inner::path};` | 14 | /// `use some::path::{inner::path};` |
15 | fn use_tree(p: &mut Parser) { | 15 | fn use_tree(p: &mut Parser, top_level: bool) { |
16 | let m = p.start(); | 16 | let m = p.start(); |
17 | match p.current() { | 17 | match p.current() { |
18 | // Finish the use_tree for cases of e.g. | 18 | // Finish the use_tree for cases of e.g. |
@@ -101,10 +101,14 @@ fn use_tree(p: &mut Parser) { | |||
101 | } | 101 | } |
102 | _ => { | 102 | _ => { |
103 | m.abandon(p); | 103 | m.abandon(p); |
104 | p.err_recover( | 104 | let msg = "expected one of `*`, `::`, `{`, `self`, `super` or an identifier"; |
105 | "expected one of `*`, `::`, `{`, `self`, `super` or an identifier", | 105 | if top_level { |
106 | ITEM_RECOVERY_SET, | 106 | p.err_recover(msg, ITEM_RECOVERY_SET); |
107 | ); | 107 | } else { |
108 | // if we are parsing a nested tree, we have to eat a token to | ||
109 | // main balanced `{}` | ||
110 | p.err_and_bump(msg); | ||
111 | } | ||
108 | return; | 112 | return; |
109 | } | 113 | } |
110 | } | 114 | } |
@@ -116,7 +120,7 @@ pub(crate) fn use_tree_list(p: &mut Parser) { | |||
116 | let m = p.start(); | 120 | let m = p.start(); |
117 | p.bump(T!['{']); | 121 | p.bump(T!['{']); |
118 | while !p.at(EOF) && !p.at(T!['}']) { | 122 | while !p.at(EOF) && !p.at(T!['}']) { |
119 | use_tree(p); | 123 | use_tree(p, false); |
120 | if !p.at(T!['}']) { | 124 | if !p.at(T!['}']) { |
121 | p.expect(T![,]); | 125 | p.expect(T![,]); |
122 | } | 126 | } |
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs new file mode 100644 index 000000000..d521a5bb2 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | use std::{error::Error; | ||
2 | use std::io; | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt new file mode 100644 index 000000000..181f408c8 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt | |||
@@ -0,0 +1,51 @@ | |||
1 | SOURCE_FILE@[0; 37) | ||
2 | USE_ITEM@[0; 36) | ||
3 | USE_KW@[0; 3) "use" | ||
4 | WHITESPACE@[3; 4) " " | ||
5 | USE_TREE@[4; 36) | ||
6 | PATH@[4; 7) | ||
7 | PATH_SEGMENT@[4; 7) | ||
8 | NAME_REF@[4; 7) | ||
9 | IDENT@[4; 7) "std" | ||
10 | COLONCOLON@[7; 9) "::" | ||
11 | USE_TREE_LIST@[9; 36) | ||
12 | L_CURLY@[9; 10) "{" | ||
13 | USE_TREE@[10; 22) | ||
14 | PATH@[10; 22) | ||
15 | PATH@[10; 15) | ||
16 | PATH_SEGMENT@[10; 15) | ||
17 | NAME_REF@[10; 15) | ||
18 | IDENT@[10; 15) "error" | ||
19 | COLONCOLON@[15; 17) "::" | ||
20 | PATH_SEGMENT@[17; 22) | ||
21 | NAME_REF@[17; 22) | ||
22 | IDENT@[17; 22) "Error" | ||
23 | ERROR@[22; 23) | ||
24 | SEMI@[22; 23) ";" | ||
25 | WHITESPACE@[23; 24) "\n" | ||
26 | ERROR@[24; 27) | ||
27 | USE_KW@[24; 27) "use" | ||
28 | WHITESPACE@[27; 28) " " | ||
29 | USE_TREE@[28; 35) | ||
30 | PATH@[28; 35) | ||
31 | PATH@[28; 31) | ||
32 | PATH_SEGMENT@[28; 31) | ||
33 | NAME_REF@[28; 31) | ||
34 | IDENT@[28; 31) "std" | ||
35 | COLONCOLON@[31; 33) "::" | ||
36 | PATH_SEGMENT@[33; 35) | ||
37 | NAME_REF@[33; 35) | ||
38 | IDENT@[33; 35) "io" | ||
39 | ERROR@[35; 36) | ||
40 | SEMI@[35; 36) ";" | ||
41 | WHITESPACE@[36; 37) "\n" | ||
42 | error 22: expected COMMA | ||
43 | error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
44 | error 23: expected COMMA | ||
45 | error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
46 | error 27: expected COMMA | ||
47 | error 35: expected COMMA | ||
48 | error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
49 | error 36: expected COMMA | ||
50 | error 36: expected R_CURLY | ||
51 | error 36: expected SEMI | ||