diff options
author | uHOOCCOOHu <hooccooh1896@gmail.com> | 2019-09-18 17:36:12 +0100 |
---|---|---|
committer | uHOOCCOOHu <hooccooh1896@gmail.com> | 2019-09-25 23:16:52 +0100 |
commit | 5807e261c27e4964fc6a8d2b8cf02e548292b940 (patch) | |
tree | b6bfef565281c2fec4b584a4e2759ff1c5b417e5 /crates/ra_hir/src/ty/tests | |
parent | bf161fa3e58d57d9b15bd965405036d834f18595 (diff) |
Support custom `CoerceUnsized`
Split out tests about coercion
Diffstat (limited to 'crates/ra_hir/src/ty/tests')
-rw-r--r-- | crates/ra_hir/src/ty/tests/coercion.rs | 278 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/never_type.rs | 36 |
2 files changed, 290 insertions, 24 deletions
diff --git a/crates/ra_hir/src/ty/tests/coercion.rs b/crates/ra_hir/src/ty/tests/coercion.rs new file mode 100644 index 000000000..d80d3fb6f --- /dev/null +++ b/crates/ra_hir/src/ty/tests/coercion.rs | |||
@@ -0,0 +1,278 @@ | |||
1 | use insta::assert_snapshot; | ||
2 | use test_utils::covers; | ||
3 | |||
4 | // Infer with some common definitions and impls. | ||
5 | fn infer(source: &str) -> String { | ||
6 | let defs = r#" | ||
7 | #[lang = "sized"] | ||
8 | pub trait Sized {} | ||
9 | #[lang = "unsize"] | ||
10 | pub trait Unsize<T: ?Sized> {} | ||
11 | #[lang = "coerce_unsized"] | ||
12 | pub trait CoerceUnsized<T> {} | ||
13 | |||
14 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} | ||
15 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} | ||
16 | "#; | ||
17 | |||
18 | // Append to the end to keep positions unchanged. | ||
19 | super::infer(&format!("{}{}", source, defs)) | ||
20 | } | ||
21 | |||
22 | #[test] | ||
23 | fn infer_let_stmt_coerce() { | ||
24 | assert_snapshot!( | ||
25 | infer(r#" | ||
26 | fn test() { | ||
27 | let x: &[i32] = &[1]; | ||
28 | } | ||
29 | "#), | ||
30 | @r###" | ||
31 | [11; 40) '{ ...[1]; }': () | ||
32 | [21; 22) 'x': &[i32] | ||
33 | [33; 37) '&[1]': &[i32;_] | ||
34 | [34; 37) '[1]': [i32;_] | ||
35 | [35; 36) '1': i32 | ||
36 | "###); | ||
37 | } | ||
38 | |||
39 | #[test] | ||
40 | fn infer_custom_coerce_unsized() { | ||
41 | assert_snapshot!( | ||
42 | infer(r#" | ||
43 | struct A<T: ?Sized>(*const T); | ||
44 | struct B<T: ?Sized>(*const T); | ||
45 | struct C<T: ?Sized> { inner: *const T } | ||
46 | |||
47 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} | ||
48 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} | ||
49 | |||
50 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } | ||
51 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } | ||
52 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } | ||
53 | |||
54 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { | ||
55 | let d = foo1(a); | ||
56 | let e = foo2(b); | ||
57 | let f = foo3(c); | ||
58 | } | ||
59 | "#), | ||
60 | @r###" | ||
61 | [258; 259) 'x': A<[T]> | ||
62 | [279; 284) '{ x }': A<[T]> | ||
63 | [281; 282) 'x': A<[T]> | ||
64 | [296; 297) 'x': B<[T]> | ||
65 | [317; 322) '{ x }': B<[T]> | ||
66 | [319; 320) 'x': B<[T]> | ||
67 | [334; 335) 'x': C<[T]> | ||
68 | [355; 360) '{ x }': C<[T]> | ||
69 | [357; 358) 'x': C<[T]> | ||
70 | [370; 371) 'a': A<[u8;_]> | ||
71 | [385; 386) 'b': B<[u8;_]> | ||
72 | [400; 401) 'c': C<[u8;_]> | ||
73 | [415; 481) '{ ...(c); }': () | ||
74 | [425; 426) 'd': A<[{unknown}]> | ||
75 | [429; 433) 'foo1': fn foo1<{unknown}>(A<[T]>) -> A<[T]> | ||
76 | [429; 436) 'foo1(a)': A<[{unknown}]> | ||
77 | [434; 435) 'a': A<[u8;_]> | ||
78 | [446; 447) 'e': B<[u8]> | ||
79 | [450; 454) 'foo2': fn foo2<u8>(B<[T]>) -> B<[T]> | ||
80 | [450; 457) 'foo2(b)': B<[u8]> | ||
81 | [455; 456) 'b': B<[u8;_]> | ||
82 | [467; 468) 'f': C<[u8]> | ||
83 | [471; 475) 'foo3': fn foo3<u8>(C<[T]>) -> C<[T]> | ||
84 | [471; 478) 'foo3(c)': C<[u8]> | ||
85 | [476; 477) 'c': C<[u8;_]> | ||
86 | "### | ||
87 | ); | ||
88 | } | ||
89 | |||
90 | #[test] | ||
91 | fn infer_if_coerce() { | ||
92 | assert_snapshot!( | ||
93 | infer(r#" | ||
94 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
95 | fn test() { | ||
96 | let x = if true { | ||
97 | foo(&[1]) | ||
98 | } else { | ||
99 | &[1] | ||
100 | }; | ||
101 | } | ||
102 | "#), | ||
103 | @r###" | ||
104 | [11; 12) 'x': &[T] | ||
105 | [28; 39) '{ loop {} }': ! | ||
106 | [30; 37) 'loop {}': ! | ||
107 | [35; 37) '{}': () | ||
108 | [50; 126) '{ ... }; }': () | ||
109 | [60; 61) 'x': &[i32] | ||
110 | [64; 123) 'if tru... }': &[i32] | ||
111 | [67; 71) 'true': bool | ||
112 | [72; 97) '{ ... }': &[i32] | ||
113 | [82; 85) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
114 | [82; 91) 'foo(&[1])': &[i32] | ||
115 | [86; 90) '&[1]': &[i32;_] | ||
116 | [87; 90) '[1]': [i32;_] | ||
117 | [88; 89) '1': i32 | ||
118 | [103; 123) '{ ... }': &[i32;_] | ||
119 | [113; 117) '&[1]': &[i32;_] | ||
120 | [114; 117) '[1]': [i32;_] | ||
121 | [115; 116) '1': i32 | ||
122 | "### | ||
123 | ); | ||
124 | } | ||
125 | |||
126 | #[test] | ||
127 | fn infer_if_else_coerce() { | ||
128 | assert_snapshot!( | ||
129 | infer(r#" | ||
130 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
131 | fn test() { | ||
132 | let x = if true { | ||
133 | &[1] | ||
134 | } else { | ||
135 | foo(&[1]) | ||
136 | }; | ||
137 | } | ||
138 | "#), | ||
139 | @r###" | ||
140 | [11; 12) 'x': &[T] | ||
141 | [28; 39) '{ loop {} }': ! | ||
142 | [30; 37) 'loop {}': ! | ||
143 | [35; 37) '{}': () | ||
144 | [50; 126) '{ ... }; }': () | ||
145 | [60; 61) 'x': &[i32] | ||
146 | [64; 123) 'if tru... }': &[i32] | ||
147 | [67; 71) 'true': bool | ||
148 | [72; 92) '{ ... }': &[i32;_] | ||
149 | [82; 86) '&[1]': &[i32;_] | ||
150 | [83; 86) '[1]': [i32;_] | ||
151 | [84; 85) '1': i32 | ||
152 | [98; 123) '{ ... }': &[i32] | ||
153 | [108; 111) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
154 | [108; 117) 'foo(&[1])': &[i32] | ||
155 | [112; 116) '&[1]': &[i32;_] | ||
156 | [113; 116) '[1]': [i32;_] | ||
157 | [114; 115) '1': i32 | ||
158 | "### | ||
159 | ); | ||
160 | } | ||
161 | |||
162 | #[test] | ||
163 | fn infer_match_first_coerce() { | ||
164 | assert_snapshot!( | ||
165 | infer(r#" | ||
166 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
167 | fn test(i: i32) { | ||
168 | let x = match i { | ||
169 | 2 => foo(&[2]), | ||
170 | 1 => &[1], | ||
171 | _ => &[3], | ||
172 | }; | ||
173 | } | ||
174 | "#), | ||
175 | @r###" | ||
176 | [11; 12) 'x': &[T] | ||
177 | [28; 39) '{ loop {} }': ! | ||
178 | [30; 37) 'loop {}': ! | ||
179 | [35; 37) '{}': () | ||
180 | [48; 49) 'i': i32 | ||
181 | [56; 150) '{ ... }; }': () | ||
182 | [66; 67) 'x': &[i32] | ||
183 | [70; 147) 'match ... }': &[i32] | ||
184 | [76; 77) 'i': i32 | ||
185 | [88; 89) '2': i32 | ||
186 | [93; 96) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
187 | [93; 102) 'foo(&[2])': &[i32] | ||
188 | [97; 101) '&[2]': &[i32;_] | ||
189 | [98; 101) '[2]': [i32;_] | ||
190 | [99; 100) '2': i32 | ||
191 | [112; 113) '1': i32 | ||
192 | [117; 121) '&[1]': &[i32;_] | ||
193 | [118; 121) '[1]': [i32;_] | ||
194 | [119; 120) '1': i32 | ||
195 | [131; 132) '_': i32 | ||
196 | [136; 140) '&[3]': &[i32;_] | ||
197 | [137; 140) '[3]': [i32;_] | ||
198 | [138; 139) '3': i32 | ||
199 | "### | ||
200 | ); | ||
201 | } | ||
202 | |||
203 | #[test] | ||
204 | fn infer_match_second_coerce() { | ||
205 | assert_snapshot!( | ||
206 | infer(r#" | ||
207 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
208 | fn test(i: i32) { | ||
209 | let x = match i { | ||
210 | 1 => &[1], | ||
211 | 2 => foo(&[2]), | ||
212 | _ => &[3], | ||
213 | }; | ||
214 | } | ||
215 | "#), | ||
216 | @r###" | ||
217 | [11; 12) 'x': &[T] | ||
218 | [28; 39) '{ loop {} }': ! | ||
219 | [30; 37) 'loop {}': ! | ||
220 | [35; 37) '{}': () | ||
221 | [48; 49) 'i': i32 | ||
222 | [56; 150) '{ ... }; }': () | ||
223 | [66; 67) 'x': &[i32] | ||
224 | [70; 147) 'match ... }': &[i32] | ||
225 | [76; 77) 'i': i32 | ||
226 | [88; 89) '1': i32 | ||
227 | [93; 97) '&[1]': &[i32;_] | ||
228 | [94; 97) '[1]': [i32;_] | ||
229 | [95; 96) '1': i32 | ||
230 | [107; 108) '2': i32 | ||
231 | [112; 115) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
232 | [112; 121) 'foo(&[2])': &[i32] | ||
233 | [116; 120) '&[2]': &[i32;_] | ||
234 | [117; 120) '[2]': [i32;_] | ||
235 | [118; 119) '2': i32 | ||
236 | [131; 132) '_': i32 | ||
237 | [136; 140) '&[3]': &[i32;_] | ||
238 | [137; 140) '[3]': [i32;_] | ||
239 | [138; 139) '3': i32 | ||
240 | "### | ||
241 | ); | ||
242 | } | ||
243 | |||
244 | #[test] | ||
245 | fn coerce_merge_one_by_one1() { | ||
246 | covers!(coerce_merge_fail_fallback); | ||
247 | |||
248 | assert_snapshot!( | ||
249 | infer(r#" | ||
250 | fn test() { | ||
251 | let t = &mut 1; | ||
252 | let x = match 1 { | ||
253 | 1 => t as *mut i32, | ||
254 | 2 => t as &i32, | ||
255 | _ => t as *const i32, | ||
256 | }; | ||
257 | } | ||
258 | "#), | ||
259 | @r###" | ||
260 | [11; 145) '{ ... }; }': () | ||
261 | [21; 22) 't': &mut i32 | ||
262 | [25; 31) '&mut 1': &mut i32 | ||
263 | [30; 31) '1': i32 | ||
264 | [41; 42) 'x': *const i32 | ||
265 | [45; 142) 'match ... }': *const i32 | ||
266 | [51; 52) '1': i32 | ||
267 | [63; 64) '1': i32 | ||
268 | [68; 69) 't': &mut i32 | ||
269 | [68; 81) 't as *mut i32': *mut i32 | ||
270 | [91; 92) '2': i32 | ||
271 | [96; 97) 't': &mut i32 | ||
272 | [96; 105) 't as &i32': &i32 | ||
273 | [115; 116) '_': i32 | ||
274 | [120; 121) 't': &mut i32 | ||
275 | [120; 135) 't as *const i32': *const i32 | ||
276 | "### | ||
277 | ); | ||
278 | } | ||
diff --git a/crates/ra_hir/src/ty/tests/never_type.rs b/crates/ra_hir/src/ty/tests/never_type.rs index b9af918e9..c202f545a 100644 --- a/crates/ra_hir/src/ty/tests/never_type.rs +++ b/crates/ra_hir/src/ty/tests/never_type.rs | |||
@@ -19,12 +19,10 @@ fn infer_never2() { | |||
19 | let t = type_at( | 19 | let t = type_at( |
20 | r#" | 20 | r#" |
21 | //- /main.rs | 21 | //- /main.rs |
22 | trait Foo { fn gen() -> Self; } | 22 | fn gen<T>() -> T { loop {} } |
23 | impl Foo for ! { fn gen() -> Self { loop {} } } | ||
24 | impl Foo for () { fn gen() -> Self { loop {} } } | ||
25 | 23 | ||
26 | fn test() { | 24 | fn test() { |
27 | let a = Foo::gen(); | 25 | let a = gen(); |
28 | if false { a } else { loop {} }; | 26 | if false { a } else { loop {} }; |
29 | a<|>; | 27 | a<|>; |
30 | } | 28 | } |
@@ -38,12 +36,10 @@ fn infer_never3() { | |||
38 | let t = type_at( | 36 | let t = type_at( |
39 | r#" | 37 | r#" |
40 | //- /main.rs | 38 | //- /main.rs |
41 | trait Foo { fn gen() -> Self; } | 39 | fn gen<T>() -> T { loop {} } |
42 | impl Foo for ! { fn gen() -> Self { loop {} } } | ||
43 | impl Foo for () { fn gen() -> Self { loop {} } } | ||
44 | 40 | ||
45 | fn test() { | 41 | fn test() { |
46 | let a = Foo::gen(); | 42 | let a = gen(); |
47 | if false { loop {} } else { a }; | 43 | if false { loop {} } else { a }; |
48 | a<|>; | 44 | a<|>; |
49 | } | 45 | } |
@@ -73,12 +69,10 @@ fn never_type_can_be_reinferred1() { | |||
73 | let t = type_at( | 69 | let t = type_at( |
74 | r#" | 70 | r#" |
75 | //- /main.rs | 71 | //- /main.rs |
76 | trait Foo { fn gen() -> Self; } | 72 | fn gen<T>() -> T { loop {} } |
77 | impl Foo for ! { fn gen() -> Self { loop {} } } | ||
78 | impl Foo for () { fn gen() -> Self { loop {} } } | ||
79 | 73 | ||
80 | fn test() { | 74 | fn test() { |
81 | let a = Foo::gen(); | 75 | let a = gen(); |
82 | if false { loop {} } else { a }; | 76 | if false { loop {} } else { a }; |
83 | a<|>; | 77 | a<|>; |
84 | if false { a }; | 78 | if false { a }; |
@@ -154,8 +148,7 @@ fn test() { | |||
154 | } else { | 148 | } else { |
155 | 3.0 | 149 | 3.0 |
156 | }; | 150 | }; |
157 | i<|> | 151 | i<|>; |
158 | () | ||
159 | } | 152 | } |
160 | "#, | 153 | "#, |
161 | ); | 154 | ); |
@@ -173,8 +166,7 @@ fn test(input: bool) { | |||
173 | } else { | 166 | } else { |
174 | return | 167 | return |
175 | }; | 168 | }; |
176 | i<|> | 169 | i<|>; |
177 | () | ||
178 | } | 170 | } |
179 | "#, | 171 | "#, |
180 | ); | 172 | ); |
@@ -193,8 +185,7 @@ fn test(a: i32) { | |||
193 | 3 => loop {}, | 185 | 3 => loop {}, |
194 | _ => 3.0, | 186 | _ => 3.0, |
195 | }; | 187 | }; |
196 | i<|> | 188 | i<|>; |
197 | () | ||
198 | } | 189 | } |
199 | "#, | 190 | "#, |
200 | ); | 191 | ); |
@@ -213,8 +204,7 @@ fn test(a: i32) { | |||
213 | 3 => 3.0, | 204 | 3 => 3.0, |
214 | _ => return, | 205 | _ => return, |
215 | }; | 206 | }; |
216 | i<|> | 207 | i<|>; |
217 | () | ||
218 | } | 208 | } |
219 | "#, | 209 | "#, |
220 | ); | 210 | ); |
@@ -231,8 +221,7 @@ fn test(a: i32) { | |||
231 | 2 => return, | 221 | 2 => return, |
232 | _ => loop {}, | 222 | _ => loop {}, |
233 | }; | 223 | }; |
234 | i<|> | 224 | i<|>; |
235 | () | ||
236 | } | 225 | } |
237 | "#, | 226 | "#, |
238 | ); | 227 | ); |
@@ -249,8 +238,7 @@ fn test(a: i32) { | |||
249 | 2 => 2.0, | 238 | 2 => 2.0, |
250 | _ => 3.0, | 239 | _ => 3.0, |
251 | }; | 240 | }; |
252 | i<|> | 241 | i<|>; |
253 | () | ||
254 | } | 242 | } |
255 | "#, | 243 | "#, |
256 | ); | 244 | ); |