diff options
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 1417 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/never_type.rs | 315 |
3 files changed, 896 insertions, 849 deletions
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 | ||
11 | use std::sync::Arc; | 11 | use std::sync::Arc; |
12 | 12 | ||
13 | use expect::Expect; | ||
13 | use hir_def::{ | 14 | use 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 | |||
349 | fn 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 | |||
355 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::infer_with_mismatches; | 4 | use super::{check_infer, check_infer_with_mismatches}; |
5 | |||
6 | // Infer with some common definitions and impls. | ||
7 | fn 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] |
25 | fn infer_block_expr_type_mismatch() { | 7 | fn infer_block_expr_type_mismatch() { |
26 | assert_snapshot!( | 8 | check_infer( |
27 | infer(r#" | 9 | r" |
28 | fn 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] |
41 | fn coerce_places() { | 24 | fn coerce_places() { |
42 | assert_snapshot!( | 25 | check_infer( |
43 | infer(r#" | 26 | r#" |
44 | struct S<T> { a: T } | 27 | struct S<T> { a: T } |
45 | 28 | ||
46 | fn f<T>(_: &[T]) -> T { loop {} } | 29 | fn f<T>(_: &[T]) -> T { loop {} } |
47 | fn g<T>(_: S<&[T]>) -> T { loop {} } | 30 | fn g<T>(_: S<&[T]>) -> T { loop {} } |
48 | 31 | ||
49 | fn gen<T>() -> *mut [T; 2] { loop {} } | 32 | fn gen<T>() -> *mut [T; 2] { loop {} } |
50 | fn test1<U>() -> *mut [U] { | 33 | fn test1<U>() -> *mut [U] { |
51 | gen() | 34 | gen() |
52 | } | 35 | } |
53 | 36 | ||
54 | fn 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] |
116 | fn infer_let_stmt_coerce() { | 109 | fn infer_let_stmt_coerce() { |
117 | assert_snapshot!( | 110 | check_infer( |
118 | infer(r#" | 111 | r" |
119 | fn 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] |
138 | fn infer_custom_coerce_unsized() { | 132 | fn infer_custom_coerce_unsized() { |
139 | assert_snapshot!( | 133 | check_infer( |
140 | infer(r#" | 134 | r#" |
141 | struct A<T: ?Sized>(*const T); | 135 | struct A<T: ?Sized>(*const T); |
142 | struct B<T: ?Sized>(*const T); | 136 | struct B<T: ?Sized>(*const T); |
143 | struct C<T: ?Sized> { inner: *const T } | 137 | struct C<T: ?Sized> { inner: *const T } |
144 | 138 | ||
145 | impl<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> {} |
146 | impl<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 | ||
148 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } | 142 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } |
149 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } | 143 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } |
150 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } | 144 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } |
151 | 145 | ||
152 | fn 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] |
189 | fn infer_if_coerce() { | 194 | fn infer_if_coerce() { |
190 | assert_snapshot!( | 195 | check_infer( |
191 | infer(r#" | 196 | r#" |
192 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 197 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
193 | fn 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] |
225 | fn infer_if_else_coerce() { | 236 | fn infer_if_else_coerce() { |
226 | assert_snapshot!( | 237 | check_infer( |
227 | infer(r#" | 238 | r#" |
228 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 239 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
229 | fn 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] |
261 | fn infer_match_first_coerce() { | 282 | fn infer_match_first_coerce() { |
262 | assert_snapshot!( | 283 | check_infer( |
263 | infer(r#" | 284 | r#" |
264 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 285 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
265 | fn 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] |
304 | fn infer_match_second_coerce() { | 330 | fn infer_match_second_coerce() { |
305 | assert_snapshot!( | 331 | check_infer( |
306 | infer(r#" | 332 | r#" |
307 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 333 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
308 | fn 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) { | |||
347 | fn coerce_merge_one_by_one1() { | 383 | fn 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" |
352 | fn 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] |
385 | fn return_coerce_unknown() { | 421 | fn return_coerce_unknown() { |
386 | assert_snapshot!( | 422 | check_infer_with_mismatches( |
387 | infer_with_mismatches(r#" | 423 | r" |
388 | fn 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] |
401 | fn coerce_autoderef() { | 437 | fn coerce_autoderef() { |
402 | assert_snapshot!( | 438 | check_infer_with_mismatches( |
403 | infer_with_mismatches(r#" | 439 | r" |
404 | struct Foo; | 440 | struct Foo; |
405 | fn takes_ref_foo(x: &Foo) {} | 441 | fn takes_ref_foo(x: &Foo) {} |
406 | fn 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] |
436 | fn coerce_autoderef_generic() { | 472 | fn coerce_autoderef_generic() { |
437 | assert_snapshot!( | 473 | check_infer_with_mismatches( |
438 | infer_with_mismatches(r#" | 474 | r" |
439 | struct Foo; | 475 | struct Foo; |
440 | fn takes_ref<T>(x: &T) -> T { *x } | 476 | fn takes_ref<T>(x: &T) -> T { *x } |
441 | fn 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] |
473 | fn coerce_autoderef_block() { | 509 | fn coerce_autoderef_block() { |
474 | assert_snapshot!( | 510 | check_infer_with_mismatches( |
475 | infer_with_mismatches(r#" | 511 | r#" |
476 | struct String {} | 512 | struct String {} |
477 | #[lang = "deref"] | 513 | #[lang = "deref"] |
478 | trait Deref { type Target; } | 514 | trait Deref { type Target; } |
479 | impl Deref for String { type Target = str; } | 515 | impl Deref for String { type Target = str; } |
480 | fn takes_ref_str(x: &str) {} | 516 | fn takes_ref_str(x: &str) {} |
481 | fn returns_string() -> String { loop {} } | 517 | fn returns_string() -> String { loop {} } |
482 | fn 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] |
504 | fn closure_return_coerce() { | 540 | fn closure_return_coerce() { |
505 | assert_snapshot!( | 541 | check_infer_with_mismatches( |
506 | infer_with_mismatches(r#" | 542 | r" |
507 | fn 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] |
535 | fn coerce_fn_item_to_fn_ptr() { | 571 | fn coerce_fn_item_to_fn_ptr() { |
536 | assert_snapshot!( | 572 | check_infer_with_mismatches( |
537 | infer_with_mismatches(r#" | 573 | r" |
538 | fn foo(x: u32) -> isize { 1 } | 574 | fn foo(x: u32) -> isize { 1 } |
539 | fn 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] |
555 | fn coerce_fn_items_in_match_arms() { | 591 | fn 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( |
559 | fn foo1(x: u32) -> isize { 1 } | 595 | r" |
560 | fn foo2(x: u32) -> isize { 2 } | 596 | fn foo1(x: u32) -> isize { 1 } |
561 | fn foo3(x: u32) -> isize { 3 } | 597 | fn foo2(x: u32) -> isize { 2 } |
562 | fn 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] |
597 | fn coerce_closure_to_fn_ptr() { | 634 | fn coerce_closure_to_fn_ptr() { |
598 | assert_snapshot!( | 635 | check_infer_with_mismatches( |
599 | infer_with_mismatches(r#" | 636 | r" |
600 | fn 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] |
616 | fn coerce_placeholder_ref() { | 653 | fn 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" |
620 | struct S<T> { t: T } | 657 | struct S<T> { t: T } |
621 | impl<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] |
638 | fn coerce_unsize_array() { | 675 | fn coerce_unsize_array() { |
639 | assert_snapshot!( | 676 | check_infer_with_mismatches( |
640 | infer_with_mismatches(r#" | 677 | r#" |
641 | #[lang = "unsize"] | 678 | #[lang = "unsize"] |
642 | pub trait Unsize<T> {} | 679 | pub trait Unsize<T> {} |
643 | #[lang = "coerce_unsized"] | 680 | #[lang = "coerce_unsized"] |
644 | pub trait CoerceUnsized<T> {} | 681 | pub trait CoerceUnsized<T> {} |
645 | 682 | ||
646 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 683 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
647 | 684 | ||
648 | fn 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] |
665 | fn coerce_unsize_trait_object_simple() { | 702 | fn 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"] |
669 | pub trait Sized {} | 706 | pub trait Sized {} |
670 | #[lang = "unsize"] | 707 | #[lang = "unsize"] |
671 | pub trait Unsize<T> {} | 708 | pub trait Unsize<T> {} |
672 | #[lang = "coerce_unsized"] | 709 | #[lang = "coerce_unsized"] |
673 | pub trait CoerceUnsized<T> {} | 710 | pub trait CoerceUnsized<T> {} |
674 | 711 | ||
675 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 712 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
676 | 713 | ||
677 | trait Foo<T, U> {} | 714 | trait Foo<T, U> {} |
678 | trait Bar<U, T, X>: Foo<T, U> {} | 715 | trait Bar<U, T, X>: Foo<T, U> {} |
679 | trait Baz<T, X>: Bar<usize, T, X> {} | 716 | trait Baz<T, X>: Bar<usize, T, X> {} |
680 | 717 | ||
681 | struct S<T, X>; | 718 | struct S<T, X>; |
682 | impl<T, X> Foo<T, usize> for S<T, X> {} | 719 | impl<T, X> Foo<T, usize> for S<T, X> {} |
683 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | 720 | impl<T, X> Bar<usize, T, X> for S<T, X> {} |
684 | impl<T, X> Baz<T, X> for S<T, X> {} | 721 | impl<T, X> Baz<T, X> for S<T, X> {} |
685 | 722 | ||
686 | fn 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] |
711 | fn coerce_unsize_trait_object_to_trait_object() { | 748 | fn 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"] |
715 | pub trait Sized {} | 752 | pub trait Sized {} |
716 | #[lang = "unsize"] | 753 | #[lang = "unsize"] |
717 | pub trait Unsize<T> {} | 754 | pub trait Unsize<T> {} |
718 | #[lang = "coerce_unsized"] | 755 | #[lang = "coerce_unsized"] |
719 | pub trait CoerceUnsized<T> {} | 756 | pub trait CoerceUnsized<T> {} |
720 | 757 | ||
721 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 758 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
722 | 759 | ||
723 | trait Foo<T, U> {} | 760 | trait Foo<T, U> {} |
724 | trait Bar<U, T, X>: Foo<T, U> {} | 761 | trait Bar<U, T, X>: Foo<T, U> {} |
725 | trait Baz<T, X>: Bar<usize, T, X> {} | 762 | trait Baz<T, X>: Bar<usize, T, X> {} |
726 | 763 | ||
727 | struct S<T, X>; | 764 | struct S<T, X>; |
728 | impl<T, X> Foo<T, usize> for S<T, X> {} | 765 | impl<T, X> Foo<T, usize> for S<T, X> {} |
729 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | 766 | impl<T, X> Bar<usize, T, X> for S<T, X> {} |
730 | impl<T, X> Baz<T, X> for S<T, X> {} | 767 | impl<T, X> Baz<T, X> for S<T, X> {} |
731 | 768 | ||
732 | fn 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] |
759 | fn coerce_unsize_super_trait_cycle() { | 796 | fn 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"] |
763 | pub trait Sized {} | 800 | pub trait Sized {} |
764 | #[lang = "unsize"] | 801 | #[lang = "unsize"] |
765 | pub trait Unsize<T> {} | 802 | pub trait Unsize<T> {} |
766 | #[lang = "coerce_unsized"] | 803 | #[lang = "coerce_unsized"] |
767 | pub trait CoerceUnsized<T> {} | 804 | pub trait CoerceUnsized<T> {} |
768 | 805 | ||
769 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 806 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
770 | 807 | ||
771 | trait A {} | 808 | trait A {} |
772 | trait B: C + A {} | 809 | trait B: C + A {} |
773 | trait C: B {} | 810 | trait C: B {} |
774 | trait D: C | 811 | trait D: C |
775 | 812 | ||
776 | struct S; | 813 | struct S; |
777 | impl A for S {} | 814 | impl A for S {} |
778 | impl B for S {} | 815 | impl B for S {} |
779 | impl C for S {} | 816 | impl C for S {} |
780 | impl D for S {} | 817 | impl D for S {} |
781 | 818 | ||
782 | fn 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() { | |||
801 | fn coerce_unsize_generic() { | 838 | fn 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"] |
807 | pub trait Unsize<T> {} | 844 | pub trait Unsize<T> {} |
808 | #[lang = "coerce_unsized"] | 845 | #[lang = "coerce_unsized"] |
809 | pub trait CoerceUnsized<T> {} | 846 | pub trait CoerceUnsized<T> {} |
810 | 847 | ||
811 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 848 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
812 | 849 | ||
813 | struct Foo<T> { t: T }; | 850 | struct Foo<T> { t: T }; |
814 | struct Bar<T>(Foo<T>); | 851 | struct Bar<T>(Foo<T>); |
815 | 852 | ||
816 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer_with_mismatches}; | 3 | use super::{check_infer_with_mismatches, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_never1() { | 6 | fn infer_never1() { |
@@ -240,173 +240,170 @@ fn test(a: i32) { | |||
240 | 240 | ||
241 | #[test] | 241 | #[test] |
242 | fn diverging_expression_1() { | 242 | fn diverging_expression_1() { |
243 | let t = infer_with_mismatches( | 243 | check_infer_with_mismatches( |
244 | r#" | 244 | r" |
245 | //- /main.rs | 245 | //- /main.rs |
246 | fn test1() { | 246 | fn test1() { |
247 | let x: u32 = return; | 247 | let x: u32 = return; |
248 | } | 248 | } |
249 | fn test2() { | 249 | fn test2() { |
250 | let x: u32 = { return; }; | 250 | let x: u32 = { return; }; |
251 | } | 251 | } |
252 | fn test3() { | 252 | fn test3() { |
253 | let x: u32 = loop {}; | 253 | let x: u32 = loop {}; |
254 | } | 254 | } |
255 | fn test4() { | 255 | fn test4() { |
256 | let x: u32 = { loop {} }; | 256 | let x: u32 = { loop {} }; |
257 | } | 257 | } |
258 | fn test5() { | 258 | fn test5() { |
259 | let x: u32 = { if true { loop {}; } else { loop {}; } }; | 259 | let x: u32 = { if true { loop {}; } else { loop {}; } }; |
260 | } | 260 | } |
261 | fn 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] |
306 | fn diverging_expression_2() { | 305 | fn diverging_expression_2() { |
307 | let t = infer_with_mismatches( | 306 | check_infer_with_mismatches( |
308 | r#" | 307 | r#" |
309 | //- /main.rs | 308 | //- /main.rs |
310 | fn 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] |
330 | fn diverging_expression_3_break() { | 328 | fn 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 |
334 | fn 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 | } |
338 | fn 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 | } |
346 | fn 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 | } |