aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/tests/coercion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/tests/coercion.rs')
-rw-r--r--crates/ra_hir/src/ty/tests/coercion.rs278
1 files changed, 278 insertions, 0 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 @@
1use insta::assert_snapshot;
2use test_utils::covers;
3
4// Infer with some common definitions and impls.
5fn 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]
23fn infer_let_stmt_coerce() {
24 assert_snapshot!(
25 infer(r#"
26fn 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]
40fn infer_custom_coerce_unsized() {
41 assert_snapshot!(
42 infer(r#"
43struct A<T: ?Sized>(*const T);
44struct B<T: ?Sized>(*const T);
45struct C<T: ?Sized> { inner: *const T }
46
47impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
48impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
49
50fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
51fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
52fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
53
54fn 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]
91fn infer_if_coerce() {
92 assert_snapshot!(
93 infer(r#"
94fn foo<T>(x: &[T]) -> &[T] { loop {} }
95fn 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]
127fn infer_if_else_coerce() {
128 assert_snapshot!(
129 infer(r#"
130fn foo<T>(x: &[T]) -> &[T] { loop {} }
131fn 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]
163fn infer_match_first_coerce() {
164 assert_snapshot!(
165 infer(r#"
166fn foo<T>(x: &[T]) -> &[T] { loop {} }
167fn 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]
204fn infer_match_second_coerce() {
205 assert_snapshot!(
206 infer(r#"
207fn foo<T>(x: &[T]) -> &[T] { loop {} }
208fn 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]
245fn coerce_merge_one_by_one1() {
246 covers!(coerce_merge_fail_fallback);
247
248 assert_snapshot!(
249 infer(r#"
250fn 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}