aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parser/grammar/patterns.rs12
-rw-r--r--tests/data/parser/inline/0034_bind_pat.rs8
-rw-r--r--tests/data/parser/inline/0034_bind_pat.txt109
-rw-r--r--tools/src/lib.rs14
-rw-r--r--tools/src/main.rs44
5 files changed, 119 insertions, 68 deletions
diff --git a/src/parser/grammar/patterns.rs b/src/parser/grammar/patterns.rs
index 6e4f2236b..a5d13a124 100644
--- a/src/parser/grammar/patterns.rs
+++ b/src/parser/grammar/patterns.rs
@@ -4,7 +4,7 @@ pub(super) fn pattern(p: &mut Parser) {
4 match p.current() { 4 match p.current() {
5 UNDERSCORE => placeholder_pat(p), 5 UNDERSCORE => placeholder_pat(p),
6 AMPERSAND => ref_pat(p), 6 AMPERSAND => ref_pat(p),
7 IDENT | REF_KW => bind_pat(p), 7 IDENT | REF_KW | MUT_KW => bind_pat(p),
8 _ => p.err_and_bump("expected pattern"), 8 _ => p.err_and_bump("expected pattern"),
9 } 9 }
10} 10}
@@ -35,14 +35,18 @@ fn ref_pat(p: &mut Parser) {
35// test bind_pat 35// test bind_pat
36// fn main() { 36// fn main() {
37// let a = (); 37// let a = ();
38// let ref b = (); 38// let mut b = ();
39// let ref mut c = (); 39// let ref c = ();
40// let d @ _ = (); 40// let ref mut d = ();
41// let e @ _ = ();
42// let ref mut f @ g @ _ = ();
41// } 43// }
42fn bind_pat(p: &mut Parser) { 44fn bind_pat(p: &mut Parser) {
43 let m = p.start(); 45 let m = p.start();
44 if p.eat(REF_KW) { 46 if p.eat(REF_KW) {
45 p.eat(MUT_KW); 47 p.eat(MUT_KW);
48 } else {
49 p.eat(MUT_KW);
46 } 50 }
47 name(p); 51 name(p);
48 if p.eat(AT) { 52 if p.eat(AT) {
diff --git a/tests/data/parser/inline/0034_bind_pat.rs b/tests/data/parser/inline/0034_bind_pat.rs
index 604db2407..820a9e72c 100644
--- a/tests/data/parser/inline/0034_bind_pat.rs
+++ b/tests/data/parser/inline/0034_bind_pat.rs
@@ -1,6 +1,8 @@
1fn main() { 1fn main() {
2 let a = (); 2 let a = ();
3 let ref b = (); 3 let mut b = ();
4 let ref mut c = (); 4 let ref c = ();
5 let d @ _ = (); 5 let ref mut d = ();
6 let e @ _ = ();
7 let ref mut f @ g @ _ = ();
6} 8}
diff --git a/tests/data/parser/inline/0034_bind_pat.txt b/tests/data/parser/inline/0034_bind_pat.txt
index c799a560c..f4eb8bc4d 100644
--- a/tests/data/parser/inline/0034_bind_pat.txt
+++ b/tests/data/parser/inline/0034_bind_pat.txt
@@ -1,5 +1,5 @@
1FILE@[0; 94) 1FILE@[0; 146)
2 FN_ITEM@[0; 94) 2 FN_ITEM@[0; 146)
3 FN_KW@[0; 2) 3 FN_KW@[0; 2)
4 NAME@[2; 7) 4 NAME@[2; 7)
5 WHITESPACE@[2; 3) 5 WHITESPACE@[2; 3)
@@ -8,7 +8,7 @@ FILE@[0; 94)
8 L_PAREN@[7; 8) 8 L_PAREN@[7; 8)
9 R_PAREN@[8; 9) 9 R_PAREN@[8; 9)
10 WHITESPACE@[9; 10) 10 WHITESPACE@[9; 10)
11 BLOCK@[10; 94) 11 BLOCK@[10; 146)
12 L_CURLY@[10; 11) 12 L_CURLY@[10; 11)
13 LET_STMT@[11; 32) 13 LET_STMT@[11; 32)
14 WHITESPACE@[11; 16) 14 WHITESPACE@[11; 16)
@@ -29,7 +29,7 @@ FILE@[0; 94)
29 LET_KW@[32; 35) 29 LET_KW@[32; 35)
30 BIND_PAT@[35; 42) 30 BIND_PAT@[35; 42)
31 WHITESPACE@[35; 36) 31 WHITESPACE@[35; 36)
32 REF_KW@[36; 39) 32 MUT_KW@[36; 39)
33 NAME@[39; 42) 33 NAME@[39; 42)
34 WHITESPACE@[39; 40) 34 WHITESPACE@[39; 40)
35 IDENT@[40; 41) "b" 35 IDENT@[40; 41) "b"
@@ -41,35 +41,32 @@ FILE@[0; 94)
41 R_PAREN@[45; 46) 41 R_PAREN@[45; 46)
42 SEMI@[46; 47) 42 SEMI@[46; 47)
43 WHITESPACE@[47; 52) 43 WHITESPACE@[47; 52)
44 LET_STMT@[52; 76) 44 LET_STMT@[52; 72)
45 LET_KW@[52; 55) 45 LET_KW@[52; 55)
46 BIND_PAT@[55; 66) 46 BIND_PAT@[55; 62)
47 WHITESPACE@[55; 56) 47 WHITESPACE@[55; 56)
48 REF_KW@[56; 59) 48 REF_KW@[56; 59)
49 WHITESPACE@[59; 60) 49 NAME@[59; 62)
50 MUT_KW@[60; 63) 50 WHITESPACE@[59; 60)
51 NAME@[63; 66) 51 IDENT@[60; 61) "c"
52 WHITESPACE@[63; 64) 52 WHITESPACE@[61; 62)
53 IDENT@[64; 65) "c" 53 EQ@[62; 63)
54 WHITESPACE@[65; 66) 54 TUPLE_EXPR@[63; 66)
55 EQ@[66; 67) 55 WHITESPACE@[63; 64)
56 TUPLE_EXPR@[67; 70) 56 L_PAREN@[64; 65)
57 WHITESPACE@[67; 68) 57 R_PAREN@[65; 66)
58 L_PAREN@[68; 69) 58 SEMI@[66; 67)
59 R_PAREN@[69; 70) 59 WHITESPACE@[67; 72)
60 SEMI@[70; 71) 60 LET_STMT@[72; 96)
61 WHITESPACE@[71; 76) 61 LET_KW@[72; 75)
62 LET_STMT@[76; 92) 62 BIND_PAT@[75; 86)
63 LET_KW@[76; 79) 63 WHITESPACE@[75; 76)
64 BIND_PAT@[79; 86) 64 REF_KW@[76; 79)
65 NAME@[79; 82) 65 WHITESPACE@[79; 80)
66 WHITESPACE@[79; 80) 66 MUT_KW@[80; 83)
67 IDENT@[80; 81) "d" 67 NAME@[83; 86)
68 WHITESPACE@[81; 82)
69 AT@[82; 83)
70 PLACEHOLDER_PAT@[83; 86)
71 WHITESPACE@[83; 84) 68 WHITESPACE@[83; 84)
72 UNDERSCORE@[84; 85) 69 IDENT@[84; 85) "d"
73 WHITESPACE@[85; 86) 70 WHITESPACE@[85; 86)
74 EQ@[86; 87) 71 EQ@[86; 87)
75 TUPLE_EXPR@[87; 90) 72 TUPLE_EXPR@[87; 90)
@@ -77,6 +74,54 @@ FILE@[0; 94)
77 L_PAREN@[88; 89) 74 L_PAREN@[88; 89)
78 R_PAREN@[89; 90) 75 R_PAREN@[89; 90)
79 SEMI@[90; 91) 76 SEMI@[90; 91)
80 WHITESPACE@[91; 92) 77 WHITESPACE@[91; 96)
81 R_CURLY@[92; 93) 78 LET_STMT@[96; 116)
82 WHITESPACE@[93; 94) 79 LET_KW@[96; 99)
80 BIND_PAT@[99; 106)
81 NAME@[99; 102)
82 WHITESPACE@[99; 100)
83 IDENT@[100; 101) "e"
84 WHITESPACE@[101; 102)
85 AT@[102; 103)
86 PLACEHOLDER_PAT@[103; 106)
87 WHITESPACE@[103; 104)
88 UNDERSCORE@[104; 105)
89 WHITESPACE@[105; 106)
90 EQ@[106; 107)
91 TUPLE_EXPR@[107; 110)
92 WHITESPACE@[107; 108)
93 L_PAREN@[108; 109)
94 R_PAREN@[109; 110)
95 SEMI@[110; 111)
96 WHITESPACE@[111; 116)
97 LET_STMT@[116; 144)
98 LET_KW@[116; 119)
99 BIND_PAT@[119; 138)
100 WHITESPACE@[119; 120)
101 REF_KW@[120; 123)
102 WHITESPACE@[123; 124)
103 MUT_KW@[124; 127)
104 NAME@[127; 130)
105 WHITESPACE@[127; 128)
106 IDENT@[128; 129) "f"
107 WHITESPACE@[129; 130)
108 AT@[130; 131)
109 BIND_PAT@[131; 138)
110 NAME@[131; 134)
111 WHITESPACE@[131; 132)
112 IDENT@[132; 133) "g"
113 WHITESPACE@[133; 134)
114 AT@[134; 135)
115 PLACEHOLDER_PAT@[135; 138)
116 WHITESPACE@[135; 136)
117 UNDERSCORE@[136; 137)
118 WHITESPACE@[137; 138)
119 EQ@[138; 139)
120 TUPLE_EXPR@[139; 142)
121 WHITESPACE@[139; 140)
122 L_PAREN@[140; 141)
123 R_PAREN@[141; 142)
124 SEMI@[142; 143)
125 WHITESPACE@[143; 144)
126 R_CURLY@[144; 145)
127 WHITESPACE@[145; 146)
diff --git a/tools/src/lib.rs b/tools/src/lib.rs
index 7a0de3e3c..21a9468bc 100644
--- a/tools/src/lib.rs
+++ b/tools/src/lib.rs
@@ -3,24 +3,12 @@ extern crate itertools;
3use std::hash; 3use std::hash;
4use itertools::Itertools; 4use itertools::Itertools;
5 5
6#[derive(Debug, Eq)] 6#[derive(Debug)]
7pub struct Test { 7pub struct Test {
8 pub name: String, 8 pub name: String,
9 pub text: String, 9 pub text: String,
10} 10}
11 11
12impl PartialEq for Test {
13 fn eq(&self, other: &Test) -> bool {
14 self.name.eq(&other.name)
15 }
16}
17
18impl hash::Hash for Test {
19 fn hash<H: hash::Hasher>(&self, state: &mut H) {
20 self.name.hash(state)
21 }
22}
23
24pub fn collect_tests(s: &str) -> Vec<(usize, Test)> { 12pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
25 let mut res = vec![]; 13 let mut res = vec![];
26 let prefix = "// "; 14 let prefix = "// ";
diff --git a/tools/src/main.rs b/tools/src/main.rs
index 84a0cf1b6..3acb6e7ed 100644
--- a/tools/src/main.rs
+++ b/tools/src/main.rs
@@ -8,7 +8,7 @@ extern crate tools;
8#[macro_use] 8#[macro_use]
9extern crate commandspec; 9extern crate commandspec;
10 10
11use std::{collections::{HashSet, HashMap}, fs, path::Path}; 11use std::{collections::{HashMap}, fs, path::{Path, PathBuf}};
12use clap::{App, Arg, SubCommand}; 12use clap::{App, Arg, SubCommand};
13use tools::{collect_tests, Test}; 13use tools::{collect_tests, Test};
14 14
@@ -104,21 +104,27 @@ fn gen_tests(verify: bool) -> Result<()> {
104 } 104 }
105 let existing = existing_tests(inline_tests_dir)?; 105 let existing = existing_tests(inline_tests_dir)?;
106 106
107 for t in existing.difference(&tests) { 107 for t in existing.keys().filter(|&t| !tests.contains_key(t)) {
108 panic!("Test is deleted: {}\n{}", t.name, t.text); 108 panic!("Test is deleted: {}", t);
109 } 109 }
110 110
111 let new_tests = tests.difference(&existing); 111 let mut new_idx = existing.len() + 2;
112 for (i, t) in new_tests.enumerate() { 112 for (name, test) in tests {
113 let name = format!("{:04}_{}.rs", existing.len() + i + 1, t.name); 113 let path = match existing.get(&name) {
114 let path = inline_tests_dir.join(name); 114 Some((path, _test)) => path.clone(),
115 update(&path, &t.text, verify)?; 115 None => {
116 let file_name = format!("{:04}_{}.rs", new_idx, name);
117 new_idx += 1;
118 inline_tests_dir.join(file_name)
119 }
120 };
121 update(&path, &test.text, verify)?;
116 } 122 }
117 Ok(()) 123 Ok(())
118} 124}
119 125
120fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> { 126fn tests_from_dir(dir: &Path) -> Result<HashMap<String, Test>> {
121 let mut res = HashSet::new(); 127 let mut res = HashMap::new();
122 for entry in ::walkdir::WalkDir::new(dir) { 128 for entry in ::walkdir::WalkDir::new(dir) {
123 let entry = entry.unwrap(); 129 let entry = entry.unwrap();
124 if !entry.file_type().is_file() { 130 if !entry.file_type().is_file() {
@@ -130,7 +136,7 @@ fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> {
130 let text = fs::read_to_string(entry.path())?; 136 let text = fs::read_to_string(entry.path())?;
131 137
132 for (_, test) in collect_tests(&text) { 138 for (_, test) in collect_tests(&text) {
133 if let Some(old_test) = res.replace(test) { 139 if let Some(old_test) = res.insert(test.name.clone(), test) {
134 bail!("Duplicate test: {}", old_test.name) 140 bail!("Duplicate test: {}", old_test.name)
135 } 141 }
136 } 142 }
@@ -138,18 +144,24 @@ fn tests_from_dir(dir: &Path) -> Result<HashSet<Test>> {
138 Ok(res) 144 Ok(res)
139} 145}
140 146
141fn existing_tests(dir: &Path) -> Result<HashSet<Test>> { 147fn existing_tests(dir: &Path) -> Result<HashMap<String, (PathBuf, Test)>> {
142 let mut res = HashSet::new(); 148 let mut res = HashMap::new();
143 for file in fs::read_dir(dir)? { 149 for file in fs::read_dir(dir)? {
144 let file = file?; 150 let file = file?;
145 let path = file.path(); 151 let path = file.path();
146 if path.extension().unwrap_or_default() != "rs" { 152 if path.extension().unwrap_or_default() != "rs" {
147 continue; 153 continue;
148 } 154 }
149 let name = path.file_name().unwrap().to_str().unwrap(); 155 let name = {
150 let name = name["0000_".len()..name.len() - 3].to_string(); 156 let file_name = path.file_name().unwrap().to_str().unwrap();
157 file_name[5..file_name.len() - 3].to_string()
158 };
151 let text = fs::read_to_string(&path)?; 159 let text = fs::read_to_string(&path)?;
152 res.insert(Test { name, text }); 160 let test = Test { name: name.clone(), text };
161 match res.insert(name, (path, test)) {
162 Some(old) => println!("Duplicate test: {:?}", old),
163 None => (),
164 }
153 } 165 }
154 Ok(res) 166 Ok(res)
155} 167}