aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/Cargo.toml6
-rw-r--r--crates/ra_hir_ty/src/tests.rs13
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs1417
-rw-r--r--crates/ra_hir_ty/src/tests/never_type.rs315
4 files changed, 899 insertions, 852 deletions
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 78f5e55bb..548a3fc1f 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -28,9 +28,9 @@ test_utils = { path = "../test_utils" }
28 28
29scoped-tls = "1" 29scoped-tls = "1"
30 30
31chalk-solve = { version = "0.17.0" } 31chalk-solve = { version = "0.18.0" }
32chalk-ir = { version = "0.17.0" } 32chalk-ir = { version = "0.18.0" }
33chalk-recursive = { version = "0.17.0" } 33chalk-recursive = { version = "0.18.0" }
34 34
35[dev-dependencies] 35[dev-dependencies]
36insta = "0.16.0" 36insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index c972bf845..59a21092e 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -10,6 +10,7 @@ mod display_source_code;
10 10
11use std::sync::Arc; 11use std::sync::Arc;
12 12
13use expect::Expect;
13use hir_def::{ 14use hir_def::{
14 body::{BodySourceMap, SyntheticSyntax}, 15 body::{BodySourceMap, SyntheticSyntax},
15 child_by_source::ChildBySource, 16 child_by_source::ChildBySource,
@@ -344,3 +345,15 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
344 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) 345 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
345 } 346 }
346} 347}
348
349fn check_infer(ra_fixture: &str, expect: Expect) {
350 let mut actual = infer(ra_fixture);
351 actual.push('\n');
352 expect.assert_eq(&actual);
353}
354
355fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
356 let mut actual = infer_with_mismatches(ra_fixture, true);
357 actual.push('\n');
358 expect.assert_eq(&actual);
359}
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index d7fb6a962..17efd75cb 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -1,345 +1,381 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::infer_with_mismatches; 4use super::{check_infer, check_infer_with_mismatches};
5
6// Infer with some common definitions and impls.
7fn infer(source: &str) -> String {
8 let defs = r#"
9 #[lang = "sized"]
10 pub trait Sized {}
11 #[lang = "unsize"]
12 pub trait Unsize<T: ?Sized> {}
13 #[lang = "coerce_unsized"]
14 pub trait CoerceUnsized<T> {}
15
16 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
17 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
18 "#;
19
20 // Append to the end to keep positions unchanged.
21 super::infer(&format!("{}{}", source, defs))
22}
23 5
24#[test] 6#[test]
25fn infer_block_expr_type_mismatch() { 7fn infer_block_expr_type_mismatch() {
26 assert_snapshot!( 8 check_infer(
27 infer(r#" 9 r"
28fn test() { 10 fn test() {
29 let a: i32 = { 1i64 }; 11 let a: i32 = { 1i64 };
30} 12 }
31"#), 13 ",
32 @r###" 14 expect![[r"
33 10..40 '{ ...4 }; }': () 15 10..40 '{ ...4 }; }': ()
34 20..21 'a': i32 16 20..21 'a': i32
35 29..37 '{ 1i64 }': i64 17 29..37 '{ 1i64 }': i64
36 31..35 '1i64': i64 18 31..35 '1i64': i64
37 "###); 19 "]],
20 );
38} 21}
39 22
40#[test] 23#[test]
41fn coerce_places() { 24fn coerce_places() {
42 assert_snapshot!( 25 check_infer(
43 infer(r#" 26 r#"
44struct S<T> { a: T } 27 struct S<T> { a: T }
45 28
46fn f<T>(_: &[T]) -> T { loop {} } 29 fn f<T>(_: &[T]) -> T { loop {} }
47fn g<T>(_: S<&[T]>) -> T { loop {} } 30 fn g<T>(_: S<&[T]>) -> T { loop {} }
48 31
49fn gen<T>() -> *mut [T; 2] { loop {} } 32 fn gen<T>() -> *mut [T; 2] { loop {} }
50fn test1<U>() -> *mut [U] { 33 fn test1<U>() -> *mut [U] {
51 gen() 34 gen()
52} 35 }
53 36
54fn test2() { 37 fn test2() {
55 let arr: &[u8; 1] = &[1]; 38 let arr: &[u8; 1] = &[1];
56 39
57 let a: &[_] = arr; 40 let a: &[_] = arr;
58 let b = f(arr); 41 let b = f(arr);
59 let c: &[_] = { arr }; 42 let c: &[_] = { arr };
60 let d = g(S { a: arr }); 43 let d = g(S { a: arr });
61 let e: [&[_]; 1] = [arr]; 44 let e: [&[_]; 1] = [arr];
62 let f: [&[_]; 2] = [arr; 2]; 45 let f: [&[_]; 2] = [arr; 2];
63 let g: (&[_], &[_]) = (arr, arr); 46 let g: (&[_], &[_]) = (arr, arr);
64} 47 }
65"#), 48
66 @r###" 49 #[lang = "sized"]
67 30..31 '_': &[T] 50 pub trait Sized {}
68 44..55 '{ loop {} }': T 51 #[lang = "unsize"]
69 46..53 'loop {}': ! 52 pub trait Unsize<T: ?Sized> {}
70 51..53 '{}': () 53 #[lang = "coerce_unsized"]
71 64..65 '_': S<&[T]> 54 pub trait CoerceUnsized<T> {}
72 81..92 '{ loop {} }': T 55
73 83..90 'loop {}': ! 56 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
74 88..90 '{}': () 57 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
75 121..132 '{ loop {} }': *mut [T; _] 58 "#,
76 123..130 'loop {}': ! 59 expect![[r"
77 128..130 '{}': () 60 30..31 '_': &[T]
78 159..172 '{ gen() }': *mut [U] 61 44..55 '{ loop {} }': T
79 165..168 'gen': fn gen<U>() -> *mut [U; _] 62 46..53 'loop {}': !
80 165..170 'gen()': *mut [U; _] 63 51..53 '{}': ()
81 185..419 '{ ...rr); }': () 64 64..65 '_': S<&[T]>
82 195..198 'arr': &[u8; _] 65 81..92 '{ loop {} }': T
83 211..215 '&[1]': &[u8; _] 66 83..90 'loop {}': !
84 212..215 '[1]': [u8; _] 67 88..90 '{}': ()
85 213..214 '1': u8 68 121..132 '{ loop {} }': *mut [T; _]
86 226..227 'a': &[u8] 69 123..130 'loop {}': !
87 236..239 'arr': &[u8; _] 70 128..130 '{}': ()
88 249..250 'b': u8 71 159..172 '{ gen() }': *mut [U]
89 253..254 'f': fn f<u8>(&[u8]) -> u8 72 165..168 'gen': fn gen<U>() -> *mut [U; _]
90 253..259 'f(arr)': u8 73 165..170 'gen()': *mut [U; _]
91 255..258 'arr': &[u8; _] 74 185..419 '{ ...rr); }': ()
92 269..270 'c': &[u8] 75 195..198 'arr': &[u8; _]
93 279..286 '{ arr }': &[u8] 76 211..215 '&[1]': &[u8; _]
94 281..284 'arr': &[u8; _] 77 212..215 '[1]': [u8; _]
95 296..297 'd': u8 78 213..214 '1': u8
96 300..301 'g': fn g<u8>(S<&[u8]>) -> u8 79 226..227 'a': &[u8]
97 300..315 'g(S { a: arr })': u8 80 236..239 'arr': &[u8; _]
98 302..314 'S { a: arr }': S<&[u8]> 81 249..250 'b': u8
99 309..312 'arr': &[u8; _] 82 253..254 'f': fn f<u8>(&[u8]) -> u8
100 325..326 'e': [&[u8]; _] 83 253..259 'f(arr)': u8
101 340..345 '[arr]': [&[u8]; _] 84 255..258 'arr': &[u8; _]
102 341..344 'arr': &[u8; _] 85 269..270 'c': &[u8]
103 355..356 'f': [&[u8]; _] 86 279..286 '{ arr }': &[u8]
104 370..378 '[arr; 2]': [&[u8]; _] 87 281..284 'arr': &[u8; _]
105 371..374 'arr': &[u8; _] 88 296..297 'd': u8
106 376..377 '2': usize 89 300..301 'g': fn g<u8>(S<&[u8]>) -> u8
107 388..389 'g': (&[u8], &[u8]) 90 300..315 'g(S { a: arr })': u8
108 406..416 '(arr, arr)': (&[u8], &[u8]) 91 302..314 'S { a: arr }': S<&[u8]>
109 407..410 'arr': &[u8; _] 92 309..312 'arr': &[u8; _]
110 412..415 'arr': &[u8; _] 93 325..326 'e': [&[u8]; _]
111 "### 94 340..345 '[arr]': [&[u8]; _]
95 341..344 'arr': &[u8; _]
96 355..356 'f': [&[u8]; _]
97 370..378 '[arr; 2]': [&[u8]; _]
98 371..374 'arr': &[u8; _]
99 376..377 '2': usize
100 388..389 'g': (&[u8], &[u8])
101 406..416 '(arr, arr)': (&[u8], &[u8])
102 407..410 'arr': &[u8; _]
103 412..415 'arr': &[u8; _]
104 "]],
112 ); 105 );
113} 106}
114 107
115#[test] 108#[test]
116fn infer_let_stmt_coerce() { 109fn infer_let_stmt_coerce() {
117 assert_snapshot!( 110 check_infer(
118 infer(r#" 111 r"
119fn test() { 112 fn test() {
120 let x: &[isize] = &[1]; 113 let x: &[isize] = &[1];
121 let x: *const [isize] = &[1]; 114 let x: *const [isize] = &[1];
122} 115 }
123"#), 116 ",
124 @r###" 117 expect![[r"
125 10..75 '{ ...[1]; }': () 118 10..75 '{ ...[1]; }': ()
126 20..21 'x': &[isize] 119 20..21 'x': &[isize]
127 34..38 '&[1]': &[isize; _] 120 34..38 '&[1]': &[isize; _]
128 35..38 '[1]': [isize; _] 121 35..38 '[1]': [isize; _]
129 36..37 '1': isize 122 36..37 '1': isize
130 48..49 'x': *const [isize] 123 48..49 'x': *const [isize]
131 68..72 '&[1]': &[isize; _] 124 68..72 '&[1]': &[isize; _]
132 69..72 '[1]': [isize; _] 125 69..72 '[1]': [isize; _]
133 70..71 '1': isize 126 70..71 '1': isize
134 "###); 127 "]],
128 );
135} 129}
136 130
137#[test] 131#[test]
138fn infer_custom_coerce_unsized() { 132fn infer_custom_coerce_unsized() {
139 assert_snapshot!( 133 check_infer(
140 infer(r#" 134 r#"
141struct A<T: ?Sized>(*const T); 135 struct A<T: ?Sized>(*const T);
142struct B<T: ?Sized>(*const T); 136 struct B<T: ?Sized>(*const T);
143struct C<T: ?Sized> { inner: *const T } 137 struct C<T: ?Sized> { inner: *const T }
144 138
145impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} 139 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
146impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} 140 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
147 141
148fn foo1<T>(x: A<[T]>) -> A<[T]> { x } 142 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
149fn foo2<T>(x: B<[T]>) -> B<[T]> { x } 143 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
150fn foo3<T>(x: C<[T]>) -> C<[T]> { x } 144 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
151 145
152fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { 146 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
153 let d = foo1(a); 147 let d = foo1(a);
154 let e = foo2(b); 148 let e = foo2(b);
155 let f = foo3(c); 149 let f = foo3(c);
156} 150 }
157"#), 151
158 @r###" 152
159 257..258 'x': A<[T]> 153 #[lang = "sized"]
160 278..283 '{ x }': A<[T]> 154 pub trait Sized {}
161 280..281 'x': A<[T]> 155 #[lang = "unsize"]
162 295..296 'x': B<[T]> 156 pub trait Unsize<T: ?Sized> {}
163 316..321 '{ x }': B<[T]> 157 #[lang = "coerce_unsized"]
164 318..319 'x': B<[T]> 158 pub trait CoerceUnsized<T> {}
165 333..334 'x': C<[T]> 159
166 354..359 '{ x }': C<[T]> 160 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
167 356..357 'x': C<[T]> 161 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
168 369..370 'a': A<[u8; _]> 162 "#,
169 384..385 'b': B<[u8; _]> 163 expect![[r"
170 399..400 'c': C<[u8; _]> 164 257..258 'x': A<[T]>
171 414..480 '{ ...(c); }': () 165 278..283 '{ x }': A<[T]>
172 424..425 'd': A<[{unknown}]> 166 280..281 'x': A<[T]>
173 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> 167 295..296 'x': B<[T]>
174 428..435 'foo1(a)': A<[{unknown}]> 168 316..321 '{ x }': B<[T]>
175 433..434 'a': A<[u8; _]> 169 318..319 'x': B<[T]>
176 445..446 'e': B<[u8]> 170 333..334 'x': C<[T]>
177 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]> 171 354..359 '{ x }': C<[T]>
178 449..456 'foo2(b)': B<[u8]> 172 356..357 'x': C<[T]>
179 454..455 'b': B<[u8; _]> 173 369..370 'a': A<[u8; _]>
180 466..467 'f': C<[u8]> 174 384..385 'b': B<[u8; _]>
181 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]> 175 399..400 'c': C<[u8; _]>
182 470..477 'foo3(c)': C<[u8]> 176 414..480 '{ ...(c); }': ()
183 475..476 'c': C<[u8; _]> 177 424..425 'd': A<[{unknown}]>
184 "### 178 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
179 428..435 'foo1(a)': A<[{unknown}]>
180 433..434 'a': A<[u8; _]>
181 445..446 'e': B<[u8]>
182 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
183 449..456 'foo2(b)': B<[u8]>
184 454..455 'b': B<[u8; _]>
185 466..467 'f': C<[u8]>
186 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
187 470..477 'foo3(c)': C<[u8]>
188 475..476 'c': C<[u8; _]>
189 "]],
185 ); 190 );
186} 191}
187 192
188#[test] 193#[test]
189fn infer_if_coerce() { 194fn infer_if_coerce() {
190 assert_snapshot!( 195 check_infer(
191 infer(r#" 196 r#"
192fn foo<T>(x: &[T]) -> &[T] { loop {} } 197 fn foo<T>(x: &[T]) -> &[T] { loop {} }
193fn test() { 198 fn test() {
194 let x = if true { 199 let x = if true {
195 foo(&[1]) 200 foo(&[1])
196 } else { 201 } else {
197 &[1] 202 &[1]
198 }; 203 };
199} 204 }
200"#), 205
201 @r###" 206
202 10..11 'x': &[T] 207 #[lang = "sized"]
203 27..38 '{ loop {} }': &[T] 208 pub trait Sized {}
204 29..36 'loop {}': ! 209 #[lang = "unsize"]
205 34..36 '{}': () 210 pub trait Unsize<T: ?Sized> {}
206 49..125 '{ ... }; }': () 211 "#,
207 59..60 'x': &[i32] 212 expect![[r"
208 63..122 'if tru... }': &[i32] 213 10..11 'x': &[T]
209 66..70 'true': bool 214 27..38 '{ loop {} }': &[T]
210 71..96 '{ ... }': &[i32] 215 29..36 'loop {}': !
211 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32] 216 34..36 '{}': ()
212 81..90 'foo(&[1])': &[i32] 217 49..125 '{ ... }; }': ()
213 85..89 '&[1]': &[i32; _] 218 59..60 'x': &[i32]
214 86..89 '[1]': [i32; _] 219 63..122 'if tru... }': &[i32]
215 87..88 '1': i32 220 66..70 'true': bool
216 102..122 '{ ... }': &[i32; _] 221 71..96 '{ ... }': &[i32]
217 112..116 '&[1]': &[i32; _] 222 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
218 113..116 '[1]': [i32; _] 223 81..90 'foo(&[1])': &[i32]
219 114..115 '1': i32 224 85..89 '&[1]': &[i32; _]
220 "### 225 86..89 '[1]': [i32; _]
226 87..88 '1': i32
227 102..122 '{ ... }': &[i32; _]
228 112..116 '&[1]': &[i32; _]
229 113..116 '[1]': [i32; _]
230 114..115 '1': i32
231 "]],
221 ); 232 );
222} 233}
223 234
224#[test] 235#[test]
225fn infer_if_else_coerce() { 236fn infer_if_else_coerce() {
226 assert_snapshot!( 237 check_infer(
227 infer(r#" 238 r#"
228fn foo<T>(x: &[T]) -> &[T] { loop {} } 239 fn foo<T>(x: &[T]) -> &[T] { loop {} }
229fn test() { 240 fn test() {
230 let x = if true { 241 let x = if true {
231 &[1] 242 &[1]
232 } else { 243 } else {
233 foo(&[1]) 244 foo(&[1])
234 }; 245 };
235} 246 }
236"#), 247
237 @r###" 248 #[lang = "sized"]
238 10..11 'x': &[T] 249 pub trait Sized {}
239 27..38 '{ loop {} }': &[T] 250 #[lang = "unsize"]
240 29..36 'loop {}': ! 251 pub trait Unsize<T: ?Sized> {}
241 34..36 '{}': () 252 #[lang = "coerce_unsized"]
242 49..125 '{ ... }; }': () 253 pub trait CoerceUnsized<T> {}
243 59..60 'x': &[i32] 254
244 63..122 'if tru... }': &[i32] 255 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
245 66..70 'true': bool 256 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
246 71..91 '{ ... }': &[i32; _] 257 "#,
247 81..85 '&[1]': &[i32; _] 258 expect![[r"
248 82..85 '[1]': [i32; _] 259 10..11 'x': &[T]
249 83..84 '1': i32 260 27..38 '{ loop {} }': &[T]
250 97..122 '{ ... }': &[i32] 261 29..36 'loop {}': !
251 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32] 262 34..36 '{}': ()
252 107..116 'foo(&[1])': &[i32] 263 49..125 '{ ... }; }': ()
253 111..115 '&[1]': &[i32; _] 264 59..60 'x': &[i32]
254 112..115 '[1]': [i32; _] 265 63..122 'if tru... }': &[i32]
255 113..114 '1': i32 266 66..70 'true': bool
256 "### 267 71..91 '{ ... }': &[i32; _]
257 ); 268 81..85 '&[1]': &[i32; _]
269 82..85 '[1]': [i32; _]
270 83..84 '1': i32
271 97..122 '{ ... }': &[i32]
272 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
273 107..116 'foo(&[1])': &[i32]
274 111..115 '&[1]': &[i32; _]
275 112..115 '[1]': [i32; _]
276 113..114 '1': i32
277 "]],
278 )
258} 279}
259 280
260#[test] 281#[test]
261fn infer_match_first_coerce() { 282fn infer_match_first_coerce() {
262 assert_snapshot!( 283 check_infer(
263 infer(r#" 284 r#"
264fn foo<T>(x: &[T]) -> &[T] { loop {} } 285 fn foo<T>(x: &[T]) -> &[T] { loop {} }
265fn test(i: i32) { 286 fn test(i: i32) {
266 let x = match i { 287 let x = match i {
267 2 => foo(&[2]), 288 2 => foo(&[2]),
268 1 => &[1], 289 1 => &[1],
269 _ => &[3], 290 _ => &[3],
270 }; 291 };
271} 292 }
272"#), 293
273 @r###" 294 #[lang = "sized"]
274 10..11 'x': &[T] 295 pub trait Sized {}
275 27..38 '{ loop {} }': &[T] 296 #[lang = "unsize"]
276 29..36 'loop {}': ! 297 pub trait Unsize<T: ?Sized> {}
277 34..36 '{}': () 298 "#,
278 47..48 'i': i32 299 expect![[r"
279 55..149 '{ ... }; }': () 300 10..11 'x': &[T]
280 65..66 'x': &[i32] 301 27..38 '{ loop {} }': &[T]
281 69..146 'match ... }': &[i32] 302 29..36 'loop {}': !
282 75..76 'i': i32 303 34..36 '{}': ()
283 87..88 '2': i32 304 47..48 'i': i32
284 87..88 '2': i32 305 55..149 '{ ... }; }': ()
285 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32] 306 65..66 'x': &[i32]
286 92..101 'foo(&[2])': &[i32] 307 69..146 'match ... }': &[i32]
287 96..100 '&[2]': &[i32; _] 308 75..76 'i': i32
288 97..100 '[2]': [i32; _] 309 87..88 '2': i32
289 98..99 '2': i32 310 87..88 '2': i32
290 111..112 '1': i32 311 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
291 111..112 '1': i32 312 92..101 'foo(&[2])': &[i32]
292 116..120 '&[1]': &[i32; _] 313 96..100 '&[2]': &[i32; _]
293 117..120 '[1]': [i32; _] 314 97..100 '[2]': [i32; _]
294 118..119 '1': i32 315 98..99 '2': i32
295 130..131 '_': i32 316 111..112 '1': i32
296 135..139 '&[3]': &[i32; _] 317 111..112 '1': i32
297 136..139 '[3]': [i32; _] 318 116..120 '&[1]': &[i32; _]
298 137..138 '3': i32 319 117..120 '[1]': [i32; _]
299 "### 320 118..119 '1': i32
321 130..131 '_': i32
322 135..139 '&[3]': &[i32; _]
323 136..139 '[3]': [i32; _]
324 137..138 '3': i32
325 "]],
300 ); 326 );
301} 327}
302 328
303#[test] 329#[test]
304fn infer_match_second_coerce() { 330fn infer_match_second_coerce() {
305 assert_snapshot!( 331 check_infer(
306 infer(r#" 332 r#"
307fn foo<T>(x: &[T]) -> &[T] { loop {} } 333 fn foo<T>(x: &[T]) -> &[T] { loop {} }
308fn test(i: i32) { 334 fn test(i: i32) {
309 let x = match i { 335 let x = match i {
310 1 => &[1], 336 1 => &[1],
311 2 => foo(&[2]), 337 2 => foo(&[2]),
312 _ => &[3], 338 _ => &[3],
313 }; 339 };
314} 340 }
315"#), 341
316 @r###" 342 #[lang = "sized"]
317 10..11 'x': &[T] 343 pub trait Sized {}
318 27..38 '{ loop {} }': &[T] 344 #[lang = "unsize"]
319 29..36 'loop {}': ! 345 pub trait Unsize<T: ?Sized> {}
320 34..36 '{}': () 346 #[lang = "coerce_unsized"]
321 47..48 'i': i32 347 pub trait CoerceUnsized<T> {}
322 55..149 '{ ... }; }': () 348
323 65..66 'x': &[i32] 349 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
324 69..146 'match ... }': &[i32] 350 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
325 75..76 'i': i32 351 "#,
326 87..88 '1': i32 352 expect![[r"
327 87..88 '1': i32 353 10..11 'x': &[T]
328 92..96 '&[1]': &[i32; _] 354 27..38 '{ loop {} }': &[T]
329 93..96 '[1]': [i32; _] 355 29..36 'loop {}': !
330 94..95 '1': i32 356 34..36 '{}': ()
331 106..107 '2': i32 357 47..48 'i': i32
332 106..107 '2': i32 358 55..149 '{ ... }; }': ()
333 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32] 359 65..66 'x': &[i32]
334 111..120 'foo(&[2])': &[i32] 360 69..146 'match ... }': &[i32]
335 115..119 '&[2]': &[i32; _] 361 75..76 'i': i32
336 116..119 '[2]': [i32; _] 362 87..88 '1': i32
337 117..118 '2': i32 363 87..88 '1': i32
338 130..131 '_': i32 364 92..96 '&[1]': &[i32; _]
339 135..139 '&[3]': &[i32; _] 365 93..96 '[1]': [i32; _]
340 136..139 '[3]': [i32; _] 366 94..95 '1': i32
341 137..138 '3': i32 367 106..107 '2': i32
342 "### 368 106..107 '2': i32
369 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
370 111..120 'foo(&[2])': &[i32]
371 115..119 '&[2]': &[i32; _]
372 116..119 '[2]': [i32; _]
373 117..118 '2': i32
374 130..131 '_': i32
375 135..139 '&[3]': &[i32; _]
376 136..139 '[3]': [i32; _]
377 137..138 '3': i32
378 "]],
343 ); 379 );
344} 380}
345 381
@@ -347,360 +383,361 @@ fn test(i: i32) {
347fn coerce_merge_one_by_one1() { 383fn coerce_merge_one_by_one1() {
348 mark::check!(coerce_merge_fail_fallback); 384 mark::check!(coerce_merge_fail_fallback);
349 385
350 assert_snapshot!( 386 check_infer(
351 infer(r#" 387 r"
352fn test() { 388 fn test() {
353 let t = &mut 1; 389 let t = &mut 1;
354 let x = match 1 { 390 let x = match 1 {
355 1 => t as *mut i32, 391 1 => t as *mut i32,
356 2 => t as &i32, 392 2 => t as &i32,
357 _ => t as *const i32, 393 _ => t as *const i32,
358 }; 394 };
359} 395 }
360"#), 396 ",
361 @r###" 397 expect![[r"
362 10..144 '{ ... }; }': () 398 10..144 '{ ... }; }': ()
363 20..21 't': &mut i32 399 20..21 't': &mut i32
364 24..30 '&mut 1': &mut i32 400 24..30 '&mut 1': &mut i32
365 29..30 '1': i32 401 29..30 '1': i32
366 40..41 'x': *const i32 402 40..41 'x': *const i32
367 44..141 'match ... }': *const i32 403 44..141 'match ... }': *const i32
368 50..51 '1': i32 404 50..51 '1': i32
369 62..63 '1': i32 405 62..63 '1': i32
370 62..63 '1': i32 406 62..63 '1': i32
371 67..68 't': &mut i32 407 67..68 't': &mut i32
372 67..80 't as *mut i32': *mut i32 408 67..80 't as *mut i32': *mut i32
373 90..91 '2': i32 409 90..91 '2': i32
374 90..91 '2': i32 410 90..91 '2': i32
375 95..96 't': &mut i32 411 95..96 't': &mut i32
376 95..104 't as &i32': &i32 412 95..104 't as &i32': &i32
377 114..115 '_': i32 413 114..115 '_': i32
378 119..120 't': &mut i32 414 119..120 't': &mut i32
379 119..134 't as *const i32': *const i32 415 119..134 't as *const i32': *const i32
380 "### 416 "]],
381 ); 417 );
382} 418}
383 419
384#[test] 420#[test]
385fn return_coerce_unknown() { 421fn return_coerce_unknown() {
386 assert_snapshot!( 422 check_infer_with_mismatches(
387 infer_with_mismatches(r#" 423 r"
388fn foo() -> u32 { 424 fn foo() -> u32 {
389 return unknown; 425 return unknown;
390} 426 }
391"#, true), 427 ",
392 @r###" 428 expect![[r"
393 16..39 '{ ...own; }': u32 429 16..39 '{ ...own; }': u32
394 22..36 'return unknown': ! 430 22..36 'return unknown': !
395 29..36 'unknown': u32 431 29..36 'unknown': u32
396 "### 432 "]],
397 ); 433 );
398} 434}
399 435
400#[test] 436#[test]
401fn coerce_autoderef() { 437fn coerce_autoderef() {
402 assert_snapshot!( 438 check_infer_with_mismatches(
403 infer_with_mismatches(r#" 439 r"
404struct Foo; 440 struct Foo;
405fn takes_ref_foo(x: &Foo) {} 441 fn takes_ref_foo(x: &Foo) {}
406fn test() { 442 fn test() {
407 takes_ref_foo(&Foo); 443 takes_ref_foo(&Foo);
408 takes_ref_foo(&&Foo); 444 takes_ref_foo(&&Foo);
409 takes_ref_foo(&&&Foo); 445 takes_ref_foo(&&&Foo);
410} 446 }
411"#, true), 447 ",
412 @r###" 448 expect![[r"
413 29..30 'x': &Foo 449 29..30 'x': &Foo
414 38..40 '{}': () 450 38..40 '{}': ()
415 51..132 '{ ...oo); }': () 451 51..132 '{ ...oo); }': ()
416 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo) 452 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
417 57..76 'takes_...(&Foo)': () 453 57..76 'takes_...(&Foo)': ()
418 71..75 '&Foo': &Foo 454 71..75 '&Foo': &Foo
419 72..75 'Foo': Foo 455 72..75 'Foo': Foo
420 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo) 456 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
421 82..102 'takes_...&&Foo)': () 457 82..102 'takes_...&&Foo)': ()
422 96..101 '&&Foo': &&Foo 458 96..101 '&&Foo': &&Foo
423 97..101 '&Foo': &Foo 459 97..101 '&Foo': &Foo
424 98..101 'Foo': Foo 460 98..101 'Foo': Foo
425 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo) 461 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
426 108..129 'takes_...&&Foo)': () 462 108..129 'takes_...&&Foo)': ()
427 122..128 '&&&Foo': &&&Foo 463 122..128 '&&&Foo': &&&Foo
428 123..128 '&&Foo': &&Foo 464 123..128 '&&Foo': &&Foo
429 124..128 '&Foo': &Foo 465 124..128 '&Foo': &Foo
430 125..128 'Foo': Foo 466 125..128 'Foo': Foo
431 "### 467 "]],
432 ); 468 );
433} 469}
434 470
435#[test] 471#[test]
436fn coerce_autoderef_generic() { 472fn coerce_autoderef_generic() {
437 assert_snapshot!( 473 check_infer_with_mismatches(
438 infer_with_mismatches(r#" 474 r"
439struct Foo; 475 struct Foo;
440fn takes_ref<T>(x: &T) -> T { *x } 476 fn takes_ref<T>(x: &T) -> T { *x }
441fn test() { 477 fn test() {
442 takes_ref(&Foo); 478 takes_ref(&Foo);
443 takes_ref(&&Foo); 479 takes_ref(&&Foo);
444 takes_ref(&&&Foo); 480 takes_ref(&&&Foo);
445} 481 }
446"#, true), 482 ",
447 @r###" 483 expect![[r"
448 28..29 'x': &T 484 28..29 'x': &T
449 40..46 '{ *x }': T 485 40..46 '{ *x }': T
450 42..44 '*x': T 486 42..44 '*x': T
451 43..44 'x': &T 487 43..44 'x': &T
452 57..126 '{ ...oo); }': () 488 57..126 '{ ...oo); }': ()
453 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo 489 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
454 63..78 'takes_ref(&Foo)': Foo 490 63..78 'takes_ref(&Foo)': Foo
455 73..77 '&Foo': &Foo 491 73..77 '&Foo': &Foo
456 74..77 'Foo': Foo 492 74..77 'Foo': Foo
457 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo 493 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
458 84..100 'takes_...&&Foo)': &Foo 494 84..100 'takes_...&&Foo)': &Foo
459 94..99 '&&Foo': &&Foo 495 94..99 '&&Foo': &&Foo
460 95..99 '&Foo': &Foo 496 95..99 '&Foo': &Foo
461 96..99 'Foo': Foo 497 96..99 'Foo': Foo
462 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo 498 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
463 106..123 'takes_...&&Foo)': &&Foo 499 106..123 'takes_...&&Foo)': &&Foo
464 116..122 '&&&Foo': &&&Foo 500 116..122 '&&&Foo': &&&Foo
465 117..122 '&&Foo': &&Foo 501 117..122 '&&Foo': &&Foo
466 118..122 '&Foo': &Foo 502 118..122 '&Foo': &Foo
467 119..122 'Foo': Foo 503 119..122 'Foo': Foo
468 "### 504 "]],
469 ); 505 );
470} 506}
471 507
472#[test] 508#[test]
473fn coerce_autoderef_block() { 509fn coerce_autoderef_block() {
474 assert_snapshot!( 510 check_infer_with_mismatches(
475 infer_with_mismatches(r#" 511 r#"
476struct String {} 512 struct String {}
477#[lang = "deref"] 513 #[lang = "deref"]
478trait Deref { type Target; } 514 trait Deref { type Target; }
479impl Deref for String { type Target = str; } 515 impl Deref for String { type Target = str; }
480fn takes_ref_str(x: &str) {} 516 fn takes_ref_str(x: &str) {}
481fn returns_string() -> String { loop {} } 517 fn returns_string() -> String { loop {} }
482fn test() { 518 fn test() {
483 takes_ref_str(&{ returns_string() }); 519 takes_ref_str(&{ returns_string() });
484} 520 }
485"#, true), 521 "#,
486 @r###" 522 expect![[r"
487 126..127 'x': &str 523 126..127 'x': &str
488 135..137 '{}': () 524 135..137 '{}': ()
489 168..179 '{ loop {} }': String 525 168..179 '{ loop {} }': String
490 170..177 'loop {}': ! 526 170..177 'loop {}': !
491 175..177 '{}': () 527 175..177 '{}': ()
492 190..235 '{ ... }); }': () 528 190..235 '{ ... }); }': ()
493 196..209 'takes_ref_str': fn takes_ref_str(&str) 529 196..209 'takes_ref_str': fn takes_ref_str(&str)
494 196..232 'takes_...g() })': () 530 196..232 'takes_...g() })': ()
495 210..231 '&{ ret...ng() }': &String 531 210..231 '&{ ret...ng() }': &String
496 211..231 '{ retu...ng() }': String 532 211..231 '{ retu...ng() }': String
497 213..227 'returns_string': fn returns_string() -> String 533 213..227 'returns_string': fn returns_string() -> String
498 213..229 'return...ring()': String 534 213..229 'return...ring()': String
499 "### 535 "]],
500 ); 536 );
501} 537}
502 538
503#[test] 539#[test]
504fn closure_return_coerce() { 540fn closure_return_coerce() {
505 assert_snapshot!( 541 check_infer_with_mismatches(
506 infer_with_mismatches(r#" 542 r"
507fn foo() { 543 fn foo() {
508 let x = || { 544 let x = || {
509 if true { 545 if true {
510 return &1u32; 546 return &1u32;
547 }
548 &&1u32
549 };
511 } 550 }
512 &&1u32 551 ",
513 }; 552 expect![[r"
514} 553 9..105 '{ ... }; }': ()
515"#, true), 554 19..20 'x': || -> &u32
516 @r###" 555 23..102 '|| { ... }': || -> &u32
517 9..105 '{ ... }; }': () 556 26..102 '{ ... }': &u32
518 19..20 'x': || -> &u32 557 36..81 'if tru... }': ()
519 23..102 '|| { ... }': || -> &u32 558 39..43 'true': bool
520 26..102 '{ ... }': &u32 559 44..81 '{ ... }': ()
521 36..81 'if tru... }': () 560 58..70 'return &1u32': !
522 39..43 'true': bool 561 65..70 '&1u32': &u32
523 44..81 '{ ... }': () 562 66..70 '1u32': u32
524 58..70 'return &1u32': ! 563 90..96 '&&1u32': &&u32
525 65..70 '&1u32': &u32 564 91..96 '&1u32': &u32
526 66..70 '1u32': u32 565 92..96 '1u32': u32
527 90..96 '&&1u32': &&u32 566 "]],
528 91..96 '&1u32': &u32
529 92..96 '1u32': u32
530 "###
531 ); 567 );
532} 568}
533 569
534#[test] 570#[test]
535fn coerce_fn_item_to_fn_ptr() { 571fn coerce_fn_item_to_fn_ptr() {
536 assert_snapshot!( 572 check_infer_with_mismatches(
537 infer_with_mismatches(r#" 573 r"
538fn foo(x: u32) -> isize { 1 } 574 fn foo(x: u32) -> isize { 1 }
539fn test() { 575 fn test() {
540 let f: fn(u32) -> isize = foo; 576 let f: fn(u32) -> isize = foo;
541} 577 }
542"#, true), 578 ",
543 @r###" 579 expect![[r"
544 7..8 'x': u32 580 7..8 'x': u32
545 24..29 '{ 1 }': isize 581 24..29 '{ 1 }': isize
546 26..27 '1': isize 582 26..27 '1': isize
547 40..78 '{ ...foo; }': () 583 40..78 '{ ...foo; }': ()
548 50..51 'f': fn(u32) -> isize 584 50..51 'f': fn(u32) -> isize
549 72..75 'foo': fn foo(u32) -> isize 585 72..75 'foo': fn foo(u32) -> isize
550 "### 586 "]],
551 ); 587 );
552} 588}
553 589
554#[test] 590#[test]
555fn coerce_fn_items_in_match_arms() { 591fn coerce_fn_items_in_match_arms() {
556 mark::check!(coerce_fn_reification); 592 mark::check!(coerce_fn_reification);
557 assert_snapshot!( 593
558 infer_with_mismatches(r#" 594 check_infer_with_mismatches(
559fn foo1(x: u32) -> isize { 1 } 595 r"
560fn foo2(x: u32) -> isize { 2 } 596 fn foo1(x: u32) -> isize { 1 }
561fn foo3(x: u32) -> isize { 3 } 597 fn foo2(x: u32) -> isize { 2 }
562fn test() { 598 fn foo3(x: u32) -> isize { 3 }
563 let x = match 1 { 599 fn test() {
564 1 => foo1, 600 let x = match 1 {
565 2 => foo2, 601 1 => foo1,
566 _ => foo3, 602 2 => foo2,
567 }; 603 _ => foo3,
568} 604 };
569"#, true), 605 }
570 @r###" 606 ",
571 8..9 'x': u32 607 expect![[r"
572 25..30 '{ 1 }': isize 608 8..9 'x': u32
573 27..28 '1': isize 609 25..30 '{ 1 }': isize
574 39..40 'x': u32 610 27..28 '1': isize
575 56..61 '{ 2 }': isize 611 39..40 'x': u32
576 58..59 '2': isize 612 56..61 '{ 2 }': isize
577 70..71 'x': u32 613 58..59 '2': isize
578 87..92 '{ 3 }': isize 614 70..71 'x': u32
579 89..90 '3': isize 615 87..92 '{ 3 }': isize
580 103..192 '{ ... }; }': () 616 89..90 '3': isize
581 113..114 'x': fn(u32) -> isize 617 103..192 '{ ... }; }': ()
582 117..189 'match ... }': fn(u32) -> isize 618 113..114 'x': fn(u32) -> isize
583 123..124 '1': i32 619 117..189 'match ... }': fn(u32) -> isize
584 135..136 '1': i32 620 123..124 '1': i32
585 135..136 '1': i32 621 135..136 '1': i32
586 140..144 'foo1': fn foo1(u32) -> isize 622 135..136 '1': i32
587 154..155 '2': i32 623 140..144 'foo1': fn foo1(u32) -> isize
588 154..155 '2': i32 624 154..155 '2': i32
589 159..163 'foo2': fn foo2(u32) -> isize 625 154..155 '2': i32
590 173..174 '_': i32 626 159..163 'foo2': fn foo2(u32) -> isize
591 178..182 'foo3': fn foo3(u32) -> isize 627 173..174 '_': i32
592 "### 628 178..182 'foo3': fn foo3(u32) -> isize
629 "]],
593 ); 630 );
594} 631}
595 632
596#[test] 633#[test]
597fn coerce_closure_to_fn_ptr() { 634fn coerce_closure_to_fn_ptr() {
598 assert_snapshot!( 635 check_infer_with_mismatches(
599 infer_with_mismatches(r#" 636 r"
600fn test() { 637 fn test() {
601 let f: fn(u32) -> isize = |x| { 1 }; 638 let f: fn(u32) -> isize = |x| { 1 };
602} 639 }
603"#, true), 640 ",
604 @r###" 641 expect![[r"
605 10..54 '{ ...1 }; }': () 642 10..54 '{ ...1 }; }': ()
606 20..21 'f': fn(u32) -> isize 643 20..21 'f': fn(u32) -> isize
607 42..51 '|x| { 1 }': |u32| -> isize 644 42..51 '|x| { 1 }': |u32| -> isize
608 43..44 'x': u32 645 43..44 'x': u32
609 46..51 '{ 1 }': isize 646 46..51 '{ 1 }': isize
610 48..49 '1': isize 647 48..49 '1': isize
611 "### 648 "]],
612 ); 649 );
613} 650}
614 651
615#[test] 652#[test]
616fn coerce_placeholder_ref() { 653fn coerce_placeholder_ref() {
617 // placeholders should unify, even behind references 654 // placeholders should unify, even behind references
618 assert_snapshot!( 655 check_infer_with_mismatches(
619 infer_with_mismatches(r#" 656 r"
620struct S<T> { t: T } 657 struct S<T> { t: T }
621impl<TT> S<TT> { 658 impl<TT> S<TT> {
622 fn get(&self) -> &TT { 659 fn get(&self) -> &TT {
623 &self.t 660 &self.t
624 } 661 }
625} 662 }
626"#, true), 663 ",
627 @r###" 664 expect![[r"
628 50..54 'self': &S<TT> 665 50..54 'self': &S<TT>
629 63..86 '{ ... }': &TT 666 63..86 '{ ... }': &TT
630 73..80 '&self.t': &TT 667 73..80 '&self.t': &TT
631 74..78 'self': &S<TT> 668 74..78 'self': &S<TT>
632 74..80 'self.t': TT 669 74..80 'self.t': TT
633 "### 670 "]],
634 ); 671 );
635} 672}
636 673
637#[test] 674#[test]
638fn coerce_unsize_array() { 675fn coerce_unsize_array() {
639 assert_snapshot!( 676 check_infer_with_mismatches(
640 infer_with_mismatches(r#" 677 r#"
641#[lang = "unsize"] 678 #[lang = "unsize"]
642pub trait Unsize<T> {} 679 pub trait Unsize<T> {}
643#[lang = "coerce_unsized"] 680 #[lang = "coerce_unsized"]
644pub trait CoerceUnsized<T> {} 681 pub trait CoerceUnsized<T> {}
645 682
646impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 683 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
647 684
648fn test() { 685 fn test() {
649 let f: &[usize] = &[1, 2, 3]; 686 let f: &[usize] = &[1, 2, 3];
650} 687 }
651"#, true), 688 "#,
652 @r###" 689 expect![[r"
653 161..198 '{ ... 3]; }': () 690 161..198 '{ ... 3]; }': ()
654 171..172 'f': &[usize] 691 171..172 'f': &[usize]
655 185..195 '&[1, 2, 3]': &[usize; _] 692 185..195 '&[1, 2, 3]': &[usize; _]
656 186..195 '[1, 2, 3]': [usize; _] 693 186..195 '[1, 2, 3]': [usize; _]
657 187..188 '1': usize 694 187..188 '1': usize
658 190..191 '2': usize 695 190..191 '2': usize
659 193..194 '3': usize 696 193..194 '3': usize
660 "### 697 "]],
661 ); 698 );
662} 699}
663 700
664#[test] 701#[test]
665fn coerce_unsize_trait_object_simple() { 702fn coerce_unsize_trait_object_simple() {
666 assert_snapshot!( 703 check_infer_with_mismatches(
667 infer_with_mismatches(r#" 704 r#"
668#[lang = "sized"] 705 #[lang = "sized"]
669pub trait Sized {} 706 pub trait Sized {}
670#[lang = "unsize"] 707 #[lang = "unsize"]
671pub trait Unsize<T> {} 708 pub trait Unsize<T> {}
672#[lang = "coerce_unsized"] 709 #[lang = "coerce_unsized"]
673pub trait CoerceUnsized<T> {} 710 pub trait CoerceUnsized<T> {}
674 711
675impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 712 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
676 713
677trait Foo<T, U> {} 714 trait Foo<T, U> {}
678trait Bar<U, T, X>: Foo<T, U> {} 715 trait Bar<U, T, X>: Foo<T, U> {}
679trait Baz<T, X>: Bar<usize, T, X> {} 716 trait Baz<T, X>: Bar<usize, T, X> {}
680 717
681struct S<T, X>; 718 struct S<T, X>;
682impl<T, X> Foo<T, usize> for S<T, X> {} 719 impl<T, X> Foo<T, usize> for S<T, X> {}
683impl<T, X> Bar<usize, T, X> for S<T, X> {} 720 impl<T, X> Bar<usize, T, X> for S<T, X> {}
684impl<T, X> Baz<T, X> for S<T, X> {} 721 impl<T, X> Baz<T, X> for S<T, X> {}
685 722
686fn test() { 723 fn test() {
687 let obj: &dyn Baz<i8, i16> = &S; 724 let obj: &dyn Baz<i8, i16> = &S;
688 let obj: &dyn Bar<_, i8, i16> = &S; 725 let obj: &dyn Bar<_, i8, i16> = &S;
689 let obj: &dyn Foo<i8, _> = &S; 726 let obj: &dyn Foo<i8, _> = &S;
690} 727 }
691"#, true), 728 "#,
692 @r###" 729 expect![[r"
693 424..539 '{ ... &S; }': () 730 424..539 '{ ... &S; }': ()
694 434..437 'obj': &dyn Baz<i8, i16> 731 434..437 'obj': &dyn Baz<i8, i16>
695 459..461 '&S': &S<i8, i16> 732 459..461 '&S': &S<i8, i16>
696 460..461 'S': S<i8, i16> 733 460..461 'S': S<i8, i16>
697 471..474 'obj': &dyn Bar<usize, i8, i16> 734 471..474 'obj': &dyn Bar<usize, i8, i16>
698 499..501 '&S': &S<i8, i16> 735 499..501 '&S': &S<i8, i16>
699 500..501 'S': S<i8, i16> 736 500..501 'S': S<i8, i16>
700 511..514 'obj': &dyn Foo<i8, usize> 737 511..514 'obj': &dyn Foo<i8, usize>
701 534..536 '&S': &S<i8, {unknown}> 738 534..536 '&S': &S<i8, {unknown}>
702 535..536 'S': S<i8, {unknown}> 739 535..536 'S': S<i8, {unknown}>
703 "### 740 "]],
704 ); 741 );
705} 742}
706 743
@@ -709,90 +746,90 @@ fn test() {
709// it. We used to support it, but Chalk doesn't. 746// it. We used to support it, but Chalk doesn't.
710#[ignore] 747#[ignore]
711fn coerce_unsize_trait_object_to_trait_object() { 748fn coerce_unsize_trait_object_to_trait_object() {
712 assert_snapshot!( 749 check_infer_with_mismatches(
713 infer_with_mismatches(r#" 750 r#"
714#[lang = "sized"] 751 #[lang = "sized"]
715pub trait Sized {} 752 pub trait Sized {}
716#[lang = "unsize"] 753 #[lang = "unsize"]
717pub trait Unsize<T> {} 754 pub trait Unsize<T> {}
718#[lang = "coerce_unsized"] 755 #[lang = "coerce_unsized"]
719pub trait CoerceUnsized<T> {} 756 pub trait CoerceUnsized<T> {}
720 757
721impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 758 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
722 759
723trait Foo<T, U> {} 760 trait Foo<T, U> {}
724trait Bar<U, T, X>: Foo<T, U> {} 761 trait Bar<U, T, X>: Foo<T, U> {}
725trait Baz<T, X>: Bar<usize, T, X> {} 762 trait Baz<T, X>: Bar<usize, T, X> {}
726 763
727struct S<T, X>; 764 struct S<T, X>;
728impl<T, X> Foo<T, usize> for S<T, X> {} 765 impl<T, X> Foo<T, usize> for S<T, X> {}
729impl<T, X> Bar<usize, T, X> for S<T, X> {} 766 impl<T, X> Bar<usize, T, X> for S<T, X> {}
730impl<T, X> Baz<T, X> for S<T, X> {} 767 impl<T, X> Baz<T, X> for S<T, X> {}
731 768
732fn test() { 769 fn test() {
733 let obj: &dyn Baz<i8, i16> = &S; 770 let obj: &dyn Baz<i8, i16> = &S;
734 let obj: &dyn Bar<_, _, _> = obj; 771 let obj: &dyn Bar<_, _, _> = obj;
735 let obj: &dyn Foo<_, _> = obj; 772 let obj: &dyn Foo<_, _> = obj;
736 let obj2: &dyn Baz<i8, i16> = &S; 773 let obj2: &dyn Baz<i8, i16> = &S;
737 let _: &dyn Foo<_, _> = obj2; 774 let _: &dyn Foo<_, _> = obj2;
738} 775 }
739"#, true), 776 "#,
740 @r###" 777 expect![[r"
741 424..609 '{ ...bj2; }': () 778 424..609 '{ ...bj2; }': ()
742 434..437 'obj': &dyn Baz<i8, i16> 779 434..437 'obj': &dyn Baz<i8, i16>
743 459..461 '&S': &S<i8, i16> 780 459..461 '&S': &S<i8, i16>
744 460..461 'S': S<i8, i16> 781 460..461 'S': S<i8, i16>
745 471..474 'obj': &dyn Bar<usize, i8, i16> 782 471..474 'obj': &dyn Bar<usize, i8, i16>
746 496..499 'obj': &dyn Baz<i8, i16> 783 496..499 'obj': &dyn Baz<i8, i16>
747 509..512 'obj': &dyn Foo<i8, usize> 784 509..512 'obj': &dyn Foo<i8, usize>
748 531..534 'obj': &dyn Bar<usize, i8, i16> 785 531..534 'obj': &dyn Bar<usize, i8, i16>
749 544..548 'obj2': &dyn Baz<i8, i16> 786 544..548 'obj2': &dyn Baz<i8, i16>
750 570..572 '&S': &S<i8, i16> 787 570..572 '&S': &S<i8, i16>
751 571..572 'S': S<i8, i16> 788 571..572 'S': S<i8, i16>
752 582..583 '_': &dyn Foo<i8, usize> 789 582..583 '_': &dyn Foo<i8, usize>
753 602..606 'obj2': &dyn Baz<i8, i16> 790 602..606 'obj2': &dyn Baz<i8, i16>
754 "### 791 "]],
755 ); 792 );
756} 793}
757 794
758#[test] 795#[test]
759fn coerce_unsize_super_trait_cycle() { 796fn coerce_unsize_super_trait_cycle() {
760 assert_snapshot!( 797 check_infer_with_mismatches(
761 infer_with_mismatches(r#" 798 r#"
762#[lang = "sized"] 799 #[lang = "sized"]
763pub trait Sized {} 800 pub trait Sized {}
764#[lang = "unsize"] 801 #[lang = "unsize"]
765pub trait Unsize<T> {} 802 pub trait Unsize<T> {}
766#[lang = "coerce_unsized"] 803 #[lang = "coerce_unsized"]
767pub trait CoerceUnsized<T> {} 804 pub trait CoerceUnsized<T> {}
768 805
769impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 806 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
770 807
771trait A {} 808 trait A {}
772trait B: C + A {} 809 trait B: C + A {}
773trait C: B {} 810 trait C: B {}
774trait D: C 811 trait D: C
775 812
776struct S; 813 struct S;
777impl A for S {} 814 impl A for S {}
778impl B for S {} 815 impl B for S {}
779impl C for S {} 816 impl C for S {}
780impl D for S {} 817 impl D for S {}
781 818
782fn test() { 819 fn test() {
783 let obj: &dyn D = &S; 820 let obj: &dyn D = &S;
784 let obj: &dyn A = &S; 821 let obj: &dyn A = &S;
785} 822 }
786"#, true), 823 "#,
787 @r###" 824 expect![[r"
788 328..383 '{ ... &S; }': () 825 328..383 '{ ... &S; }': ()
789 338..341 'obj': &dyn D 826 338..341 'obj': &dyn D
790 352..354 '&S': &S 827 352..354 '&S': &S
791 353..354 'S': S 828 353..354 'S': S
792 364..367 'obj': &dyn A 829 364..367 'obj': &dyn A
793 378..380 '&S': &S 830 378..380 '&S': &S
794 379..380 'S': S 831 379..380 'S': S
795 "### 832 "]],
796 ); 833 );
797} 834}
798 835
@@ -801,24 +838,24 @@ fn test() {
801fn coerce_unsize_generic() { 838fn coerce_unsize_generic() {
802 // FIXME: Implement this 839 // FIXME: Implement this
803 // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions 840 // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
804 assert_snapshot!( 841 check_infer_with_mismatches(
805 infer_with_mismatches(r#" 842 r#"
806#[lang = "unsize"] 843 #[lang = "unsize"]
807pub trait Unsize<T> {} 844 pub trait Unsize<T> {}
808#[lang = "coerce_unsized"] 845 #[lang = "coerce_unsized"]
809pub trait CoerceUnsized<T> {} 846 pub trait CoerceUnsized<T> {}
810 847
811impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 848 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
812 849
813struct Foo<T> { t: T }; 850 struct Foo<T> { t: T };
814struct Bar<T>(Foo<T>); 851 struct Bar<T>(Foo<T>);
815 852
816fn test() { 853 fn test() {
817 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; 854 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
818 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); 855 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
819} 856 }
820"#, true), 857 "#,
821 @r###" 858 expect![[r"
822 "### 859 "]],
823 ); 860 );
824} 861}
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs
index 64d421d40..49538b572 100644
--- a/crates/ra_hir_ty/src/tests/never_type.rs
+++ b/crates/ra_hir_ty/src/tests/never_type.rs
@@ -1,6 +1,6 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer_with_mismatches}; 3use super::{check_infer_with_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn infer_never1() { 6fn infer_never1() {
@@ -240,173 +240,170 @@ fn test(a: i32) {
240 240
241#[test] 241#[test]
242fn diverging_expression_1() { 242fn diverging_expression_1() {
243 let t = infer_with_mismatches( 243 check_infer_with_mismatches(
244 r#" 244 r"
245//- /main.rs 245 //- /main.rs
246fn test1() { 246 fn test1() {
247 let x: u32 = return; 247 let x: u32 = return;
248} 248 }
249fn test2() { 249 fn test2() {
250 let x: u32 = { return; }; 250 let x: u32 = { return; };
251} 251 }
252fn test3() { 252 fn test3() {
253 let x: u32 = loop {}; 253 let x: u32 = loop {};
254} 254 }
255fn test4() { 255 fn test4() {
256 let x: u32 = { loop {} }; 256 let x: u32 = { loop {} };
257} 257 }
258fn test5() { 258 fn test5() {
259 let x: u32 = { if true { loop {}; } else { loop {}; } }; 259 let x: u32 = { if true { loop {}; } else { loop {}; } };
260} 260 }
261fn test6() { 261 fn test6() {
262 let x: u32 = { let y: u32 = { loop {}; }; }; 262 let x: u32 = { let y: u32 = { loop {}; }; };
263} 263 }
264"#, 264 ",
265 true, 265 expect![[r"
266 11..39 '{ ...urn; }': ()
267 21..22 'x': u32
268 30..36 'return': !
269 51..84 '{ ...; }; }': ()
270 61..62 'x': u32
271 70..81 '{ return; }': u32
272 72..78 'return': !
273 96..125 '{ ... {}; }': ()
274 106..107 'x': u32
275 115..122 'loop {}': !
276 120..122 '{}': ()
277 137..170 '{ ...} }; }': ()
278 147..148 'x': u32
279 156..167 '{ loop {} }': u32
280 158..165 'loop {}': !
281 163..165 '{}': ()
282 182..246 '{ ...} }; }': ()
283 192..193 'x': u32
284 201..243 '{ if t...}; } }': u32
285 203..241 'if tru... {}; }': u32
286 206..210 'true': bool
287 211..223 '{ loop {}; }': u32
288 213..220 'loop {}': !
289 218..220 '{}': ()
290 229..241 '{ loop {}; }': u32
291 231..238 'loop {}': !
292 236..238 '{}': ()
293 258..310 '{ ...; }; }': ()
294 268..269 'x': u32
295 277..307 '{ let ...; }; }': u32
296 283..284 'y': u32
297 292..304 '{ loop {}; }': u32
298 294..301 'loop {}': !
299 299..301 '{}': ()
300 "]],
266 ); 301 );
267 assert_snapshot!(t, @r###"
268 11..39 '{ ...urn; }': ()
269 21..22 'x': u32
270 30..36 'return': !
271 51..84 '{ ...; }; }': ()
272 61..62 'x': u32
273 70..81 '{ return; }': u32
274 72..78 'return': !
275 96..125 '{ ... {}; }': ()
276 106..107 'x': u32
277 115..122 'loop {}': !
278 120..122 '{}': ()
279 137..170 '{ ...} }; }': ()
280 147..148 'x': u32
281 156..167 '{ loop {} }': u32
282 158..165 'loop {}': !
283 163..165 '{}': ()
284 182..246 '{ ...} }; }': ()
285 192..193 'x': u32
286 201..243 '{ if t...}; } }': u32
287 203..241 'if tru... {}; }': u32
288 206..210 'true': bool
289 211..223 '{ loop {}; }': u32
290 213..220 'loop {}': !
291 218..220 '{}': ()
292 229..241 '{ loop {}; }': u32
293 231..238 'loop {}': !
294 236..238 '{}': ()
295 258..310 '{ ...; }; }': ()
296 268..269 'x': u32
297 277..307 '{ let ...; }; }': u32
298 283..284 'y': u32
299 292..304 '{ loop {}; }': u32
300 294..301 'loop {}': !
301 299..301 '{}': ()
302 "###);
303} 302}
304 303
305#[test] 304#[test]
306fn diverging_expression_2() { 305fn diverging_expression_2() {
307 let t = infer_with_mismatches( 306 check_infer_with_mismatches(
308 r#" 307 r#"
309//- /main.rs 308 //- /main.rs
310fn test1() { 309 fn test1() {
311 // should give type mismatch 310 // should give type mismatch
312 let x: u32 = { loop {}; "foo" }; 311 let x: u32 = { loop {}; "foo" };
313} 312 }
314"#, 313 "#,
315 true, 314 expect![[r#"
315 11..84 '{ ..." }; }': ()
316 54..55 'x': u32
317 63..81 '{ loop...foo" }': &str
318 65..72 'loop {}': !
319 70..72 '{}': ()
320 74..79 '"foo"': &str
321 63..81: expected u32, got &str
322 74..79: expected u32, got &str
323 "#]],
316 ); 324 );
317 assert_snapshot!(t, @r###"
318 11..84 '{ ..." }; }': ()
319 54..55 'x': u32
320 63..81 '{ loop...foo" }': &str
321 65..72 'loop {}': !
322 70..72 '{}': ()
323 74..79 '"foo"': &str
324 63..81: expected u32, got &str
325 74..79: expected u32, got &str
326 "###);
327} 325}
328 326
329#[test] 327#[test]
330fn diverging_expression_3_break() { 328fn diverging_expression_3_break() {
331 let t = infer_with_mismatches( 329 check_infer_with_mismatches(
332 r#" 330 r"
333//- /main.rs 331 //- /main.rs
334fn test1() { 332 fn test1() {
335 // should give type mismatch 333 // should give type mismatch
336 let x: u32 = { loop { break; } }; 334 let x: u32 = { loop { break; } };
337} 335 }
338fn test2() { 336 fn test2() {
339 // should give type mismatch 337 // should give type mismatch
340 let x: u32 = { for a in b { break; }; }; 338 let x: u32 = { for a in b { break; }; };
341 // should give type mismatch as well 339 // should give type mismatch as well
342 let x: u32 = { for a in b {}; }; 340 let x: u32 = { for a in b {}; };
343 // should give type mismatch as well 341 // should give type mismatch as well
344 let x: u32 = { for a in b { return; }; }; 342 let x: u32 = { for a in b { return; }; };
345} 343 }
346fn test3() { 344 fn test3() {
347 // should give type mismatch 345 // should give type mismatch
348 let x: u32 = { while true { break; }; }; 346 let x: u32 = { while true { break; }; };
349 // should give type mismatch as well -- there's an implicit break, even if it's never hit 347 // should give type mismatch as well -- there's an implicit break, even if it's never hit
350 let x: u32 = { while true {}; }; 348 let x: u32 = { while true {}; };
351 // should give type mismatch as well 349 // should give type mismatch as well
352 let x: u32 = { while true { return; }; }; 350 let x: u32 = { while true { return; }; };
353} 351 }
354"#, 352 ",
355 true, 353 expect![[r"
354 11..85 '{ ...} }; }': ()
355 54..55 'x': u32
356 63..82 '{ loop...k; } }': ()
357 65..80 'loop { break; }': ()
358 70..80 '{ break; }': ()
359 72..77 'break': !
360 63..82: expected u32, got ()
361 65..80: expected u32, got ()
362 97..343 '{ ...; }; }': ()
363 140..141 'x': u32
364 149..175 '{ for ...; }; }': ()
365 151..172 'for a ...eak; }': ()
366 155..156 'a': {unknown}
367 160..161 'b': {unknown}
368 162..172 '{ break; }': ()
369 164..169 'break': !
370 226..227 'x': u32
371 235..253 '{ for ... {}; }': ()
372 237..250 'for a in b {}': ()
373 241..242 'a': {unknown}
374 246..247 'b': {unknown}
375 248..250 '{}': ()
376 304..305 'x': u32
377 313..340 '{ for ...; }; }': ()
378 315..337 'for a ...urn; }': ()
379 319..320 'a': {unknown}
380 324..325 'b': {unknown}
381 326..337 '{ return; }': ()
382 328..334 'return': !
383 149..175: expected u32, got ()
384 235..253: expected u32, got ()
385 313..340: expected u32, got ()
386 355..654 '{ ...; }; }': ()
387 398..399 'x': u32
388 407..433 '{ whil...; }; }': ()
389 409..430 'while ...eak; }': ()
390 415..419 'true': bool
391 420..430 '{ break; }': ()
392 422..427 'break': !
393 537..538 'x': u32
394 546..564 '{ whil... {}; }': ()
395 548..561 'while true {}': ()
396 554..558 'true': bool
397 559..561 '{}': ()
398 615..616 'x': u32
399 624..651 '{ whil...; }; }': ()
400 626..648 'while ...urn; }': ()
401 632..636 'true': bool
402 637..648 '{ return; }': ()
403 639..645 'return': !
404 407..433: expected u32, got ()
405 546..564: expected u32, got ()
406 624..651: expected u32, got ()
407 "]],
356 ); 408 );
357 assert_snapshot!(t, @r###"
358 11..85 '{ ...} }; }': ()
359 54..55 'x': u32
360 63..82 '{ loop...k; } }': ()
361 65..80 'loop { break; }': ()
362 70..80 '{ break; }': ()
363 72..77 'break': !
364 63..82: expected u32, got ()
365 65..80: expected u32, got ()
366 97..343 '{ ...; }; }': ()
367 140..141 'x': u32
368 149..175 '{ for ...; }; }': ()
369 151..172 'for a ...eak; }': ()
370 155..156 'a': {unknown}
371 160..161 'b': {unknown}
372 162..172 '{ break; }': ()
373 164..169 'break': !
374 226..227 'x': u32
375 235..253 '{ for ... {}; }': ()
376 237..250 'for a in b {}': ()
377 241..242 'a': {unknown}
378 246..247 'b': {unknown}
379 248..250 '{}': ()
380 304..305 'x': u32
381 313..340 '{ for ...; }; }': ()
382 315..337 'for a ...urn; }': ()
383 319..320 'a': {unknown}
384 324..325 'b': {unknown}
385 326..337 '{ return; }': ()
386 328..334 'return': !
387 149..175: expected u32, got ()
388 235..253: expected u32, got ()
389 313..340: expected u32, got ()
390 355..654 '{ ...; }; }': ()
391 398..399 'x': u32
392 407..433 '{ whil...; }; }': ()
393 409..430 'while ...eak; }': ()
394 415..419 'true': bool
395 420..430 '{ break; }': ()
396 422..427 'break': !
397 537..538 'x': u32
398 546..564 '{ whil... {}; }': ()
399 548..561 'while true {}': ()
400 554..558 'true': bool
401 559..561 '{}': ()
402 615..616 'x': u32
403 624..651 '{ whil...; }; }': ()
404 626..648 'while ...urn; }': ()
405 632..636 'true': bool
406 637..648 '{ return; }': ()
407 639..645 'return': !
408 407..433: expected u32, got ()
409 546..564: expected u32, got ()
410 624..651: expected u32, got ()
411 "###);
412} 409}