diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/never_type.rs | 118 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 89 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 34 |
5 files changed, 137 insertions, 133 deletions
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index 9c2c6959d..0481a7b12 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs | |||
@@ -154,6 +154,19 @@ impl TestDB { | |||
154 | }); | 154 | }); |
155 | (buf, count) | 155 | (buf, count) |
156 | } | 156 | } |
157 | |||
158 | pub fn all_files(&self) -> Vec<FileId> { | ||
159 | let mut res = Vec::new(); | ||
160 | let crate_graph = self.crate_graph(); | ||
161 | for krate in crate_graph.iter() { | ||
162 | let crate_def_map = self.crate_def_map(krate); | ||
163 | for (module_id, _) in crate_def_map.modules.iter() { | ||
164 | let file_id = crate_def_map[module_id].origin.file_id(); | ||
165 | res.extend(file_id) | ||
166 | } | ||
167 | } | ||
168 | res | ||
169 | } | ||
157 | } | 170 | } |
158 | 171 | ||
159 | impl TestDB { | 172 | impl TestDB { |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index 2a85ce85d..4d0dc3011 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -28,6 +28,7 @@ use ra_syntax::{ | |||
28 | SyntaxNode, | 28 | SyntaxNode, |
29 | }; | 29 | }; |
30 | use stdx::format_to; | 30 | use stdx::format_to; |
31 | use test_utils::extract_annotations; | ||
31 | 32 | ||
32 | use crate::{ | 33 | use crate::{ |
33 | db::HirDatabase, display::HirDisplay, infer::TypeMismatch, test_db::TestDB, InferenceResult, Ty, | 34 | db::HirDatabase, display::HirDisplay, infer::TypeMismatch, test_db::TestDB, InferenceResult, Ty, |
@@ -37,6 +38,21 @@ use crate::{ | |||
37 | // against snapshots of the expected results using insta. Use cargo-insta to | 38 | // against snapshots of the expected results using insta. Use cargo-insta to |
38 | // update the snapshots. | 39 | // update the snapshots. |
39 | 40 | ||
41 | fn check_types(ra_fixture: &str) { | ||
42 | let db = TestDB::with_files(ra_fixture); | ||
43 | let mut checked_one = false; | ||
44 | for file_id in db.all_files() { | ||
45 | let text = db.parse(file_id).syntax_node().to_string(); | ||
46 | let annotations = extract_annotations(&text); | ||
47 | for (offset, expected) in annotations { | ||
48 | let actual = type_at_pos(&db, FilePosition { file_id, offset }); | ||
49 | assert_eq!(expected, actual); | ||
50 | checked_one = true; | ||
51 | } | ||
52 | } | ||
53 | assert!(checked_one, "no `//^` annotations found"); | ||
54 | } | ||
55 | |||
40 | fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { | 56 | fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { |
41 | type_at_pos_displayed(db, pos, |ty, _| ty.display(db).to_string()) | 57 | type_at_pos_displayed(db, pos, |ty, _| ty.display(db).to_string()) |
42 | } | 58 | } |
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs index ab9a990f5..64d421d40 100644 --- a/crates/ra_hir_ty/src/tests/never_type.rs +++ b/crates/ra_hir_ty/src/tests/never_type.rs | |||
@@ -1,99 +1,91 @@ | |||
1 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
2 | 2 | ||
3 | use super::{infer_with_mismatches, type_at}; | 3 | use super::{check_types, infer_with_mismatches}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_never1() { | 6 | fn infer_never1() { |
7 | let t = type_at( | 7 | check_types( |
8 | r#" | 8 | r#" |
9 | //- /main.rs | ||
10 | fn test() { | 9 | fn test() { |
11 | let t = return; | 10 | let t = return; |
12 | t<|>; | 11 | t; |
13 | } | 12 | } //^ ! |
14 | "#, | 13 | "#, |
15 | ); | 14 | ); |
16 | assert_eq!(t, "!"); | ||
17 | } | 15 | } |
18 | 16 | ||
19 | #[test] | 17 | #[test] |
20 | fn infer_never2() { | 18 | fn infer_never2() { |
21 | let t = type_at( | 19 | check_types( |
22 | r#" | 20 | r#" |
23 | //- /main.rs | ||
24 | fn gen<T>() -> T { loop {} } | 21 | fn gen<T>() -> T { loop {} } |
25 | 22 | ||
26 | fn test() { | 23 | fn test() { |
27 | let a = gen(); | 24 | let a = gen(); |
28 | if false { a } else { loop {} }; | 25 | if false { a } else { loop {} }; |
29 | a<|>; | 26 | a; |
30 | } | 27 | } //^ ! |
31 | "#, | 28 | "#, |
32 | ); | 29 | ); |
33 | assert_eq!(t, "!"); | ||
34 | } | 30 | } |
35 | 31 | ||
36 | #[test] | 32 | #[test] |
37 | fn infer_never3() { | 33 | fn infer_never3() { |
38 | let t = type_at( | 34 | check_types( |
39 | r#" | 35 | r#" |
40 | //- /main.rs | ||
41 | fn gen<T>() -> T { loop {} } | 36 | fn gen<T>() -> T { loop {} } |
42 | 37 | ||
43 | fn test() { | 38 | fn test() { |
44 | let a = gen(); | 39 | let a = gen(); |
45 | if false { loop {} } else { a }; | 40 | if false { loop {} } else { a }; |
46 | a<|>; | 41 | a; |
42 | //^ ! | ||
47 | } | 43 | } |
48 | "#, | 44 | "#, |
49 | ); | 45 | ); |
50 | assert_eq!(t, "!"); | ||
51 | } | 46 | } |
52 | 47 | ||
53 | #[test] | 48 | #[test] |
54 | fn never_type_in_generic_args() { | 49 | fn never_type_in_generic_args() { |
55 | let t = type_at( | 50 | check_types( |
56 | r#" | 51 | r#" |
57 | //- /main.rs | ||
58 | enum Option<T> { None, Some(T) } | 52 | enum Option<T> { None, Some(T) } |
59 | 53 | ||
60 | fn test() { | 54 | fn test() { |
61 | let a = if true { Option::None } else { Option::Some(return) }; | 55 | let a = if true { Option::None } else { Option::Some(return) }; |
62 | a<|>; | 56 | a; |
63 | } | 57 | } //^ Option<!> |
64 | "#, | 58 | "#, |
65 | ); | 59 | ); |
66 | assert_eq!(t, "Option<!>"); | ||
67 | } | 60 | } |
68 | 61 | ||
69 | #[test] | 62 | #[test] |
70 | fn never_type_can_be_reinferred1() { | 63 | fn never_type_can_be_reinferred1() { |
71 | let t = type_at( | 64 | check_types( |
72 | r#" | 65 | r#" |
73 | //- /main.rs | ||
74 | fn gen<T>() -> T { loop {} } | 66 | fn gen<T>() -> T { loop {} } |
75 | 67 | ||
76 | fn test() { | 68 | fn test() { |
77 | let a = gen(); | 69 | let a = gen(); |
78 | if false { loop {} } else { a }; | 70 | if false { loop {} } else { a }; |
79 | a<|>; | 71 | a; |
72 | //^ () | ||
80 | if false { a }; | 73 | if false { a }; |
81 | } | 74 | } |
82 | "#, | 75 | "#, |
83 | ); | 76 | ); |
84 | assert_eq!(t, "()"); | ||
85 | } | 77 | } |
86 | 78 | ||
87 | #[test] | 79 | #[test] |
88 | fn never_type_can_be_reinferred2() { | 80 | fn never_type_can_be_reinferred2() { |
89 | let t = type_at( | 81 | check_types( |
90 | r#" | 82 | r#" |
91 | //- /main.rs | ||
92 | enum Option<T> { None, Some(T) } | 83 | enum Option<T> { None, Some(T) } |
93 | 84 | ||
94 | fn test() { | 85 | fn test() { |
95 | let a = if true { Option::None } else { Option::Some(return) }; | 86 | let a = if true { Option::None } else { Option::Some(return) }; |
96 | a<|>; | 87 | a; |
88 | //^ Option<i32> | ||
97 | match 42 { | 89 | match 42 { |
98 | 42 => a, | 90 | 42 => a, |
99 | _ => Option::Some(42), | 91 | _ => Option::Some(42), |
@@ -101,19 +93,18 @@ fn test() { | |||
101 | } | 93 | } |
102 | "#, | 94 | "#, |
103 | ); | 95 | ); |
104 | assert_eq!(t, "Option<i32>"); | ||
105 | } | 96 | } |
106 | 97 | ||
107 | #[test] | 98 | #[test] |
108 | fn never_type_can_be_reinferred3() { | 99 | fn never_type_can_be_reinferred3() { |
109 | let t = type_at( | 100 | check_types( |
110 | r#" | 101 | r#" |
111 | //- /main.rs | ||
112 | enum Option<T> { None, Some(T) } | 102 | enum Option<T> { None, Some(T) } |
113 | 103 | ||
114 | fn test() { | 104 | fn test() { |
115 | let a = if true { Option::None } else { Option::Some(return) }; | 105 | let a = if true { Option::None } else { Option::Some(return) }; |
116 | a<|>; | 106 | a; |
107 | //^ Option<&str> | ||
117 | match 42 { | 108 | match 42 { |
118 | 42 => a, | 109 | 42 => a, |
119 | _ => Option::Some("str"), | 110 | _ => Option::Some("str"), |
@@ -121,82 +112,72 @@ fn test() { | |||
121 | } | 112 | } |
122 | "#, | 113 | "#, |
123 | ); | 114 | ); |
124 | assert_eq!(t, "Option<&str>"); | ||
125 | } | 115 | } |
126 | 116 | ||
127 | #[test] | 117 | #[test] |
128 | fn match_no_arm() { | 118 | fn match_no_arm() { |
129 | let t = type_at( | 119 | check_types( |
130 | r#" | 120 | r#" |
131 | //- /main.rs | ||
132 | enum Void {} | 121 | enum Void {} |
133 | 122 | ||
134 | fn test(a: Void) { | 123 | fn test(a: Void) { |
135 | let t = match a {}; | 124 | let t = match a {}; |
136 | t<|>; | 125 | t; |
137 | } | 126 | } //^ ! |
138 | "#, | 127 | "#, |
139 | ); | 128 | ); |
140 | assert_eq!(t, "!"); | ||
141 | } | 129 | } |
142 | 130 | ||
143 | #[test] | 131 | #[test] |
144 | fn match_unknown_arm() { | 132 | fn match_unknown_arm() { |
145 | let t = type_at( | 133 | check_types( |
146 | r#" | 134 | r#" |
147 | //- /main.rs | ||
148 | fn test(a: Option) { | 135 | fn test(a: Option) { |
149 | let t = match 0 { | 136 | let t = match 0 { |
150 | _ => unknown, | 137 | _ => unknown, |
151 | }; | 138 | }; |
152 | t<|>; | 139 | t; |
153 | } | 140 | } //^ {unknown} |
154 | "#, | 141 | "#, |
155 | ); | 142 | ); |
156 | assert_eq!(t, "{unknown}"); | ||
157 | } | 143 | } |
158 | 144 | ||
159 | #[test] | 145 | #[test] |
160 | fn if_never() { | 146 | fn if_never() { |
161 | let t = type_at( | 147 | check_types( |
162 | r#" | 148 | r#" |
163 | //- /main.rs | ||
164 | fn test() { | 149 | fn test() { |
165 | let i = if true { | 150 | let i = if true { |
166 | loop {} | 151 | loop {} |
167 | } else { | 152 | } else { |
168 | 3.0 | 153 | 3.0 |
169 | }; | 154 | }; |
170 | i<|>; | 155 | i; |
171 | } | 156 | } //^ f64 |
172 | "#, | 157 | "#, |
173 | ); | 158 | ); |
174 | assert_eq!(t, "f64"); | ||
175 | } | 159 | } |
176 | 160 | ||
177 | #[test] | 161 | #[test] |
178 | fn if_else_never() { | 162 | fn if_else_never() { |
179 | let t = type_at( | 163 | check_types( |
180 | r#" | 164 | r#" |
181 | //- /main.rs | ||
182 | fn test(input: bool) { | 165 | fn test(input: bool) { |
183 | let i = if input { | 166 | let i = if input { |
184 | 2.0 | 167 | 2.0 |
185 | } else { | 168 | } else { |
186 | return | 169 | return |
187 | }; | 170 | }; |
188 | i<|>; | 171 | i; |
189 | } | 172 | } //^ f64 |
190 | "#, | 173 | "#, |
191 | ); | 174 | ); |
192 | assert_eq!(t, "f64"); | ||
193 | } | 175 | } |
194 | 176 | ||
195 | #[test] | 177 | #[test] |
196 | fn match_first_arm_never() { | 178 | fn match_first_arm_never() { |
197 | let t = type_at( | 179 | check_types( |
198 | r#" | 180 | r#" |
199 | //- /main.rs | ||
200 | fn test(a: i32) { | 181 | fn test(a: i32) { |
201 | let i = match a { | 182 | let i = match a { |
202 | 1 => return, | 183 | 1 => return, |
@@ -204,18 +185,16 @@ fn test(a: i32) { | |||
204 | 3 => loop {}, | 185 | 3 => loop {}, |
205 | _ => 3.0, | 186 | _ => 3.0, |
206 | }; | 187 | }; |
207 | i<|>; | 188 | i; |
208 | } | 189 | } //^ f64 |
209 | "#, | 190 | "#, |
210 | ); | 191 | ); |
211 | assert_eq!(t, "f64"); | ||
212 | } | 192 | } |
213 | 193 | ||
214 | #[test] | 194 | #[test] |
215 | fn match_second_arm_never() { | 195 | fn match_second_arm_never() { |
216 | let t = type_at( | 196 | check_types( |
217 | r#" | 197 | r#" |
218 | //- /main.rs | ||
219 | fn test(a: i32) { | 198 | fn test(a: i32) { |
220 | let i = match a { | 199 | let i = match a { |
221 | 1 => 3.0, | 200 | 1 => 3.0, |
@@ -223,45 +202,40 @@ fn test(a: i32) { | |||
223 | 3 => 3.0, | 202 | 3 => 3.0, |
224 | _ => return, | 203 | _ => return, |
225 | }; | 204 | }; |
226 | i<|>; | 205 | i; |
227 | } | 206 | } //^ f64 |
228 | "#, | 207 | "#, |
229 | ); | 208 | ); |
230 | assert_eq!(t, "f64"); | ||
231 | } | 209 | } |
232 | 210 | ||
233 | #[test] | 211 | #[test] |
234 | fn match_all_arms_never() { | 212 | fn match_all_arms_never() { |
235 | let t = type_at( | 213 | check_types( |
236 | r#" | 214 | r#" |
237 | //- /main.rs | ||
238 | fn test(a: i32) { | 215 | fn test(a: i32) { |
239 | let i = match a { | 216 | let i = match a { |
240 | 2 => return, | 217 | 2 => return, |
241 | _ => loop {}, | 218 | _ => loop {}, |
242 | }; | 219 | }; |
243 | i<|>; | 220 | i; |
244 | } | 221 | } //^ ! |
245 | "#, | 222 | "#, |
246 | ); | 223 | ); |
247 | assert_eq!(t, "!"); | ||
248 | } | 224 | } |
249 | 225 | ||
250 | #[test] | 226 | #[test] |
251 | fn match_no_never_arms() { | 227 | fn match_no_never_arms() { |
252 | let t = type_at( | 228 | check_types( |
253 | r#" | 229 | r#" |
254 | //- /main.rs | ||
255 | fn test(a: i32) { | 230 | fn test(a: i32) { |
256 | let i = match a { | 231 | let i = match a { |
257 | 2 => 2.0, | 232 | 2 => 2.0, |
258 | _ => 3.0, | 233 | _ => 3.0, |
259 | }; | 234 | }; |
260 | i<|>; | 235 | i; |
261 | } | 236 | } //^ f64 |
262 | "#, | 237 | "#, |
263 | ); | 238 | ); |
264 | assert_eq!(t, "f64"); | ||
265 | } | 239 | } |
266 | 240 | ||
267 | #[test] | 241 | #[test] |
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 5e3f2bd3c..de63f4cce 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -1,19 +1,17 @@ | |||
1 | use super::{infer, type_at, type_at_pos}; | ||
2 | use crate::test_db::TestDB; | ||
3 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
4 | use ra_db::fixture::WithFixture; | 2 | |
3 | use super::{check_types, infer}; | ||
5 | 4 | ||
6 | #[test] | 5 | #[test] |
7 | fn infer_box() { | 6 | fn infer_box() { |
8 | let (db, pos) = TestDB::with_position( | 7 | check_types( |
9 | r#" | 8 | r#" |
10 | //- /main.rs crate:main deps:std | 9 | //- /main.rs crate:main deps:std |
11 | |||
12 | fn test() { | 10 | fn test() { |
13 | let x = box 1; | 11 | let x = box 1; |
14 | let t = (x, box x, box &1, box [1]); | 12 | let t = (x, box x, box &1, box [1]); |
15 | t<|>; | 13 | t; |
16 | } | 14 | } //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; _]>) |
17 | 15 | ||
18 | //- /std.rs crate:std | 16 | //- /std.rs crate:std |
19 | #[prelude_import] use prelude::*; | 17 | #[prelude_import] use prelude::*; |
@@ -25,29 +23,24 @@ mod boxed { | |||
25 | inner: *mut T, | 23 | inner: *mut T, |
26 | } | 24 | } |
27 | } | 25 | } |
28 | |||
29 | "#, | 26 | "#, |
30 | ); | 27 | ); |
31 | assert_eq!("(Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; _]>)", type_at_pos(&db, pos)); | ||
32 | } | 28 | } |
33 | 29 | ||
34 | #[test] | 30 | #[test] |
35 | fn infer_adt_self() { | 31 | fn infer_adt_self() { |
36 | let (db, pos) = TestDB::with_position( | 32 | check_types( |
37 | r#" | 33 | r#" |
38 | //- /main.rs | ||
39 | enum Nat { Succ(Self), Demo(Nat), Zero } | 34 | enum Nat { Succ(Self), Demo(Nat), Zero } |
40 | 35 | ||
41 | fn test() { | 36 | fn test() { |
42 | let foo: Nat = Nat::Zero; | 37 | let foo: Nat = Nat::Zero; |
43 | if let Nat::Succ(x) = foo { | 38 | if let Nat::Succ(x) = foo { |
44 | x<|> | 39 | x |
45 | } | 40 | } //^ Nat |
46 | } | 41 | } |
47 | |||
48 | "#, | 42 | "#, |
49 | ); | 43 | ); |
50 | assert_eq!("Nat", type_at_pos(&db, pos)); | ||
51 | } | 44 | } |
52 | 45 | ||
53 | #[test] | 46 | #[test] |
@@ -93,7 +86,7 @@ fn foo() { | |||
93 | 86 | ||
94 | #[test] | 87 | #[test] |
95 | fn infer_ranges() { | 88 | fn infer_ranges() { |
96 | let (db, pos) = TestDB::with_position( | 89 | check_types( |
97 | r#" | 90 | r#" |
98 | //- /main.rs crate:main deps:core | 91 | //- /main.rs crate:main deps:core |
99 | fn test() { | 92 | fn test() { |
@@ -105,8 +98,8 @@ fn test() { | |||
105 | let f = 'a'..='z'; | 98 | let f = 'a'..='z'; |
106 | 99 | ||
107 | let t = (a, b, c, d, e, f); | 100 | let t = (a, b, c, d, e, f); |
108 | t<|>; | 101 | t; |
109 | } | 102 | } //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>) |
110 | 103 | ||
111 | //- /core.rs crate:core | 104 | //- /core.rs crate:core |
112 | #[prelude_import] use prelude::*; | 105 | #[prelude_import] use prelude::*; |
@@ -135,29 +128,22 @@ pub mod ops { | |||
135 | } | 128 | } |
136 | "#, | 129 | "#, |
137 | ); | 130 | ); |
138 | assert_eq!( | ||
139 | "(RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)", | ||
140 | type_at_pos(&db, pos), | ||
141 | ); | ||
142 | } | 131 | } |
143 | 132 | ||
144 | #[test] | 133 | #[test] |
145 | fn infer_while_let() { | 134 | fn infer_while_let() { |
146 | let (db, pos) = TestDB::with_position( | 135 | check_types( |
147 | r#" | 136 | r#" |
148 | //- /main.rs | ||
149 | enum Option<T> { Some(T), None } | 137 | enum Option<T> { Some(T), None } |
150 | 138 | ||
151 | fn test() { | 139 | fn test() { |
152 | let foo: Option<f32> = None; | 140 | let foo: Option<f32> = None; |
153 | while let Option::Some(x) = foo { | 141 | while let Option::Some(x) = foo { |
154 | <|>x | 142 | x |
155 | } | 143 | } //^ f32 |
156 | } | 144 | } |
157 | |||
158 | "#, | 145 | "#, |
159 | ); | 146 | ); |
160 | assert_eq!("f32", type_at_pos(&db, pos)); | ||
161 | } | 147 | } |
162 | 148 | ||
163 | #[test] | 149 | #[test] |
@@ -1687,9 +1673,8 @@ fn test() { | |||
1687 | 1673 | ||
1688 | #[test] | 1674 | #[test] |
1689 | fn shadowing_primitive() { | 1675 | fn shadowing_primitive() { |
1690 | let t = type_at( | 1676 | check_types( |
1691 | r#" | 1677 | r#" |
1692 | //- /main.rs | ||
1693 | struct i32; | 1678 | struct i32; |
1694 | struct Foo; | 1679 | struct Foo; |
1695 | 1680 | ||
@@ -1697,15 +1682,15 @@ impl i32 { fn foo(&self) -> Foo { Foo } } | |||
1697 | 1682 | ||
1698 | fn main() { | 1683 | fn main() { |
1699 | let x: i32 = i32; | 1684 | let x: i32 = i32; |
1700 | x.foo()<|>; | 1685 | x.foo(); |
1686 | //^ Foo | ||
1701 | }"#, | 1687 | }"#, |
1702 | ); | 1688 | ); |
1703 | assert_eq!(t, "Foo"); | ||
1704 | } | 1689 | } |
1705 | 1690 | ||
1706 | #[test] | 1691 | #[test] |
1707 | fn not_shadowing_primitive_by_module() { | 1692 | fn not_shadowing_primitive_by_module() { |
1708 | let t = type_at( | 1693 | check_types( |
1709 | r#" | 1694 | r#" |
1710 | //- /str.rs | 1695 | //- /str.rs |
1711 | fn foo() {} | 1696 | fn foo() {} |
@@ -1715,15 +1700,15 @@ mod str; | |||
1715 | fn foo() -> &'static str { "" } | 1700 | fn foo() -> &'static str { "" } |
1716 | 1701 | ||
1717 | fn main() { | 1702 | fn main() { |
1718 | foo()<|>; | 1703 | foo(); |
1704 | //^ &str | ||
1719 | }"#, | 1705 | }"#, |
1720 | ); | 1706 | ); |
1721 | assert_eq!(t, "&str"); | ||
1722 | } | 1707 | } |
1723 | 1708 | ||
1724 | #[test] | 1709 | #[test] |
1725 | fn not_shadowing_module_by_primitive() { | 1710 | fn not_shadowing_module_by_primitive() { |
1726 | let t = type_at( | 1711 | check_types( |
1727 | r#" | 1712 | r#" |
1728 | //- /str.rs | 1713 | //- /str.rs |
1729 | fn foo() -> u32 {0} | 1714 | fn foo() -> u32 {0} |
@@ -1733,10 +1718,10 @@ mod str; | |||
1733 | fn foo() -> &'static str { "" } | 1718 | fn foo() -> &'static str { "" } |
1734 | 1719 | ||
1735 | fn main() { | 1720 | fn main() { |
1736 | str::foo()<|>; | 1721 | str::foo(); |
1722 | //^ u32 | ||
1737 | }"#, | 1723 | }"#, |
1738 | ); | 1724 | ); |
1739 | assert_eq!(t, "u32"); | ||
1740 | } | 1725 | } |
1741 | 1726 | ||
1742 | // This test is actually testing the shadowing behavior within ra_hir_def. It | 1727 | // This test is actually testing the shadowing behavior within ra_hir_def. It |
@@ -1744,27 +1729,7 @@ fn main() { | |||
1744 | // capable of asserting the necessary conditions. | 1729 | // capable of asserting the necessary conditions. |
1745 | #[test] | 1730 | #[test] |
1746 | fn should_be_shadowing_imports() { | 1731 | fn should_be_shadowing_imports() { |
1747 | let t = type_at( | 1732 | check_types( |
1748 | r#" | ||
1749 | mod a { | ||
1750 | pub fn foo() -> i8 {0} | ||
1751 | pub struct foo { a: i8 } | ||
1752 | } | ||
1753 | mod b { pub fn foo () -> u8 {0} } | ||
1754 | mod c { pub struct foo { a: u8 } } | ||
1755 | mod d { | ||
1756 | pub use super::a::*; | ||
1757 | pub use super::c::foo; | ||
1758 | pub use super::b::foo; | ||
1759 | } | ||
1760 | |||
1761 | fn main() { | ||
1762 | d::foo()<|>; | ||
1763 | }"#, | ||
1764 | ); | ||
1765 | assert_eq!(t, "u8"); | ||
1766 | |||
1767 | let t = type_at( | ||
1768 | r#" | 1733 | r#" |
1769 | mod a { | 1734 | mod a { |
1770 | pub fn foo() -> i8 {0} | 1735 | pub fn foo() -> i8 {0} |
@@ -1779,10 +1744,12 @@ mod d { | |||
1779 | } | 1744 | } |
1780 | 1745 | ||
1781 | fn main() { | 1746 | fn main() { |
1782 | d::foo{a:0<|>}; | 1747 | d::foo(); |
1748 | //^ u8 | ||
1749 | d::foo{a:0}; | ||
1750 | //^ u8 | ||
1783 | }"#, | 1751 | }"#, |
1784 | ); | 1752 | ); |
1785 | assert_eq!(t, "u8"); | ||
1786 | } | 1753 | } |
1787 | 1754 | ||
1788 | #[test] | 1755 | #[test] |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index eaeeeb97b..e74f3b263 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -16,6 +16,7 @@ use std::{ | |||
16 | }; | 16 | }; |
17 | 17 | ||
18 | use serde_json::Value; | 18 | use serde_json::Value; |
19 | use stdx::lines_with_ends; | ||
19 | use text_size::{TextRange, TextSize}; | 20 | use text_size::{TextRange, TextSize}; |
20 | 21 | ||
21 | pub use difference::Changeset as __Changeset; | 22 | pub use difference::Changeset as __Changeset; |
@@ -159,6 +160,39 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String { | |||
159 | res | 160 | res |
160 | } | 161 | } |
161 | 162 | ||
163 | /// Extracts `//^ some text` annotations | ||
164 | pub fn extract_annotations(text: &str) -> Vec<(TextSize, String)> { | ||
165 | let mut res = Vec::new(); | ||
166 | let mut prev_line_start: Option<TextSize> = None; | ||
167 | let mut line_start: TextSize = 0.into(); | ||
168 | for line in lines_with_ends(text) { | ||
169 | if let Some(idx) = line.find("//^") { | ||
170 | let offset = prev_line_start.unwrap() + TextSize::of(&line[..idx + "//".len()]); | ||
171 | let data = line[idx + "//^".len()..].trim().to_string(); | ||
172 | res.push((offset, data)) | ||
173 | } | ||
174 | prev_line_start = Some(line_start); | ||
175 | line_start += TextSize::of(line); | ||
176 | } | ||
177 | res | ||
178 | } | ||
179 | |||
180 | #[test] | ||
181 | fn test_extract_annotations() { | ||
182 | let res = extract_annotations(&trim_indent( | ||
183 | r#" | ||
184 | fn main() { | ||
185 | let x = 92; | ||
186 | //^ def | ||
187 | |||
188 | x + 1 | ||
189 | } //^ i32 | ||
190 | "#, | ||
191 | )); | ||
192 | |||
193 | assert_eq!(res, vec![(20.into(), "def".into()), (47.into(), "i32".into())]); | ||
194 | } | ||
195 | |||
162 | // Comparison functionality borrowed from cargo: | 196 | // Comparison functionality borrowed from cargo: |
163 | 197 | ||
164 | /// Compare a line with an expected pattern. | 198 | /// Compare a line with an expected pattern. |