aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/nameres/collector.rs8
-rw-r--r--crates/ra_hir/src/nameres/mod_resolution.rs3
-rw-r--r--crates/ra_hir/src/nameres/tests/mod_resolution.rs31
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs18
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs15
-rw-r--r--crates/ra_syntax/test_data/parser/err/0036_partial_use.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/err/0036_partial_use.txt51
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs4
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt75
9 files changed, 195 insertions, 12 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 @@
1use ra_db::FileId; 1use ra_db::FileId;
2use ra_syntax::ast; 2use ra_syntax::{ast, SmolStr};
3use rustc_hash::FxHashMap; 3use rustc_hash::FxHashMap;
4use test_utils::tested_by; 4use 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> {
23pub(super) fn resolve_submodule( 23pub(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]
711fn 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::*;
3pub(super) fn use_item(p: &mut Parser, m: Marker) { 3pub(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};`
15fn use_tree(p: &mut Parser) { 15fn 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_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index a4ffd6960..aa9a6d18e 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -167,7 +167,7 @@ fn record_field_pat_list(p: &mut Parser) {
167 // A trailing `..` is *not* treated as a DOT_DOT_PAT. 167 // A trailing `..` is *not* treated as a DOT_DOT_PAT.
168 T![.] if p.at(T![..]) => p.bump(T![..]), 168 T![.] if p.at(T![..]) => p.bump(T![..]),
169 169
170 IDENT if p.nth(1) == T![:] => record_field_pat(p), 170 IDENT | INT_NUMBER if p.nth(1) == T![:] => record_field_pat(p),
171 T!['{'] => error_block(p, "expected ident"), 171 T!['{'] => error_block(p, "expected ident"),
172 T![box] => { 172 T![box] => {
173 box_pat(p); 173 box_pat(p);
@@ -184,12 +184,21 @@ fn record_field_pat_list(p: &mut Parser) {
184 m.complete(p, RECORD_FIELD_PAT_LIST); 184 m.complete(p, RECORD_FIELD_PAT_LIST);
185} 185}
186 186
187// test record_field_pat
188// fn foo() {
189// let S { 0: 1 } = ();
190// let S { x: 1 } = ();
191// }
187fn record_field_pat(p: &mut Parser) { 192fn record_field_pat(p: &mut Parser) {
188 assert!(p.at(IDENT)); 193 assert!(p.at(IDENT) || p.at(INT_NUMBER));
189 assert!(p.nth(1) == T![:]); 194 assert!(p.nth(1) == T![:]);
190 195
191 let m = p.start(); 196 let m = p.start();
192 name(p); 197
198 if !p.eat(INT_NUMBER) {
199 name(p)
200 }
201
193 p.bump_any(); 202 p.bump_any();
194 pattern(p); 203 pattern(p);
195 m.complete(p, RECORD_FIELD_PAT); 204 m.complete(p, RECORD_FIELD_PAT);
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 @@
1use std::{error::Error;
2use 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 @@
1SOURCE_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"
42error 22: expected COMMA
43error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
44error 23: expected COMMA
45error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
46error 27: expected COMMA
47error 35: expected COMMA
48error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
49error 36: expected COMMA
50error 36: expected R_CURLY
51error 36: expected SEMI
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs
new file mode 100644
index 000000000..26b1d5f89
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 let S { 0: 1 } = ();
3 let S { x: 1 } = ();
4}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt
new file mode 100644
index 000000000..06fbdfabf
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0145_record_field_pat.txt
@@ -0,0 +1,75 @@
1SOURCE_FILE@[0; 63)
2 FN_DEF@[0; 62)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " "
11 BLOCK_EXPR@[9; 62)
12 BLOCK@[9; 62)
13 L_CURLY@[9; 10) "{"
14 WHITESPACE@[10; 15) "\n "
15 LET_STMT@[15; 35)
16 LET_KW@[15; 18) "let"
17 WHITESPACE@[18; 19) " "
18 RECORD_PAT@[19; 29)
19 PATH@[19; 20)
20 PATH_SEGMENT@[19; 20)
21 NAME_REF@[19; 20)
22 IDENT@[19; 20) "S"
23 WHITESPACE@[20; 21) " "
24 RECORD_FIELD_PAT_LIST@[21; 29)
25 L_CURLY@[21; 22) "{"
26 WHITESPACE@[22; 23) " "
27 RECORD_FIELD_PAT@[23; 27)
28 INT_NUMBER@[23; 24) "0"
29 COLON@[24; 25) ":"
30 WHITESPACE@[25; 26) " "
31 LITERAL_PAT@[26; 27)
32 LITERAL@[26; 27)
33 INT_NUMBER@[26; 27) "1"
34 WHITESPACE@[27; 28) " "
35 R_CURLY@[28; 29) "}"
36 WHITESPACE@[29; 30) " "
37 EQ@[30; 31) "="
38 WHITESPACE@[31; 32) " "
39 TUPLE_EXPR@[32; 34)
40 L_PAREN@[32; 33) "("
41 R_PAREN@[33; 34) ")"
42 SEMI@[34; 35) ";"
43 WHITESPACE@[35; 40) "\n "
44 LET_STMT@[40; 60)
45 LET_KW@[40; 43) "let"
46 WHITESPACE@[43; 44) " "
47 RECORD_PAT@[44; 54)
48 PATH@[44; 45)
49 PATH_SEGMENT@[44; 45)
50 NAME_REF@[44; 45)
51 IDENT@[44; 45) "S"
52 WHITESPACE@[45; 46) " "
53 RECORD_FIELD_PAT_LIST@[46; 54)
54 L_CURLY@[46; 47) "{"
55 WHITESPACE@[47; 48) " "
56 RECORD_FIELD_PAT@[48; 52)
57 NAME@[48; 49)
58 IDENT@[48; 49) "x"
59 COLON@[49; 50) ":"
60 WHITESPACE@[50; 51) " "
61 LITERAL_PAT@[51; 52)
62 LITERAL@[51; 52)
63 INT_NUMBER@[51; 52) "1"
64 WHITESPACE@[52; 53) " "
65 R_CURLY@[53; 54) "}"
66 WHITESPACE@[54; 55) " "
67 EQ@[55; 56) "="
68 WHITESPACE@[56; 57) " "
69 TUPLE_EXPR@[57; 59)
70 L_PAREN@[57; 58) "("
71 R_PAREN@[58; 59) ")"
72 SEMI@[59; 60) ";"
73 WHITESPACE@[60; 61) "\n"
74 R_CURLY@[61; 62) "}"
75 WHITESPACE@[62; 63) "\n"