diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 1386 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 620 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 1150 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/never_type.rs | 315 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/patterns.rs | 1102 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 1137 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 3398 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 3460 |
8 files changed, 6409 insertions, 6159 deletions
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 136d28a91..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,405 +383,453 @@ 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() { | 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<_, _, _> = obj; | 725 | let obj: &dyn Bar<_, i8, i16> = &S; |
689 | let obj: &dyn Foo<_, _> = obj; | 726 | let obj: &dyn Foo<i8, _> = &S; |
690 | let obj2: &dyn Baz<i8, i16> = &S; | 727 | } |
691 | let _: &dyn Foo<_, _> = obj2; | 728 | "#, |
729 | expect![[r" | ||
730 | 424..539 '{ ... &S; }': () | ||
731 | 434..437 'obj': &dyn Baz<i8, i16> | ||
732 | 459..461 '&S': &S<i8, i16> | ||
733 | 460..461 'S': S<i8, i16> | ||
734 | 471..474 'obj': &dyn Bar<usize, i8, i16> | ||
735 | 499..501 '&S': &S<i8, i16> | ||
736 | 500..501 'S': S<i8, i16> | ||
737 | 511..514 'obj': &dyn Foo<i8, usize> | ||
738 | 534..536 '&S': &S<i8, {unknown}> | ||
739 | 535..536 'S': S<i8, {unknown}> | ||
740 | "]], | ||
741 | ); | ||
692 | } | 742 | } |
693 | "#, true), | 743 | |
694 | @r###" | 744 | #[test] |
695 | 424..609 '{ ...bj2; }': () | 745 | // The rust reference says this should be possible, but rustc doesn't implement |
696 | 434..437 'obj': &dyn Baz<i8, i16> | 746 | // it. We used to support it, but Chalk doesn't. |
697 | 459..461 '&S': &S<i8, i16> | 747 | #[ignore] |
698 | 460..461 'S': S<i8, i16> | 748 | fn coerce_unsize_trait_object_to_trait_object() { |
699 | 471..474 'obj': &dyn Bar<usize, i8, i16> | 749 | check_infer_with_mismatches( |
700 | 496..499 'obj': &dyn Baz<i8, i16> | 750 | r#" |
701 | 509..512 'obj': &dyn Foo<i8, usize> | 751 | #[lang = "sized"] |
702 | 531..534 'obj': &dyn Bar<usize, i8, i16> | 752 | pub trait Sized {} |
703 | 544..548 'obj2': &dyn Baz<i8, i16> | 753 | #[lang = "unsize"] |
704 | 570..572 '&S': &S<i8, i16> | 754 | pub trait Unsize<T> {} |
705 | 571..572 'S': S<i8, i16> | 755 | #[lang = "coerce_unsized"] |
706 | 582..583 '_': &dyn Foo<i8, usize> | 756 | pub trait CoerceUnsized<T> {} |
707 | 602..606 'obj2': &dyn Baz<i8, i16> | 757 | |
708 | "### | 758 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
759 | |||
760 | trait Foo<T, U> {} | ||
761 | trait Bar<U, T, X>: Foo<T, U> {} | ||
762 | trait Baz<T, X>: Bar<usize, T, X> {} | ||
763 | |||
764 | struct S<T, X>; | ||
765 | impl<T, X> Foo<T, usize> for S<T, X> {} | ||
766 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | ||
767 | impl<T, X> Baz<T, X> for S<T, X> {} | ||
768 | |||
769 | fn test() { | ||
770 | let obj: &dyn Baz<i8, i16> = &S; | ||
771 | let obj: &dyn Bar<_, _, _> = obj; | ||
772 | let obj: &dyn Foo<_, _> = obj; | ||
773 | let obj2: &dyn Baz<i8, i16> = &S; | ||
774 | let _: &dyn Foo<_, _> = obj2; | ||
775 | } | ||
776 | "#, | ||
777 | expect![[r" | ||
778 | 424..609 '{ ...bj2; }': () | ||
779 | 434..437 'obj': &dyn Baz<i8, i16> | ||
780 | 459..461 '&S': &S<i8, i16> | ||
781 | 460..461 'S': S<i8, i16> | ||
782 | 471..474 'obj': &dyn Bar<usize, i8, i16> | ||
783 | 496..499 'obj': &dyn Baz<i8, i16> | ||
784 | 509..512 'obj': &dyn Foo<i8, usize> | ||
785 | 531..534 'obj': &dyn Bar<usize, i8, i16> | ||
786 | 544..548 'obj2': &dyn Baz<i8, i16> | ||
787 | 570..572 '&S': &S<i8, i16> | ||
788 | 571..572 'S': S<i8, i16> | ||
789 | 582..583 '_': &dyn Foo<i8, usize> | ||
790 | 602..606 'obj2': &dyn Baz<i8, i16> | ||
791 | "]], | ||
709 | ); | 792 | ); |
710 | } | 793 | } |
711 | 794 | ||
712 | #[test] | 795 | #[test] |
713 | fn coerce_unsize_super_trait_cycle() { | 796 | fn coerce_unsize_super_trait_cycle() { |
714 | assert_snapshot!( | 797 | check_infer_with_mismatches( |
715 | infer_with_mismatches(r#" | 798 | r#" |
716 | #[lang = "sized"] | 799 | #[lang = "sized"] |
717 | pub trait Sized {} | 800 | pub trait Sized {} |
718 | #[lang = "unsize"] | 801 | #[lang = "unsize"] |
719 | pub trait Unsize<T> {} | 802 | pub trait Unsize<T> {} |
720 | #[lang = "coerce_unsized"] | 803 | #[lang = "coerce_unsized"] |
721 | pub trait CoerceUnsized<T> {} | 804 | pub trait CoerceUnsized<T> {} |
722 | 805 | ||
723 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 806 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
724 | 807 | ||
725 | trait A {} | 808 | trait A {} |
726 | trait B: C + A {} | 809 | trait B: C + A {} |
727 | trait C: B {} | 810 | trait C: B {} |
728 | trait D: C | 811 | trait D: C |
729 | 812 | ||
730 | struct S; | 813 | struct S; |
731 | impl A for S {} | 814 | impl A for S {} |
732 | impl B for S {} | 815 | impl B for S {} |
733 | impl C for S {} | 816 | impl C for S {} |
734 | impl D for S {} | 817 | impl D for S {} |
735 | 818 | ||
736 | fn test() { | 819 | fn test() { |
737 | let obj: &dyn D = &S; | 820 | let obj: &dyn D = &S; |
738 | let obj: &dyn A = obj; | 821 | let obj: &dyn A = &S; |
739 | } | 822 | } |
740 | "#, true), | 823 | "#, |
741 | @r###" | 824 | expect![[r" |
742 | 328..384 '{ ...obj; }': () | 825 | 328..383 '{ ... &S; }': () |
743 | 338..341 'obj': &dyn D | 826 | 338..341 'obj': &dyn D |
744 | 352..354 '&S': &S | 827 | 352..354 '&S': &S |
745 | 353..354 'S': S | 828 | 353..354 'S': S |
746 | 364..367 'obj': &dyn A | 829 | 364..367 'obj': &dyn A |
747 | 378..381 'obj': &dyn D | 830 | 378..380 '&S': &S |
748 | "### | 831 | 379..380 'S': S |
832 | "]], | ||
749 | ); | 833 | ); |
750 | } | 834 | } |
751 | 835 | ||
@@ -754,24 +838,24 @@ fn test() { | |||
754 | fn coerce_unsize_generic() { | 838 | fn coerce_unsize_generic() { |
755 | // FIXME: Implement this | 839 | // FIXME: Implement this |
756 | // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions | 840 | // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions |
757 | assert_snapshot!( | 841 | check_infer_with_mismatches( |
758 | infer_with_mismatches(r#" | 842 | r#" |
759 | #[lang = "unsize"] | 843 | #[lang = "unsize"] |
760 | pub trait Unsize<T> {} | 844 | pub trait Unsize<T> {} |
761 | #[lang = "coerce_unsized"] | 845 | #[lang = "coerce_unsized"] |
762 | pub trait CoerceUnsized<T> {} | 846 | pub trait CoerceUnsized<T> {} |
763 | 847 | ||
764 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 848 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
765 | 849 | ||
766 | struct Foo<T> { t: T }; | 850 | struct Foo<T> { t: T }; |
767 | struct Bar<T>(Foo<T>); | 851 | struct Bar<T>(Foo<T>); |
768 | 852 | ||
769 | fn test() { | 853 | fn test() { |
770 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; | 854 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; |
771 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); | 855 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); |
772 | } | 856 | } |
773 | "#, true), | 857 | "#, |
774 | @r###" | 858 | expect![[r" |
775 | "### | 859 | "]], |
776 | ); | 860 | ); |
777 | } | 861 | } |
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 45c4e309e..24c53eb02 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | use std::fs; | 1 | use std::fs; |
2 | 2 | ||
3 | use insta::assert_snapshot; | 3 | use expect::expect; |
4 | use test_utils::project_dir; | 4 | use test_utils::project_dir; |
5 | 5 | ||
6 | use super::{check_types, infer}; | 6 | use super::{check_infer, check_types}; |
7 | 7 | ||
8 | #[test] | 8 | #[test] |
9 | fn cfg_impl_def() { | 9 | fn cfg_impl_def() { |
@@ -46,204 +46,204 @@ impl S { | |||
46 | 46 | ||
47 | #[test] | 47 | #[test] |
48 | fn infer_macros_expanded() { | 48 | fn infer_macros_expanded() { |
49 | assert_snapshot!( | 49 | check_infer( |
50 | infer(r#" | 50 | r#" |
51 | struct Foo(Vec<i32>); | 51 | struct Foo(Vec<i32>); |
52 | 52 | ||
53 | macro_rules! foo { | 53 | macro_rules! foo { |
54 | ($($item:expr),*) => { | 54 | ($($item:expr),*) => { |
55 | { | 55 | { |
56 | Foo(vec![$($item,)*]) | 56 | Foo(vec![$($item,)*]) |
57 | } | 57 | } |
58 | }; | 58 | }; |
59 | } | 59 | } |
60 | 60 | ||
61 | fn main() { | 61 | fn main() { |
62 | let x = foo!(1,2); | 62 | let x = foo!(1,2); |
63 | } | 63 | } |
64 | "#), | 64 | "#, |
65 | @r###" | 65 | expect![[r#" |
66 | !0..17 '{Foo(v...,2,])}': Foo | 66 | !0..17 '{Foo(v...,2,])}': Foo |
67 | !1..4 'Foo': Foo({unknown}) -> Foo | 67 | !1..4 'Foo': Foo({unknown}) -> Foo |
68 | !1..16 'Foo(vec![1,2,])': Foo | 68 | !1..16 'Foo(vec![1,2,])': Foo |
69 | !5..15 'vec![1,2,]': {unknown} | 69 | !5..15 'vec![1,2,]': {unknown} |
70 | 155..181 '{ ...,2); }': () | 70 | 155..181 '{ ...,2); }': () |
71 | 165..166 'x': Foo | 71 | 165..166 'x': Foo |
72 | "### | 72 | "#]], |
73 | ); | 73 | ); |
74 | } | 74 | } |
75 | 75 | ||
76 | #[test] | 76 | #[test] |
77 | fn infer_legacy_textual_scoped_macros_expanded() { | 77 | fn infer_legacy_textual_scoped_macros_expanded() { |
78 | assert_snapshot!( | 78 | check_infer( |
79 | infer(r#" | 79 | r#" |
80 | struct Foo(Vec<i32>); | 80 | struct Foo(Vec<i32>); |
81 | 81 | ||
82 | #[macro_use] | 82 | #[macro_use] |
83 | mod m { | 83 | mod m { |
84 | macro_rules! foo { | 84 | macro_rules! foo { |
85 | ($($item:expr),*) => { | 85 | ($($item:expr),*) => { |
86 | { | 86 | { |
87 | Foo(vec![$($item,)*]) | 87 | Foo(vec![$($item,)*]) |
88 | } | ||
89 | }; | ||
88 | } | 90 | } |
89 | }; | 91 | } |
90 | } | ||
91 | } | ||
92 | 92 | ||
93 | fn main() { | 93 | fn main() { |
94 | let x = foo!(1,2); | 94 | let x = foo!(1,2); |
95 | let y = crate::foo!(1,2); | 95 | let y = crate::foo!(1,2); |
96 | } | 96 | } |
97 | "#), | 97 | "#, |
98 | @r###" | 98 | expect![[r#" |
99 | !0..17 '{Foo(v...,2,])}': Foo | 99 | !0..17 '{Foo(v...,2,])}': Foo |
100 | !1..4 'Foo': Foo({unknown}) -> Foo | 100 | !1..4 'Foo': Foo({unknown}) -> Foo |
101 | !1..16 'Foo(vec![1,2,])': Foo | 101 | !1..16 'Foo(vec![1,2,])': Foo |
102 | !5..15 'vec![1,2,]': {unknown} | 102 | !5..15 'vec![1,2,]': {unknown} |
103 | 194..250 '{ ...,2); }': () | 103 | 194..250 '{ ...,2); }': () |
104 | 204..205 'x': Foo | 104 | 204..205 'x': Foo |
105 | 227..228 'y': {unknown} | 105 | 227..228 'y': {unknown} |
106 | 231..247 'crate:...!(1,2)': {unknown} | 106 | 231..247 'crate:...!(1,2)': {unknown} |
107 | "### | 107 | "#]], |
108 | ); | 108 | ); |
109 | } | 109 | } |
110 | 110 | ||
111 | #[test] | 111 | #[test] |
112 | fn infer_path_qualified_macros_expanded() { | 112 | fn infer_path_qualified_macros_expanded() { |
113 | assert_snapshot!( | 113 | check_infer( |
114 | infer(r#" | 114 | r#" |
115 | #[macro_export] | 115 | #[macro_export] |
116 | macro_rules! foo { | 116 | macro_rules! foo { |
117 | () => { 42i32 } | 117 | () => { 42i32 } |
118 | } | 118 | } |
119 | 119 | ||
120 | mod m { | 120 | mod m { |
121 | pub use super::foo as bar; | 121 | pub use super::foo as bar; |
122 | } | 122 | } |
123 | 123 | ||
124 | fn main() { | 124 | fn main() { |
125 | let x = crate::foo!(); | 125 | let x = crate::foo!(); |
126 | let y = m::bar!(); | 126 | let y = m::bar!(); |
127 | } | 127 | } |
128 | "#), | 128 | "#, |
129 | @r###" | 129 | expect![[r#" |
130 | !0..5 '42i32': i32 | 130 | !0..5 '42i32': i32 |
131 | !0..5 '42i32': i32 | 131 | !0..5 '42i32': i32 |
132 | 110..163 '{ ...!(); }': () | 132 | 110..163 '{ ...!(); }': () |
133 | 120..121 'x': i32 | 133 | 120..121 'x': i32 |
134 | 147..148 'y': i32 | 134 | 147..148 'y': i32 |
135 | "### | 135 | "#]], |
136 | ); | 136 | ); |
137 | } | 137 | } |
138 | 138 | ||
139 | #[test] | 139 | #[test] |
140 | fn expr_macro_expanded_in_various_places() { | 140 | fn expr_macro_expanded_in_various_places() { |
141 | assert_snapshot!( | 141 | check_infer( |
142 | infer(r#" | 142 | r#" |
143 | macro_rules! spam { | 143 | macro_rules! spam { |
144 | () => (1isize); | 144 | () => (1isize); |
145 | } | 145 | } |
146 | 146 | ||
147 | fn spam() { | 147 | fn spam() { |
148 | spam!(); | 148 | spam!(); |
149 | (spam!()); | 149 | (spam!()); |
150 | spam!().spam(spam!()); | 150 | spam!().spam(spam!()); |
151 | for _ in spam!() {} | 151 | for _ in spam!() {} |
152 | || spam!(); | 152 | || spam!(); |
153 | while spam!() {} | 153 | while spam!() {} |
154 | break spam!(); | 154 | break spam!(); |
155 | return spam!(); | 155 | return spam!(); |
156 | match spam!() { | 156 | match spam!() { |
157 | _ if spam!() => spam!(), | 157 | _ if spam!() => spam!(), |
158 | } | 158 | } |
159 | spam!()(spam!()); | 159 | spam!()(spam!()); |
160 | Spam { spam: spam!() }; | 160 | Spam { spam: spam!() }; |
161 | spam!()[spam!()]; | 161 | spam!()[spam!()]; |
162 | await spam!(); | 162 | await spam!(); |
163 | spam!() as usize; | 163 | spam!() as usize; |
164 | &spam!(); | 164 | &spam!(); |
165 | -spam!(); | 165 | -spam!(); |
166 | spam!()..spam!(); | 166 | spam!()..spam!(); |
167 | spam!() + spam!(); | 167 | spam!() + spam!(); |
168 | } | 168 | } |
169 | "#), | 169 | "#, |
170 | @r###" | 170 | expect![[r#" |
171 | !0..6 '1isize': isize | 171 | !0..6 '1isize': isize |
172 | !0..6 '1isize': isize | 172 | !0..6 '1isize': isize |
173 | !0..6 '1isize': isize | 173 | !0..6 '1isize': isize |
174 | !0..6 '1isize': isize | 174 | !0..6 '1isize': isize |
175 | !0..6 '1isize': isize | 175 | !0..6 '1isize': isize |
176 | !0..6 '1isize': isize | 176 | !0..6 '1isize': isize |
177 | !0..6 '1isize': isize | 177 | !0..6 '1isize': isize |
178 | !0..6 '1isize': isize | 178 | !0..6 '1isize': isize |
179 | !0..6 '1isize': isize | 179 | !0..6 '1isize': isize |
180 | !0..6 '1isize': isize | 180 | !0..6 '1isize': isize |
181 | !0..6 '1isize': isize | 181 | !0..6 '1isize': isize |
182 | !0..6 '1isize': isize | 182 | !0..6 '1isize': isize |
183 | !0..6 '1isize': isize | 183 | !0..6 '1isize': isize |
184 | !0..6 '1isize': isize | 184 | !0..6 '1isize': isize |
185 | !0..6 '1isize': isize | 185 | !0..6 '1isize': isize |
186 | !0..6 '1isize': isize | 186 | !0..6 '1isize': isize |
187 | !0..6 '1isize': isize | 187 | !0..6 '1isize': isize |
188 | !0..6 '1isize': isize | 188 | !0..6 '1isize': isize |
189 | !0..6 '1isize': isize | 189 | !0..6 '1isize': isize |
190 | !0..6 '1isize': isize | 190 | !0..6 '1isize': isize |
191 | !0..6 '1isize': isize | 191 | !0..6 '1isize': isize |
192 | !0..6 '1isize': isize | 192 | !0..6 '1isize': isize |
193 | !0..6 '1isize': isize | 193 | !0..6 '1isize': isize |
194 | !0..6 '1isize': isize | 194 | !0..6 '1isize': isize |
195 | !0..6 '1isize': isize | 195 | !0..6 '1isize': isize |
196 | 53..456 '{ ...!(); }': () | 196 | 53..456 '{ ...!(); }': () |
197 | 87..108 'spam!(...am!())': {unknown} | 197 | 87..108 'spam!(...am!())': {unknown} |
198 | 114..133 'for _ ...!() {}': () | 198 | 114..133 'for _ ...!() {}': () |
199 | 118..119 '_': {unknown} | 199 | 118..119 '_': {unknown} |
200 | 131..133 '{}': () | 200 | 131..133 '{}': () |
201 | 138..148 '|| spam!()': || -> isize | 201 | 138..148 '|| spam!()': || -> isize |
202 | 154..170 'while ...!() {}': () | 202 | 154..170 'while ...!() {}': () |
203 | 168..170 '{}': () | 203 | 168..170 '{}': () |
204 | 175..188 'break spam!()': ! | 204 | 175..188 'break spam!()': ! |
205 | 194..208 'return spam!()': ! | 205 | 194..208 'return spam!()': ! |
206 | 214..268 'match ... }': isize | 206 | 214..268 'match ... }': isize |
207 | 238..239 '_': isize | 207 | 238..239 '_': isize |
208 | 273..289 'spam!(...am!())': {unknown} | 208 | 273..289 'spam!(...am!())': {unknown} |
209 | 295..317 'Spam {...m!() }': {unknown} | 209 | 295..317 'Spam {...m!() }': {unknown} |
210 | 323..339 'spam!(...am!()]': {unknown} | 210 | 323..339 'spam!(...am!()]': {unknown} |
211 | 364..380 'spam!(... usize': usize | 211 | 364..380 'spam!(... usize': usize |
212 | 386..394 '&spam!()': &isize | 212 | 386..394 '&spam!()': &isize |
213 | 400..408 '-spam!()': isize | 213 | 400..408 '-spam!()': isize |
214 | 414..430 'spam!(...pam!()': {unknown} | 214 | 414..430 'spam!(...pam!()': {unknown} |
215 | 436..453 'spam!(...pam!()': isize | 215 | 436..453 'spam!(...pam!()': isize |
216 | "### | 216 | "#]], |
217 | ); | 217 | ); |
218 | } | 218 | } |
219 | 219 | ||
220 | #[test] | 220 | #[test] |
221 | fn infer_type_value_macro_having_same_name() { | 221 | fn infer_type_value_macro_having_same_name() { |
222 | assert_snapshot!( | 222 | check_infer( |
223 | infer(r#" | 223 | r#" |
224 | #[macro_export] | 224 | #[macro_export] |
225 | macro_rules! foo { | 225 | macro_rules! foo { |
226 | () => { | 226 | () => { |
227 | mod foo { | 227 | mod foo { |
228 | pub use super::foo; | 228 | pub use super::foo; |
229 | } | ||
230 | }; | ||
231 | ($x:tt) => { | ||
232 | $x | ||
233 | }; | ||
229 | } | 234 | } |
230 | }; | ||
231 | ($x:tt) => { | ||
232 | $x | ||
233 | }; | ||
234 | } | ||
235 | 235 | ||
236 | foo!(); | 236 | foo!(); |
237 | 237 | ||
238 | fn foo() { | 238 | fn foo() { |
239 | let foo = foo::foo!(42i32); | 239 | let foo = foo::foo!(42i32); |
240 | } | 240 | } |
241 | "#), | 241 | "#, |
242 | @r###" | 242 | expect![[r#" |
243 | !0..5 '42i32': i32 | 243 | !0..5 '42i32': i32 |
244 | 170..205 '{ ...32); }': () | 244 | 170..205 '{ ...32); }': () |
245 | 180..183 'foo': i32 | 245 | 180..183 'foo': i32 |
246 | "### | 246 | "#]], |
247 | ); | 247 | ); |
248 | } | 248 | } |
249 | 249 | ||
@@ -372,50 +372,50 @@ expand!(); | |||
372 | 372 | ||
373 | #[test] | 373 | #[test] |
374 | fn infer_type_value_non_legacy_macro_use_as() { | 374 | fn infer_type_value_non_legacy_macro_use_as() { |
375 | assert_snapshot!( | 375 | check_infer( |
376 | infer(r#" | 376 | r#" |
377 | mod m { | 377 | mod m { |
378 | macro_rules! _foo { | 378 | macro_rules! _foo { |
379 | ($x:ident) => { type $x = u64; } | 379 | ($x:ident) => { type $x = u64; } |
380 | } | 380 | } |
381 | pub(crate) use _foo as foo; | 381 | pub(crate) use _foo as foo; |
382 | } | 382 | } |
383 | 383 | ||
384 | m::foo!(foo); | 384 | m::foo!(foo); |
385 | use foo as bar; | 385 | use foo as bar; |
386 | fn f() -> bar { 0 } | 386 | fn f() -> bar { 0 } |
387 | fn main() { | 387 | fn main() { |
388 | let _a = f(); | 388 | let _a = f(); |
389 | } | 389 | } |
390 | "#), | 390 | "#, |
391 | @r###" | 391 | expect![[r#" |
392 | 158..163 '{ 0 }': u64 | 392 | 158..163 '{ 0 }': u64 |
393 | 160..161 '0': u64 | 393 | 160..161 '0': u64 |
394 | 174..196 '{ ...f(); }': () | 394 | 174..196 '{ ...f(); }': () |
395 | 184..186 '_a': u64 | 395 | 184..186 '_a': u64 |
396 | 190..191 'f': fn f() -> u64 | 396 | 190..191 'f': fn f() -> u64 |
397 | 190..193 'f()': u64 | 397 | 190..193 'f()': u64 |
398 | "### | 398 | "#]], |
399 | ); | 399 | ); |
400 | } | 400 | } |
401 | 401 | ||
402 | #[test] | 402 | #[test] |
403 | fn infer_local_macro() { | 403 | fn infer_local_macro() { |
404 | assert_snapshot!( | 404 | check_infer( |
405 | infer(r#" | 405 | r#" |
406 | fn main() { | 406 | fn main() { |
407 | macro_rules! foo { | 407 | macro_rules! foo { |
408 | () => { 1usize } | 408 | () => { 1usize } |
409 | } | 409 | } |
410 | let _a = foo!(); | 410 | let _a = foo!(); |
411 | } | 411 | } |
412 | "#), | 412 | "#, |
413 | @r###" | 413 | expect![[r#" |
414 | !0..6 '1usize': usize | 414 | !0..6 '1usize': usize |
415 | 10..89 '{ ...!(); }': () | 415 | 10..89 '{ ...!(); }': () |
416 | 16..65 'macro_... }': {unknown} | 416 | 16..65 'macro_... }': {unknown} |
417 | 74..76 '_a': usize | 417 | 74..76 '_a': usize |
418 | "### | 418 | "#]], |
419 | ); | 419 | ); |
420 | } | 420 | } |
421 | 421 | ||
@@ -446,77 +446,77 @@ macro_rules! bar { | |||
446 | 446 | ||
447 | #[test] | 447 | #[test] |
448 | fn infer_builtin_macros_line() { | 448 | fn infer_builtin_macros_line() { |
449 | assert_snapshot!( | 449 | check_infer( |
450 | infer(r#" | 450 | r#" |
451 | #[rustc_builtin_macro] | 451 | #[rustc_builtin_macro] |
452 | macro_rules! line {() => {}} | 452 | macro_rules! line {() => {}} |
453 | 453 | ||
454 | fn main() { | 454 | fn main() { |
455 | let x = line!(); | 455 | let x = line!(); |
456 | } | 456 | } |
457 | "#), | 457 | "#, |
458 | @r###" | 458 | expect![[r#" |
459 | !0..1 '0': i32 | 459 | !0..1 '0': i32 |
460 | 63..87 '{ ...!(); }': () | 460 | 63..87 '{ ...!(); }': () |
461 | 73..74 'x': i32 | 461 | 73..74 'x': i32 |
462 | "### | 462 | "#]], |
463 | ); | 463 | ); |
464 | } | 464 | } |
465 | 465 | ||
466 | #[test] | 466 | #[test] |
467 | fn infer_builtin_macros_file() { | 467 | fn infer_builtin_macros_file() { |
468 | assert_snapshot!( | 468 | check_infer( |
469 | infer(r#" | 469 | r#" |
470 | #[rustc_builtin_macro] | 470 | #[rustc_builtin_macro] |
471 | macro_rules! file {() => {}} | 471 | macro_rules! file {() => {}} |
472 | 472 | ||
473 | fn main() { | 473 | fn main() { |
474 | let x = file!(); | 474 | let x = file!(); |
475 | } | 475 | } |
476 | "#), | 476 | "#, |
477 | @r###" | 477 | expect![[r#" |
478 | !0..2 '""': &str | 478 | !0..2 '""': &str |
479 | 63..87 '{ ...!(); }': () | 479 | 63..87 '{ ...!(); }': () |
480 | 73..74 'x': &str | 480 | 73..74 'x': &str |
481 | "### | 481 | "#]], |
482 | ); | 482 | ); |
483 | } | 483 | } |
484 | 484 | ||
485 | #[test] | 485 | #[test] |
486 | fn infer_builtin_macros_column() { | 486 | fn infer_builtin_macros_column() { |
487 | assert_snapshot!( | 487 | check_infer( |
488 | infer(r#" | 488 | r#" |
489 | #[rustc_builtin_macro] | 489 | #[rustc_builtin_macro] |
490 | macro_rules! column {() => {}} | 490 | macro_rules! column {() => {}} |
491 | 491 | ||
492 | fn main() { | 492 | fn main() { |
493 | let x = column!(); | 493 | let x = column!(); |
494 | } | 494 | } |
495 | "#), | 495 | "#, |
496 | @r###" | 496 | expect![[r#" |
497 | !0..1 '0': i32 | 497 | !0..1 '0': i32 |
498 | 65..91 '{ ...!(); }': () | 498 | 65..91 '{ ...!(); }': () |
499 | 75..76 'x': i32 | 499 | 75..76 'x': i32 |
500 | "### | 500 | "#]], |
501 | ); | 501 | ); |
502 | } | 502 | } |
503 | 503 | ||
504 | #[test] | 504 | #[test] |
505 | fn infer_builtin_macros_concat() { | 505 | fn infer_builtin_macros_concat() { |
506 | assert_snapshot!( | 506 | check_infer( |
507 | infer(r#" | 507 | r#" |
508 | #[rustc_builtin_macro] | 508 | #[rustc_builtin_macro] |
509 | macro_rules! concat {() => {}} | 509 | macro_rules! concat {() => {}} |
510 | 510 | ||
511 | fn main() { | 511 | fn main() { |
512 | let x = concat!("hello", concat!("world", "!")); | 512 | let x = concat!("hello", concat!("world", "!")); |
513 | } | 513 | } |
514 | "#), | 514 | "#, |
515 | @r###" | 515 | expect![[r#" |
516 | !0..13 '"helloworld!"': &str | 516 | !0..13 '"helloworld!"': &str |
517 | 65..121 '{ ...")); }': () | 517 | 65..121 '{ ...")); }': () |
518 | 75..76 'x': &str | 518 | 75..76 'x': &str |
519 | "### | 519 | "#]], |
520 | ); | 520 | ); |
521 | } | 521 | } |
522 | 522 | ||
@@ -622,7 +622,7 @@ macro_rules! include {() => {}} | |||
622 | include!("main.rs"); | 622 | include!("main.rs"); |
623 | 623 | ||
624 | fn main() { | 624 | fn main() { |
625 | 0 | 625 | 0 |
626 | } //^ i32 | 626 | } //^ i32 |
627 | "#, | 627 | "#, |
628 | ); | 628 | ); |
@@ -630,42 +630,42 @@ fn main() { | |||
630 | 630 | ||
631 | #[test] | 631 | #[test] |
632 | fn infer_builtin_macros_concat_with_lazy() { | 632 | fn infer_builtin_macros_concat_with_lazy() { |
633 | assert_snapshot!( | 633 | check_infer( |
634 | infer(r#" | 634 | r#" |
635 | macro_rules! hello {() => {"hello"}} | 635 | macro_rules! hello {() => {"hello"}} |
636 | 636 | ||
637 | #[rustc_builtin_macro] | 637 | #[rustc_builtin_macro] |
638 | macro_rules! concat {() => {}} | 638 | macro_rules! concat {() => {}} |
639 | 639 | ||
640 | fn main() { | 640 | fn main() { |
641 | let x = concat!(hello!(), concat!("world", "!")); | 641 | let x = concat!(hello!(), concat!("world", "!")); |
642 | } | 642 | } |
643 | "#), | 643 | "#, |
644 | @r###" | 644 | expect![[r#" |
645 | !0..13 '"helloworld!"': &str | 645 | !0..13 '"helloworld!"': &str |
646 | 103..160 '{ ...")); }': () | 646 | 103..160 '{ ...")); }': () |
647 | 113..114 'x': &str | 647 | 113..114 'x': &str |
648 | "### | 648 | "#]], |
649 | ); | 649 | ); |
650 | } | 650 | } |
651 | 651 | ||
652 | #[test] | 652 | #[test] |
653 | fn infer_builtin_macros_env() { | 653 | fn infer_builtin_macros_env() { |
654 | assert_snapshot!( | 654 | check_infer( |
655 | infer(r#" | 655 | r#" |
656 | //- /main.rs env:foo=bar | 656 | //- /main.rs env:foo=bar |
657 | #[rustc_builtin_macro] | 657 | #[rustc_builtin_macro] |
658 | macro_rules! env {() => {}} | 658 | macro_rules! env {() => {}} |
659 | 659 | ||
660 | fn main() { | 660 | fn main() { |
661 | let x = env!("foo"); | 661 | let x = env!("foo"); |
662 | } | 662 | } |
663 | "#), | 663 | "#, |
664 | @r###" | 664 | expect![[r#" |
665 | !0..22 '"__RA_...TED__"': &str | 665 | !0..22 '"__RA_...TED__"': &str |
666 | 62..90 '{ ...o"); }': () | 666 | 62..90 '{ ...o"); }': () |
667 | 72..73 'x': &str | 667 | 72..73 'x': &str |
668 | "### | 668 | "#]], |
669 | ); | 669 | ); |
670 | } | 670 | } |
671 | 671 | ||
@@ -763,25 +763,25 @@ fn test() { | |||
763 | 763 | ||
764 | #[test] | 764 | #[test] |
765 | fn macro_in_arm() { | 765 | fn macro_in_arm() { |
766 | assert_snapshot!( | 766 | check_infer( |
767 | infer(r#" | 767 | r#" |
768 | macro_rules! unit { | 768 | macro_rules! unit { |
769 | () => { () }; | 769 | () => { () }; |
770 | } | 770 | } |
771 | 771 | ||
772 | fn main() { | 772 | fn main() { |
773 | let x = match () { | 773 | let x = match () { |
774 | unit!() => 92u32, | 774 | unit!() => 92u32, |
775 | }; | 775 | }; |
776 | } | 776 | } |
777 | "#), | 777 | "#, |
778 | @r###" | 778 | expect![[r#" |
779 | 51..110 '{ ... }; }': () | 779 | 51..110 '{ ... }; }': () |
780 | 61..62 'x': u32 | 780 | 61..62 'x': u32 |
781 | 65..107 'match ... }': u32 | 781 | 65..107 'match ... }': u32 |
782 | 71..73 '()': () | 782 | 71..73 '()': () |
783 | 84..91 'unit!()': () | 783 | 84..91 'unit!()': () |
784 | 95..100 '92u32': u32 | 784 | 95..100 '92u32': u32 |
785 | "### | 785 | "#]], |
786 | ); | 786 | ); |
787 | } | 787 | } |
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 9c8f22314..fa68355aa 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -1,245 +1,245 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer}; | 3 | use super::{check_infer, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_slice_method() { | 6 | fn infer_slice_method() { |
7 | assert_snapshot!( | 7 | check_infer( |
8 | infer(r#" | 8 | r#" |
9 | #[lang = "slice"] | 9 | #[lang = "slice"] |
10 | impl<T> [T] { | 10 | impl<T> [T] { |
11 | fn foo(&self) -> T { | 11 | fn foo(&self) -> T { |
12 | loop {} | 12 | loop {} |
13 | } | 13 | } |
14 | } | 14 | } |
15 | 15 | ||
16 | #[lang = "slice_alloc"] | 16 | #[lang = "slice_alloc"] |
17 | impl<T> [T] {} | 17 | impl<T> [T] {} |
18 | 18 | ||
19 | fn test(x: &[u8]) { | 19 | fn test(x: &[u8]) { |
20 | <[_]>::foo(x); | 20 | <[_]>::foo(x); |
21 | } | 21 | } |
22 | "#), | 22 | "#, |
23 | @r###" | 23 | expect![[r#" |
24 | 44..48 'self': &[T] | 24 | 44..48 'self': &[T] |
25 | 55..78 '{ ... }': T | 25 | 55..78 '{ ... }': T |
26 | 65..72 'loop {}': ! | 26 | 65..72 'loop {}': ! |
27 | 70..72 '{}': () | 27 | 70..72 '{}': () |
28 | 130..131 'x': &[u8] | 28 | 130..131 'x': &[u8] |
29 | 140..162 '{ ...(x); }': () | 29 | 140..162 '{ ...(x); }': () |
30 | 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8 | 30 | 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8 |
31 | 146..159 '<[_]>::foo(x)': u8 | 31 | 146..159 '<[_]>::foo(x)': u8 |
32 | 157..158 'x': &[u8] | 32 | 157..158 'x': &[u8] |
33 | "### | 33 | "#]], |
34 | ); | 34 | ); |
35 | } | 35 | } |
36 | 36 | ||
37 | #[test] | 37 | #[test] |
38 | fn infer_associated_method_struct() { | 38 | fn infer_associated_method_struct() { |
39 | assert_snapshot!( | 39 | check_infer( |
40 | infer(r#" | 40 | r#" |
41 | struct A { x: u32 } | 41 | struct A { x: u32 } |
42 | 42 | ||
43 | impl A { | 43 | impl A { |
44 | fn new() -> A { | 44 | fn new() -> A { |
45 | A { x: 0 } | 45 | A { x: 0 } |
46 | } | 46 | } |
47 | } | 47 | } |
48 | fn test() { | 48 | fn test() { |
49 | let a = A::new(); | 49 | let a = A::new(); |
50 | a.x; | 50 | a.x; |
51 | } | 51 | } |
52 | "#), | 52 | "#, |
53 | @r###" | 53 | expect![[r#" |
54 | 48..74 '{ ... }': A | 54 | 48..74 '{ ... }': A |
55 | 58..68 'A { x: 0 }': A | 55 | 58..68 'A { x: 0 }': A |
56 | 65..66 '0': u32 | 56 | 65..66 '0': u32 |
57 | 87..121 '{ ...a.x; }': () | 57 | 87..121 '{ ...a.x; }': () |
58 | 97..98 'a': A | 58 | 97..98 'a': A |
59 | 101..107 'A::new': fn new() -> A | 59 | 101..107 'A::new': fn new() -> A |
60 | 101..109 'A::new()': A | 60 | 101..109 'A::new()': A |
61 | 115..116 'a': A | 61 | 115..116 'a': A |
62 | 115..118 'a.x': u32 | 62 | 115..118 'a.x': u32 |
63 | "### | 63 | "#]], |
64 | ); | 64 | ); |
65 | } | 65 | } |
66 | 66 | ||
67 | #[test] | 67 | #[test] |
68 | fn infer_associated_method_enum() { | 68 | fn infer_associated_method_enum() { |
69 | assert_snapshot!( | 69 | check_infer( |
70 | infer(r#" | 70 | r#" |
71 | enum A { B, C } | 71 | enum A { B, C } |
72 | 72 | ||
73 | impl A { | 73 | impl A { |
74 | pub fn b() -> A { | 74 | pub fn b() -> A { |
75 | A::B | 75 | A::B |
76 | } | 76 | } |
77 | pub fn c() -> A { | 77 | pub fn c() -> A { |
78 | A::C | 78 | A::C |
79 | } | 79 | } |
80 | } | 80 | } |
81 | fn test() { | 81 | fn test() { |
82 | let a = A::b(); | 82 | let a = A::b(); |
83 | a; | 83 | a; |
84 | let c = A::c(); | 84 | let c = A::c(); |
85 | c; | 85 | c; |
86 | } | 86 | } |
87 | "#), | 87 | "#, |
88 | @r###" | 88 | expect![[r#" |
89 | 46..66 '{ ... }': A | 89 | 46..66 '{ ... }': A |
90 | 56..60 'A::B': A | 90 | 56..60 'A::B': A |
91 | 87..107 '{ ... }': A | 91 | 87..107 '{ ... }': A |
92 | 97..101 'A::C': A | 92 | 97..101 'A::C': A |
93 | 120..177 '{ ... c; }': () | 93 | 120..177 '{ ... c; }': () |
94 | 130..131 'a': A | 94 | 130..131 'a': A |
95 | 134..138 'A::b': fn b() -> A | 95 | 134..138 'A::b': fn b() -> A |
96 | 134..140 'A::b()': A | 96 | 134..140 'A::b()': A |
97 | 146..147 'a': A | 97 | 146..147 'a': A |
98 | 157..158 'c': A | 98 | 157..158 'c': A |
99 | 161..165 'A::c': fn c() -> A | 99 | 161..165 'A::c': fn c() -> A |
100 | 161..167 'A::c()': A | 100 | 161..167 'A::c()': A |
101 | 173..174 'c': A | 101 | 173..174 'c': A |
102 | "### | 102 | "#]], |
103 | ); | 103 | ); |
104 | } | 104 | } |
105 | 105 | ||
106 | #[test] | 106 | #[test] |
107 | fn infer_associated_method_with_modules() { | 107 | fn infer_associated_method_with_modules() { |
108 | assert_snapshot!( | 108 | check_infer( |
109 | infer(r#" | 109 | r#" |
110 | mod a { | 110 | mod a { |
111 | struct A; | 111 | struct A; |
112 | impl A { pub fn thing() -> A { A {} }} | 112 | impl A { pub fn thing() -> A { A {} }} |
113 | } | 113 | } |
114 | 114 | ||
115 | mod b { | 115 | mod b { |
116 | struct B; | 116 | struct B; |
117 | impl B { pub fn thing() -> u32 { 99 }} | 117 | impl B { pub fn thing() -> u32 { 99 }} |
118 | 118 | ||
119 | mod c { | 119 | mod c { |
120 | struct C; | 120 | struct C; |
121 | impl C { pub fn thing() -> C { C {} }} | 121 | impl C { pub fn thing() -> C { C {} }} |
122 | } | 122 | } |
123 | } | 123 | } |
124 | use b::c; | 124 | use b::c; |
125 | 125 | ||
126 | fn test() { | 126 | fn test() { |
127 | let x = a::A::thing(); | 127 | let x = a::A::thing(); |
128 | let y = b::B::thing(); | 128 | let y = b::B::thing(); |
129 | let z = c::C::thing(); | 129 | let z = c::C::thing(); |
130 | } | 130 | } |
131 | "#), | 131 | "#, |
132 | @r###" | 132 | expect![[r#" |
133 | 55..63 '{ A {} }': A | 133 | 55..63 '{ A {} }': A |
134 | 57..61 'A {}': A | 134 | 57..61 'A {}': A |
135 | 125..131 '{ 99 }': u32 | 135 | 125..131 '{ 99 }': u32 |
136 | 127..129 '99': u32 | 136 | 127..129 '99': u32 |
137 | 201..209 '{ C {} }': C | 137 | 201..209 '{ C {} }': C |
138 | 203..207 'C {}': C | 138 | 203..207 'C {}': C |
139 | 240..324 '{ ...g(); }': () | 139 | 240..324 '{ ...g(); }': () |
140 | 250..251 'x': A | 140 | 250..251 'x': A |
141 | 254..265 'a::A::thing': fn thing() -> A | 141 | 254..265 'a::A::thing': fn thing() -> A |
142 | 254..267 'a::A::thing()': A | 142 | 254..267 'a::A::thing()': A |
143 | 277..278 'y': u32 | 143 | 277..278 'y': u32 |
144 | 281..292 'b::B::thing': fn thing() -> u32 | 144 | 281..292 'b::B::thing': fn thing() -> u32 |
145 | 281..294 'b::B::thing()': u32 | 145 | 281..294 'b::B::thing()': u32 |
146 | 304..305 'z': C | 146 | 304..305 'z': C |
147 | 308..319 'c::C::thing': fn thing() -> C | 147 | 308..319 'c::C::thing': fn thing() -> C |
148 | 308..321 'c::C::thing()': C | 148 | 308..321 'c::C::thing()': C |
149 | "### | 149 | "#]], |
150 | ); | 150 | ); |
151 | } | 151 | } |
152 | 152 | ||
153 | #[test] | 153 | #[test] |
154 | fn infer_associated_method_generics() { | 154 | fn infer_associated_method_generics() { |
155 | assert_snapshot!( | 155 | check_infer( |
156 | infer(r#" | 156 | r#" |
157 | struct Gen<T> { | 157 | struct Gen<T> { |
158 | val: T | 158 | val: T |
159 | } | 159 | } |
160 | 160 | ||
161 | impl<T> Gen<T> { | 161 | impl<T> Gen<T> { |
162 | pub fn make(val: T) -> Gen<T> { | 162 | pub fn make(val: T) -> Gen<T> { |
163 | Gen { val } | 163 | Gen { val } |
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
167 | fn test() { | 167 | fn test() { |
168 | let a = Gen::make(0u32); | 168 | let a = Gen::make(0u32); |
169 | } | 169 | } |
170 | "#), | 170 | "#, |
171 | @r###" | 171 | expect![[r#" |
172 | 63..66 'val': T | 172 | 63..66 'val': T |
173 | 81..108 '{ ... }': Gen<T> | 173 | 81..108 '{ ... }': Gen<T> |
174 | 91..102 'Gen { val }': Gen<T> | 174 | 91..102 'Gen { val }': Gen<T> |
175 | 97..100 'val': T | 175 | 97..100 'val': T |
176 | 122..154 '{ ...32); }': () | 176 | 122..154 '{ ...32); }': () |
177 | 132..133 'a': Gen<u32> | 177 | 132..133 'a': Gen<u32> |
178 | 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32> | 178 | 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32> |
179 | 136..151 'Gen::make(0u32)': Gen<u32> | 179 | 136..151 'Gen::make(0u32)': Gen<u32> |
180 | 146..150 '0u32': u32 | 180 | 146..150 '0u32': u32 |
181 | "### | 181 | "#]], |
182 | ); | 182 | ); |
183 | } | 183 | } |
184 | 184 | ||
185 | #[test] | 185 | #[test] |
186 | fn infer_associated_method_generics_without_args() { | 186 | fn infer_associated_method_generics_without_args() { |
187 | assert_snapshot!( | 187 | check_infer( |
188 | infer(r#" | 188 | r#" |
189 | struct Gen<T> { | 189 | struct Gen<T> { |
190 | val: T | 190 | val: T |
191 | } | 191 | } |
192 | 192 | ||
193 | impl<T> Gen<T> { | 193 | impl<T> Gen<T> { |
194 | pub fn make() -> Gen<T> { | 194 | pub fn make() -> Gen<T> { |
195 | loop { } | 195 | loop { } |
196 | } | 196 | } |
197 | } | 197 | } |
198 | 198 | ||
199 | fn test() { | 199 | fn test() { |
200 | let a = Gen::<u32>::make(); | 200 | let a = Gen::<u32>::make(); |
201 | } | 201 | } |
202 | "#), | 202 | "#, |
203 | @r###" | 203 | expect![[r#" |
204 | 75..99 '{ ... }': Gen<T> | 204 | 75..99 '{ ... }': Gen<T> |
205 | 85..93 'loop { }': ! | 205 | 85..93 'loop { }': ! |
206 | 90..93 '{ }': () | 206 | 90..93 '{ }': () |
207 | 113..148 '{ ...e(); }': () | 207 | 113..148 '{ ...e(); }': () |
208 | 123..124 'a': Gen<u32> | 208 | 123..124 'a': Gen<u32> |
209 | 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32> | 209 | 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32> |
210 | 127..145 'Gen::<...make()': Gen<u32> | 210 | 127..145 'Gen::<...make()': Gen<u32> |
211 | "### | 211 | "#]], |
212 | ); | 212 | ); |
213 | } | 213 | } |
214 | 214 | ||
215 | #[test] | 215 | #[test] |
216 | fn infer_associated_method_generics_2_type_params_without_args() { | 216 | fn infer_associated_method_generics_2_type_params_without_args() { |
217 | assert_snapshot!( | 217 | check_infer( |
218 | infer(r#" | 218 | r#" |
219 | struct Gen<T, U> { | 219 | struct Gen<T, U> { |
220 | val: T, | 220 | val: T, |
221 | val2: U, | 221 | val2: U, |
222 | } | 222 | } |
223 | 223 | ||
224 | impl<T> Gen<u32, T> { | 224 | impl<T> Gen<u32, T> { |
225 | pub fn make() -> Gen<u32,T> { | 225 | pub fn make() -> Gen<u32,T> { |
226 | loop { } | 226 | loop { } |
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | ||
230 | fn test() { | 230 | fn test() { |
231 | let a = Gen::<u32, u64>::make(); | 231 | let a = Gen::<u32, u64>::make(); |
232 | } | 232 | } |
233 | "#), | 233 | "#, |
234 | @r###" | 234 | expect![[r#" |
235 | 101..125 '{ ... }': Gen<u32, T> | 235 | 101..125 '{ ... }': Gen<u32, T> |
236 | 111..119 'loop { }': ! | 236 | 111..119 'loop { }': ! |
237 | 116..119 '{ }': () | 237 | 116..119 '{ }': () |
238 | 139..179 '{ ...e(); }': () | 238 | 139..179 '{ ...e(); }': () |
239 | 149..150 'a': Gen<u32, u64> | 239 | 149..150 'a': Gen<u32, u64> |
240 | 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64> | 240 | 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64> |
241 | 153..176 'Gen::<...make()': Gen<u32, u64> | 241 | 153..176 'Gen::<...make()': Gen<u32, u64> |
242 | "### | 242 | "#]], |
243 | ); | 243 | ); |
244 | } | 244 | } |
245 | 245 | ||
@@ -267,416 +267,416 @@ mod foo { | |||
267 | #[test] | 267 | #[test] |
268 | fn infer_trait_method_simple() { | 268 | fn infer_trait_method_simple() { |
269 | // the trait implementation is intentionally incomplete -- it shouldn't matter | 269 | // the trait implementation is intentionally incomplete -- it shouldn't matter |
270 | assert_snapshot!( | 270 | check_infer( |
271 | infer(r#" | 271 | r#" |
272 | trait Trait1 { | 272 | trait Trait1 { |
273 | fn method(&self) -> u32; | 273 | fn method(&self) -> u32; |
274 | } | 274 | } |
275 | struct S1; | 275 | struct S1; |
276 | impl Trait1 for S1 {} | 276 | impl Trait1 for S1 {} |
277 | trait Trait2 { | 277 | trait Trait2 { |
278 | fn method(&self) -> i128; | 278 | fn method(&self) -> i128; |
279 | } | 279 | } |
280 | struct S2; | 280 | struct S2; |
281 | impl Trait2 for S2 {} | 281 | impl Trait2 for S2 {} |
282 | fn test() { | 282 | fn test() { |
283 | S1.method(); // -> u32 | 283 | S1.method(); // -> u32 |
284 | S2.method(); // -> i128 | 284 | S2.method(); // -> i128 |
285 | } | 285 | } |
286 | "#), | 286 | "#, |
287 | @r###" | 287 | expect![[r#" |
288 | 30..34 'self': &Self | 288 | 30..34 'self': &Self |
289 | 109..113 'self': &Self | 289 | 109..113 'self': &Self |
290 | 169..227 '{ ...i128 }': () | 290 | 169..227 '{ ...i128 }': () |
291 | 175..177 'S1': S1 | 291 | 175..177 'S1': S1 |
292 | 175..186 'S1.method()': u32 | 292 | 175..186 'S1.method()': u32 |
293 | 202..204 'S2': S2 | 293 | 202..204 'S2': S2 |
294 | 202..213 'S2.method()': i128 | 294 | 202..213 'S2.method()': i128 |
295 | "### | 295 | "#]], |
296 | ); | 296 | ); |
297 | } | 297 | } |
298 | 298 | ||
299 | #[test] | 299 | #[test] |
300 | fn infer_trait_method_scoped() { | 300 | fn infer_trait_method_scoped() { |
301 | // the trait implementation is intentionally incomplete -- it shouldn't matter | 301 | // the trait implementation is intentionally incomplete -- it shouldn't matter |
302 | assert_snapshot!( | 302 | check_infer( |
303 | infer(r#" | 303 | r#" |
304 | struct S; | 304 | struct S; |
305 | mod foo { | 305 | mod foo { |
306 | pub trait Trait1 { | 306 | pub trait Trait1 { |
307 | fn method(&self) -> u32; | 307 | fn method(&self) -> u32; |
308 | } | 308 | } |
309 | impl Trait1 for super::S {} | 309 | impl Trait1 for super::S {} |
310 | } | 310 | } |
311 | mod bar { | 311 | mod bar { |
312 | pub trait Trait2 { | 312 | pub trait Trait2 { |
313 | fn method(&self) -> i128; | 313 | fn method(&self) -> i128; |
314 | } | 314 | } |
315 | impl Trait2 for super::S {} | 315 | impl Trait2 for super::S {} |
316 | } | 316 | } |
317 | 317 | ||
318 | mod foo_test { | 318 | mod foo_test { |
319 | use super::S; | 319 | use super::S; |
320 | use super::foo::Trait1; | 320 | use super::foo::Trait1; |
321 | fn test() { | 321 | fn test() { |
322 | S.method(); // -> u32 | 322 | S.method(); // -> u32 |
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | mod bar_test { | 326 | mod bar_test { |
327 | use super::S; | 327 | use super::S; |
328 | use super::bar::Trait2; | 328 | use super::bar::Trait2; |
329 | fn test() { | 329 | fn test() { |
330 | S.method(); // -> i128 | 330 | S.method(); // -> i128 |
331 | } | 331 | } |
332 | } | 332 | } |
333 | "#), | 333 | "#, |
334 | @r###" | 334 | expect![[r#" |
335 | 62..66 'self': &Self | 335 | 62..66 'self': &Self |
336 | 168..172 'self': &Self | 336 | 168..172 'self': &Self |
337 | 299..336 '{ ... }': () | 337 | 299..336 '{ ... }': () |
338 | 309..310 'S': S | 338 | 309..310 'S': S |
339 | 309..319 'S.method()': u32 | 339 | 309..319 'S.method()': u32 |
340 | 415..453 '{ ... }': () | 340 | 415..453 '{ ... }': () |
341 | 425..426 'S': S | 341 | 425..426 'S': S |
342 | 425..435 'S.method()': i128 | 342 | 425..435 'S.method()': i128 |
343 | "### | 343 | "#]], |
344 | ); | 344 | ); |
345 | } | 345 | } |
346 | 346 | ||
347 | #[test] | 347 | #[test] |
348 | fn infer_trait_method_generic_1() { | 348 | fn infer_trait_method_generic_1() { |
349 | // the trait implementation is intentionally incomplete -- it shouldn't matter | 349 | // the trait implementation is intentionally incomplete -- it shouldn't matter |
350 | assert_snapshot!( | 350 | check_infer( |
351 | infer(r#" | 351 | r#" |
352 | trait Trait<T> { | 352 | trait Trait<T> { |
353 | fn method(&self) -> T; | 353 | fn method(&self) -> T; |
354 | } | 354 | } |
355 | struct S; | 355 | struct S; |
356 | impl Trait<u32> for S {} | 356 | impl Trait<u32> for S {} |
357 | fn test() { | 357 | fn test() { |
358 | S.method(); | 358 | S.method(); |
359 | } | 359 | } |
360 | "#), | 360 | "#, |
361 | @r###" | 361 | expect![[r#" |
362 | 32..36 'self': &Self | 362 | 32..36 'self': &Self |
363 | 91..110 '{ ...d(); }': () | 363 | 91..110 '{ ...d(); }': () |
364 | 97..98 'S': S | 364 | 97..98 'S': S |
365 | 97..107 'S.method()': u32 | 365 | 97..107 'S.method()': u32 |
366 | "### | 366 | "#]], |
367 | ); | 367 | ); |
368 | } | 368 | } |
369 | 369 | ||
370 | #[test] | 370 | #[test] |
371 | fn infer_trait_method_generic_more_params() { | 371 | fn infer_trait_method_generic_more_params() { |
372 | // the trait implementation is intentionally incomplete -- it shouldn't matter | 372 | // the trait implementation is intentionally incomplete -- it shouldn't matter |
373 | assert_snapshot!( | 373 | check_infer( |
374 | infer(r#" | 374 | r#" |
375 | trait Trait<T1, T2, T3> { | 375 | trait Trait<T1, T2, T3> { |
376 | fn method1(&self) -> (T1, T2, T3); | 376 | fn method1(&self) -> (T1, T2, T3); |
377 | fn method2(&self) -> (T3, T2, T1); | 377 | fn method2(&self) -> (T3, T2, T1); |
378 | } | 378 | } |
379 | struct S1; | 379 | struct S1; |
380 | impl Trait<u8, u16, u32> for S1 {} | 380 | impl Trait<u8, u16, u32> for S1 {} |
381 | struct S2; | 381 | struct S2; |
382 | impl<T> Trait<i8, i16, T> for S2 {} | 382 | impl<T> Trait<i8, i16, T> for S2 {} |
383 | fn test() { | 383 | fn test() { |
384 | S1.method1(); // u8, u16, u32 | 384 | S1.method1(); // u8, u16, u32 |
385 | S1.method2(); // u32, u16, u8 | 385 | S1.method2(); // u32, u16, u8 |
386 | S2.method1(); // i8, i16, {unknown} | 386 | S2.method1(); // i8, i16, {unknown} |
387 | S2.method2(); // {unknown}, i16, i8 | 387 | S2.method2(); // {unknown}, i16, i8 |
388 | } | 388 | } |
389 | "#), | 389 | "#, |
390 | @r###" | 390 | expect![[r#" |
391 | 42..46 'self': &Self | 391 | 42..46 'self': &Self |
392 | 81..85 'self': &Self | 392 | 81..85 'self': &Self |
393 | 209..360 '{ ..., i8 }': () | 393 | 209..360 '{ ..., i8 }': () |
394 | 215..217 'S1': S1 | 394 | 215..217 'S1': S1 |
395 | 215..227 'S1.method1()': (u8, u16, u32) | 395 | 215..227 'S1.method1()': (u8, u16, u32) |
396 | 249..251 'S1': S1 | 396 | 249..251 'S1': S1 |
397 | 249..261 'S1.method2()': (u32, u16, u8) | 397 | 249..261 'S1.method2()': (u32, u16, u8) |
398 | 283..285 'S2': S2 | 398 | 283..285 'S2': S2 |
399 | 283..295 'S2.method1()': (i8, i16, {unknown}) | 399 | 283..295 'S2.method1()': (i8, i16, {unknown}) |
400 | 323..325 'S2': S2 | 400 | 323..325 'S2': S2 |
401 | 323..335 'S2.method2()': ({unknown}, i16, i8) | 401 | 323..335 'S2.method2()': ({unknown}, i16, i8) |
402 | "### | 402 | "#]], |
403 | ); | 403 | ); |
404 | } | 404 | } |
405 | 405 | ||
406 | #[test] | 406 | #[test] |
407 | fn infer_trait_method_generic_2() { | 407 | fn infer_trait_method_generic_2() { |
408 | // the trait implementation is intentionally incomplete -- it shouldn't matter | 408 | // the trait implementation is intentionally incomplete -- it shouldn't matter |
409 | assert_snapshot!( | 409 | check_infer( |
410 | infer(r#" | 410 | r#" |
411 | trait Trait<T> { | 411 | trait Trait<T> { |
412 | fn method(&self) -> T; | 412 | fn method(&self) -> T; |
413 | } | 413 | } |
414 | struct S<T>(T); | 414 | struct S<T>(T); |
415 | impl<U> Trait<U> for S<U> {} | 415 | impl<U> Trait<U> for S<U> {} |
416 | fn test() { | 416 | fn test() { |
417 | S(1u32).method(); | 417 | S(1u32).method(); |
418 | } | 418 | } |
419 | "#), | 419 | "#, |
420 | @r###" | 420 | expect![[r#" |
421 | 32..36 'self': &Self | 421 | 32..36 'self': &Self |
422 | 101..126 '{ ...d(); }': () | 422 | 101..126 '{ ...d(); }': () |
423 | 107..108 'S': S<u32>(u32) -> S<u32> | 423 | 107..108 'S': S<u32>(u32) -> S<u32> |
424 | 107..114 'S(1u32)': S<u32> | 424 | 107..114 'S(1u32)': S<u32> |
425 | 107..123 'S(1u32...thod()': u32 | 425 | 107..123 'S(1u32...thod()': u32 |
426 | 109..113 '1u32': u32 | 426 | 109..113 '1u32': u32 |
427 | "### | 427 | "#]], |
428 | ); | 428 | ); |
429 | } | 429 | } |
430 | 430 | ||
431 | #[test] | 431 | #[test] |
432 | fn infer_trait_assoc_method() { | 432 | fn infer_trait_assoc_method() { |
433 | assert_snapshot!( | 433 | check_infer( |
434 | infer(r#" | 434 | r#" |
435 | trait Default { | 435 | trait Default { |
436 | fn default() -> Self; | 436 | fn default() -> Self; |
437 | } | 437 | } |
438 | struct S; | 438 | struct S; |
439 | impl Default for S {} | 439 | impl Default for S {} |
440 | fn test() { | 440 | fn test() { |
441 | let s1: S = Default::default(); | 441 | let s1: S = Default::default(); |
442 | let s2 = S::default(); | 442 | let s2 = S::default(); |
443 | let s3 = <S as Default>::default(); | 443 | let s3 = <S as Default>::default(); |
444 | } | 444 | } |
445 | "#), | 445 | "#, |
446 | @r###" | 446 | expect![[r#" |
447 | 86..192 '{ ...t(); }': () | 447 | 86..192 '{ ...t(); }': () |
448 | 96..98 's1': S | 448 | 96..98 's1': S |
449 | 104..120 'Defaul...efault': fn default<S>() -> S | 449 | 104..120 'Defaul...efault': fn default<S>() -> S |
450 | 104..122 'Defaul...ault()': S | 450 | 104..122 'Defaul...ault()': S |
451 | 132..134 's2': S | 451 | 132..134 's2': S |
452 | 137..147 'S::default': fn default<S>() -> S | 452 | 137..147 'S::default': fn default<S>() -> S |
453 | 137..149 'S::default()': S | 453 | 137..149 'S::default()': S |
454 | 159..161 's3': S | 454 | 159..161 's3': S |
455 | 164..187 '<S as ...efault': fn default<S>() -> S | 455 | 164..187 '<S as ...efault': fn default<S>() -> S |
456 | 164..189 '<S as ...ault()': S | 456 | 164..189 '<S as ...ault()': S |
457 | "### | 457 | "#]], |
458 | ); | 458 | ); |
459 | } | 459 | } |
460 | 460 | ||
461 | #[test] | 461 | #[test] |
462 | fn infer_trait_assoc_method_generics_1() { | 462 | fn infer_trait_assoc_method_generics_1() { |
463 | assert_snapshot!( | 463 | check_infer( |
464 | infer(r#" | 464 | r#" |
465 | trait Trait<T> { | 465 | trait Trait<T> { |
466 | fn make() -> T; | 466 | fn make() -> T; |
467 | } | 467 | } |
468 | struct S; | 468 | struct S; |
469 | impl Trait<u32> for S {} | 469 | impl Trait<u32> for S {} |
470 | struct G<T>; | 470 | struct G<T>; |
471 | impl<T> Trait<T> for G<T> {} | 471 | impl<T> Trait<T> for G<T> {} |
472 | fn test() { | 472 | fn test() { |
473 | let a = S::make(); | 473 | let a = S::make(); |
474 | let b = G::<u64>::make(); | 474 | let b = G::<u64>::make(); |
475 | let c: f64 = G::make(); | 475 | let c: f64 = G::make(); |
476 | } | 476 | } |
477 | "#), | 477 | "#, |
478 | @r###" | 478 | expect![[r#" |
479 | 126..210 '{ ...e(); }': () | 479 | 126..210 '{ ...e(); }': () |
480 | 136..137 'a': u32 | 480 | 136..137 'a': u32 |
481 | 140..147 'S::make': fn make<S, u32>() -> u32 | 481 | 140..147 'S::make': fn make<S, u32>() -> u32 |
482 | 140..149 'S::make()': u32 | 482 | 140..149 'S::make()': u32 |
483 | 159..160 'b': u64 | 483 | 159..160 'b': u64 |
484 | 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64 | 484 | 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64 |
485 | 163..179 'G::<u6...make()': u64 | 485 | 163..179 'G::<u6...make()': u64 |
486 | 189..190 'c': f64 | 486 | 189..190 'c': f64 |
487 | 198..205 'G::make': fn make<G<f64>, f64>() -> f64 | 487 | 198..205 'G::make': fn make<G<f64>, f64>() -> f64 |
488 | 198..207 'G::make()': f64 | 488 | 198..207 'G::make()': f64 |
489 | "### | 489 | "#]], |
490 | ); | 490 | ); |
491 | } | 491 | } |
492 | 492 | ||
493 | #[test] | 493 | #[test] |
494 | fn infer_trait_assoc_method_generics_2() { | 494 | fn infer_trait_assoc_method_generics_2() { |
495 | assert_snapshot!( | 495 | check_infer( |
496 | infer(r#" | 496 | r#" |
497 | trait Trait<T> { | 497 | trait Trait<T> { |
498 | fn make<U>() -> (T, U); | 498 | fn make<U>() -> (T, U); |
499 | } | 499 | } |
500 | struct S; | 500 | struct S; |
501 | impl Trait<u32> for S {} | 501 | impl Trait<u32> for S {} |
502 | struct G<T>; | 502 | struct G<T>; |
503 | impl<T> Trait<T> for G<T> {} | 503 | impl<T> Trait<T> for G<T> {} |
504 | fn test() { | 504 | fn test() { |
505 | let a = S::make::<i64>(); | 505 | let a = S::make::<i64>(); |
506 | let b: (_, i64) = S::make(); | 506 | let b: (_, i64) = S::make(); |
507 | let c = G::<u32>::make::<i64>(); | 507 | let c = G::<u32>::make::<i64>(); |
508 | let d: (u32, _) = G::make::<i64>(); | 508 | let d: (u32, _) = G::make::<i64>(); |
509 | let e: (u32, i64) = G::make(); | 509 | let e: (u32, i64) = G::make(); |
510 | } | 510 | } |
511 | "#), | 511 | "#, |
512 | @r###" | 512 | expect![[r#" |
513 | 134..312 '{ ...e(); }': () | 513 | 134..312 '{ ...e(); }': () |
514 | 144..145 'a': (u32, i64) | 514 | 144..145 'a': (u32, i64) |
515 | 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64) | 515 | 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64) |
516 | 148..164 'S::mak...i64>()': (u32, i64) | 516 | 148..164 'S::mak...i64>()': (u32, i64) |
517 | 174..175 'b': (u32, i64) | 517 | 174..175 'b': (u32, i64) |
518 | 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64) | 518 | 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64) |
519 | 188..197 'S::make()': (u32, i64) | 519 | 188..197 'S::make()': (u32, i64) |
520 | 207..208 'c': (u32, i64) | 520 | 207..208 'c': (u32, i64) |
521 | 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) | 521 | 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) |
522 | 211..234 'G::<u3...i64>()': (u32, i64) | 522 | 211..234 'G::<u3...i64>()': (u32, i64) |
523 | 244..245 'd': (u32, i64) | 523 | 244..245 'd': (u32, i64) |
524 | 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) | 524 | 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) |
525 | 258..274 'G::mak...i64>()': (u32, i64) | 525 | 258..274 'G::mak...i64>()': (u32, i64) |
526 | 284..285 'e': (u32, i64) | 526 | 284..285 'e': (u32, i64) |
527 | 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64) | 527 | 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64) |
528 | 300..309 'G::make()': (u32, i64) | 528 | 300..309 'G::make()': (u32, i64) |
529 | "### | 529 | "#]], |
530 | ); | 530 | ); |
531 | } | 531 | } |
532 | 532 | ||
533 | #[test] | 533 | #[test] |
534 | fn infer_trait_assoc_method_generics_3() { | 534 | fn infer_trait_assoc_method_generics_3() { |
535 | assert_snapshot!( | 535 | check_infer( |
536 | infer(r#" | 536 | r#" |
537 | trait Trait<T> { | 537 | trait Trait<T> { |
538 | fn make() -> (Self, T); | 538 | fn make() -> (Self, T); |
539 | } | 539 | } |
540 | struct S<T>; | 540 | struct S<T>; |
541 | impl Trait<i64> for S<i32> {} | 541 | impl Trait<i64> for S<i32> {} |
542 | fn test() { | 542 | fn test() { |
543 | let a = S::make(); | 543 | let a = S::make(); |
544 | } | 544 | } |
545 | "#), | 545 | "#, |
546 | @r###" | 546 | expect![[r#" |
547 | 100..126 '{ ...e(); }': () | 547 | 100..126 '{ ...e(); }': () |
548 | 110..111 'a': (S<i32>, i64) | 548 | 110..111 'a': (S<i32>, i64) |
549 | 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64) | 549 | 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64) |
550 | 114..123 'S::make()': (S<i32>, i64) | 550 | 114..123 'S::make()': (S<i32>, i64) |
551 | "### | 551 | "#]], |
552 | ); | 552 | ); |
553 | } | 553 | } |
554 | 554 | ||
555 | #[test] | 555 | #[test] |
556 | fn infer_trait_assoc_method_generics_4() { | 556 | fn infer_trait_assoc_method_generics_4() { |
557 | assert_snapshot!( | 557 | check_infer( |
558 | infer(r#" | 558 | r#" |
559 | trait Trait<T> { | 559 | trait Trait<T> { |
560 | fn make() -> (Self, T); | 560 | fn make() -> (Self, T); |
561 | } | 561 | } |
562 | struct S<T>; | 562 | struct S<T>; |
563 | impl Trait<i64> for S<u64> {} | 563 | impl Trait<i64> for S<u64> {} |
564 | impl Trait<i32> for S<u32> {} | 564 | impl Trait<i32> for S<u32> {} |
565 | fn test() { | 565 | fn test() { |
566 | let a: (S<u64>, _) = S::make(); | 566 | let a: (S<u64>, _) = S::make(); |
567 | let b: (_, i32) = S::make(); | 567 | let b: (_, i32) = S::make(); |
568 | } | 568 | } |
569 | "#), | 569 | "#, |
570 | @r###" | 570 | expect![[r#" |
571 | 130..202 '{ ...e(); }': () | 571 | 130..202 '{ ...e(); }': () |
572 | 140..141 'a': (S<u64>, i64) | 572 | 140..141 'a': (S<u64>, i64) |
573 | 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64) | 573 | 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64) |
574 | 157..166 'S::make()': (S<u64>, i64) | 574 | 157..166 'S::make()': (S<u64>, i64) |
575 | 176..177 'b': (S<u32>, i32) | 575 | 176..177 'b': (S<u32>, i32) |
576 | 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32) | 576 | 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32) |
577 | 190..199 'S::make()': (S<u32>, i32) | 577 | 190..199 'S::make()': (S<u32>, i32) |
578 | "### | 578 | "#]], |
579 | ); | 579 | ); |
580 | } | 580 | } |
581 | 581 | ||
582 | #[test] | 582 | #[test] |
583 | fn infer_trait_assoc_method_generics_5() { | 583 | fn infer_trait_assoc_method_generics_5() { |
584 | assert_snapshot!( | 584 | check_infer( |
585 | infer(r#" | 585 | r#" |
586 | trait Trait<T> { | 586 | trait Trait<T> { |
587 | fn make<U>() -> (Self, T, U); | 587 | fn make<U>() -> (Self, T, U); |
588 | } | 588 | } |
589 | struct S<T>; | 589 | struct S<T>; |
590 | impl Trait<i64> for S<u64> {} | 590 | impl Trait<i64> for S<u64> {} |
591 | fn test() { | 591 | fn test() { |
592 | let a = <S as Trait<i64>>::make::<u8>(); | 592 | let a = <S as Trait<i64>>::make::<u8>(); |
593 | let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>(); | 593 | let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>(); |
594 | } | 594 | } |
595 | "#), | 595 | "#, |
596 | @r###" | 596 | expect![[r#" |
597 | 106..210 '{ ...>(); }': () | 597 | 106..210 '{ ...>(); }': () |
598 | 116..117 'a': (S<u64>, i64, u8) | 598 | 116..117 'a': (S<u64>, i64, u8) |
599 | 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) | 599 | 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) |
600 | 120..151 '<S as ...<u8>()': (S<u64>, i64, u8) | 600 | 120..151 '<S as ...<u8>()': (S<u64>, i64, u8) |
601 | 161..162 'b': (S<u64>, i64, u8) | 601 | 161..162 'b': (S<u64>, i64, u8) |
602 | 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) | 602 | 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) |
603 | 181..207 'Trait:...<u8>()': (S<u64>, i64, u8) | 603 | 181..207 'Trait:...<u8>()': (S<u64>, i64, u8) |
604 | "### | 604 | "#]], |
605 | ); | 605 | ); |
606 | } | 606 | } |
607 | 607 | ||
608 | #[test] | 608 | #[test] |
609 | fn infer_call_trait_method_on_generic_param_1() { | 609 | fn infer_call_trait_method_on_generic_param_1() { |
610 | assert_snapshot!( | 610 | check_infer( |
611 | infer(r#" | 611 | r#" |
612 | trait Trait { | 612 | trait Trait { |
613 | fn method(&self) -> u32; | 613 | fn method(&self) -> u32; |
614 | } | 614 | } |
615 | fn test<T: Trait>(t: T) { | 615 | fn test<T: Trait>(t: T) { |
616 | t.method(); | 616 | t.method(); |
617 | } | 617 | } |
618 | "#), | 618 | "#, |
619 | @r###" | 619 | expect![[r#" |
620 | 29..33 'self': &Self | 620 | 29..33 'self': &Self |
621 | 63..64 't': T | 621 | 63..64 't': T |
622 | 69..88 '{ ...d(); }': () | 622 | 69..88 '{ ...d(); }': () |
623 | 75..76 't': T | 623 | 75..76 't': T |
624 | 75..85 't.method()': u32 | 624 | 75..85 't.method()': u32 |
625 | "### | 625 | "#]], |
626 | ); | 626 | ); |
627 | } | 627 | } |
628 | 628 | ||
629 | #[test] | 629 | #[test] |
630 | fn infer_call_trait_method_on_generic_param_2() { | 630 | fn infer_call_trait_method_on_generic_param_2() { |
631 | assert_snapshot!( | 631 | check_infer( |
632 | infer(r#" | 632 | r#" |
633 | trait Trait<T> { | 633 | trait Trait<T> { |
634 | fn method(&self) -> T; | 634 | fn method(&self) -> T; |
635 | } | 635 | } |
636 | fn test<U, T: Trait<U>>(t: T) { | 636 | fn test<U, T: Trait<U>>(t: T) { |
637 | t.method(); | 637 | t.method(); |
638 | } | 638 | } |
639 | "#), | 639 | "#, |
640 | @r###" | 640 | expect![[r#" |
641 | 32..36 'self': &Self | 641 | 32..36 'self': &Self |
642 | 70..71 't': T | 642 | 70..71 't': T |
643 | 76..95 '{ ...d(); }': () | 643 | 76..95 '{ ...d(); }': () |
644 | 82..83 't': T | 644 | 82..83 't': T |
645 | 82..92 't.method()': U | 645 | 82..92 't.method()': U |
646 | "### | 646 | "#]], |
647 | ); | 647 | ); |
648 | } | 648 | } |
649 | 649 | ||
650 | #[test] | 650 | #[test] |
651 | fn infer_with_multiple_trait_impls() { | 651 | fn infer_with_multiple_trait_impls() { |
652 | assert_snapshot!( | 652 | check_infer( |
653 | infer(r#" | 653 | r#" |
654 | trait Into<T> { | 654 | trait Into<T> { |
655 | fn into(self) -> T; | 655 | fn into(self) -> T; |
656 | } | 656 | } |
657 | struct S; | 657 | struct S; |
658 | impl Into<u32> for S {} | 658 | impl Into<u32> for S {} |
659 | impl Into<u64> for S {} | 659 | impl Into<u64> for S {} |
660 | fn test() { | 660 | fn test() { |
661 | let x: u32 = S.into(); | 661 | let x: u32 = S.into(); |
662 | let y: u64 = S.into(); | 662 | let y: u64 = S.into(); |
663 | let z = Into::<u64>::into(S); | 663 | let z = Into::<u64>::into(S); |
664 | } | 664 | } |
665 | "#), | 665 | "#, |
666 | @r###" | 666 | expect![[r#" |
667 | 28..32 'self': Self | 667 | 28..32 'self': Self |
668 | 110..201 '{ ...(S); }': () | 668 | 110..201 '{ ...(S); }': () |
669 | 120..121 'x': u32 | 669 | 120..121 'x': u32 |
670 | 129..130 'S': S | 670 | 129..130 'S': S |
671 | 129..137 'S.into()': u32 | 671 | 129..137 'S.into()': u32 |
672 | 147..148 'y': u64 | 672 | 147..148 'y': u64 |
673 | 156..157 'S': S | 673 | 156..157 'S': S |
674 | 156..164 'S.into()': u64 | 674 | 156..164 'S.into()': u64 |
675 | 174..175 'z': u64 | 675 | 174..175 'z': u64 |
676 | 178..195 'Into::...::into': fn into<S, u64>(S) -> u64 | 676 | 178..195 'Into::...::into': fn into<S, u64>(S) -> u64 |
677 | 178..198 'Into::...nto(S)': u64 | 677 | 178..198 'Into::...nto(S)': u64 |
678 | 196..197 'S': S | 678 | 196..197 'S': S |
679 | "### | 679 | "#]], |
680 | ); | 680 | ); |
681 | } | 681 | } |
682 | 682 | ||
@@ -1023,31 +1023,31 @@ fn test() { (S {}).method(); } | |||
1023 | 1023 | ||
1024 | #[test] | 1024 | #[test] |
1025 | fn dyn_trait_super_trait_not_in_scope() { | 1025 | fn dyn_trait_super_trait_not_in_scope() { |
1026 | assert_snapshot!( | 1026 | check_infer( |
1027 | infer(r#" | 1027 | r#" |
1028 | mod m { | 1028 | mod m { |
1029 | pub trait SuperTrait { | 1029 | pub trait SuperTrait { |
1030 | fn foo(&self) -> u32 { 0 } | 1030 | fn foo(&self) -> u32 { 0 } |
1031 | } | 1031 | } |
1032 | } | 1032 | } |
1033 | trait Trait: m::SuperTrait {} | 1033 | trait Trait: m::SuperTrait {} |
1034 | 1034 | ||
1035 | struct S; | 1035 | struct S; |
1036 | impl m::SuperTrait for S {} | 1036 | impl m::SuperTrait for S {} |
1037 | impl Trait for S {} | 1037 | impl Trait for S {} |
1038 | 1038 | ||
1039 | fn test(d: &dyn Trait) { | 1039 | fn test(d: &dyn Trait) { |
1040 | d.foo(); | 1040 | d.foo(); |
1041 | } | 1041 | } |
1042 | "#), | 1042 | "#, |
1043 | @r###" | 1043 | expect![[r#" |
1044 | 51..55 'self': &Self | 1044 | 51..55 'self': &Self |
1045 | 64..69 '{ 0 }': u32 | 1045 | 64..69 '{ 0 }': u32 |
1046 | 66..67 '0': u32 | 1046 | 66..67 '0': u32 |
1047 | 176..177 'd': &dyn Trait | 1047 | 176..177 'd': &dyn Trait |
1048 | 191..207 '{ ...o(); }': () | 1048 | 191..207 '{ ...o(); }': () |
1049 | 197..198 'd': &dyn Trait | 1049 | 197..198 'd': &dyn Trait |
1050 | 197..204 'd.foo()': u32 | 1050 | 197..204 'd.foo()': u32 |
1051 | "### | 1051 | "#]], |
1052 | ); | 1052 | ); |
1053 | } | 1053 | } |
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 | } |
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index f937426bd..39fabf7eb 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs | |||
@@ -1,561 +1,561 @@ | |||
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, infer_with_mismatches}; | 4 | use super::{check_infer, check_infer_with_mismatches}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn infer_pattern() { | 7 | fn infer_pattern() { |
8 | assert_snapshot!( | 8 | check_infer( |
9 | infer(r#" | 9 | r#" |
10 | fn test(x: &i32) { | 10 | fn test(x: &i32) { |
11 | let y = x; | 11 | let y = x; |
12 | let &z = x; | 12 | let &z = x; |
13 | let a = z; | 13 | let a = z; |
14 | let (c, d) = (1, "hello"); | 14 | let (c, d) = (1, "hello"); |
15 | 15 | ||
16 | for (e, f) in some_iter { | 16 | for (e, f) in some_iter { |
17 | let g = e; | 17 | let g = e; |
18 | } | 18 | } |
19 | 19 | ||
20 | if let [val] = opt { | 20 | if let [val] = opt { |
21 | let h = val; | 21 | let h = val; |
22 | } | 22 | } |
23 | 23 | ||
24 | let lambda = |a: u64, b, c: i32| { a + b; c }; | 24 | let lambda = |a: u64, b, c: i32| { a + b; c }; |
25 | 25 | ||
26 | let ref ref_to_x = x; | 26 | let ref ref_to_x = x; |
27 | let mut mut_x = x; | 27 | let mut mut_x = x; |
28 | let ref mut mut_ref_to_x = x; | 28 | let ref mut mut_ref_to_x = x; |
29 | let k = mut_ref_to_x; | 29 | let k = mut_ref_to_x; |
30 | } | 30 | } |
31 | "#), | 31 | "#, |
32 | @r###" | 32 | expect![[r#" |
33 | 8..9 'x': &i32 | 33 | 8..9 'x': &i32 |
34 | 17..368 '{ ...o_x; }': () | 34 | 17..368 '{ ...o_x; }': () |
35 | 27..28 'y': &i32 | 35 | 27..28 'y': &i32 |
36 | 31..32 'x': &i32 | 36 | 31..32 'x': &i32 |
37 | 42..44 '&z': &i32 | 37 | 42..44 '&z': &i32 |
38 | 43..44 'z': i32 | 38 | 43..44 'z': i32 |
39 | 47..48 'x': &i32 | 39 | 47..48 'x': &i32 |
40 | 58..59 'a': i32 | 40 | 58..59 'a': i32 |
41 | 62..63 'z': i32 | 41 | 62..63 'z': i32 |
42 | 73..79 '(c, d)': (i32, &str) | 42 | 73..79 '(c, d)': (i32, &str) |
43 | 74..75 'c': i32 | 43 | 74..75 'c': i32 |
44 | 77..78 'd': &str | 44 | 77..78 'd': &str |
45 | 82..94 '(1, "hello")': (i32, &str) | 45 | 82..94 '(1, "hello")': (i32, &str) |
46 | 83..84 '1': i32 | 46 | 83..84 '1': i32 |
47 | 86..93 '"hello"': &str | 47 | 86..93 '"hello"': &str |
48 | 101..151 'for (e... }': () | 48 | 101..151 'for (e... }': () |
49 | 105..111 '(e, f)': ({unknown}, {unknown}) | 49 | 105..111 '(e, f)': ({unknown}, {unknown}) |
50 | 106..107 'e': {unknown} | 50 | 106..107 'e': {unknown} |
51 | 109..110 'f': {unknown} | 51 | 109..110 'f': {unknown} |
52 | 115..124 'some_iter': {unknown} | 52 | 115..124 'some_iter': {unknown} |
53 | 125..151 '{ ... }': () | 53 | 125..151 '{ ... }': () |
54 | 139..140 'g': {unknown} | 54 | 139..140 'g': {unknown} |
55 | 143..144 'e': {unknown} | 55 | 143..144 'e': {unknown} |
56 | 157..204 'if let... }': () | 56 | 157..204 'if let... }': () |
57 | 164..169 '[val]': [{unknown}] | 57 | 164..169 '[val]': [{unknown}] |
58 | 165..168 'val': {unknown} | 58 | 165..168 'val': {unknown} |
59 | 172..175 'opt': [{unknown}] | 59 | 172..175 'opt': [{unknown}] |
60 | 176..204 '{ ... }': () | 60 | 176..204 '{ ... }': () |
61 | 190..191 'h': {unknown} | 61 | 190..191 'h': {unknown} |
62 | 194..197 'val': {unknown} | 62 | 194..197 'val': {unknown} |
63 | 214..220 'lambda': |u64, u64, i32| -> i32 | 63 | 214..220 'lambda': |u64, u64, i32| -> i32 |
64 | 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 | 64 | 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 |
65 | 224..225 'a': u64 | 65 | 224..225 'a': u64 |
66 | 232..233 'b': u64 | 66 | 232..233 'b': u64 |
67 | 235..236 'c': i32 | 67 | 235..236 'c': i32 |
68 | 243..255 '{ a + b; c }': i32 | 68 | 243..255 '{ a + b; c }': i32 |
69 | 245..246 'a': u64 | 69 | 245..246 'a': u64 |
70 | 245..250 'a + b': u64 | 70 | 245..250 'a + b': u64 |
71 | 249..250 'b': u64 | 71 | 249..250 'b': u64 |
72 | 252..253 'c': i32 | 72 | 252..253 'c': i32 |
73 | 266..278 'ref ref_to_x': &&i32 | 73 | 266..278 'ref ref_to_x': &&i32 |
74 | 281..282 'x': &i32 | 74 | 281..282 'x': &i32 |
75 | 292..301 'mut mut_x': &i32 | 75 | 292..301 'mut mut_x': &i32 |
76 | 304..305 'x': &i32 | 76 | 304..305 'x': &i32 |
77 | 315..335 'ref mu...f_to_x': &mut &i32 | 77 | 315..335 'ref mu...f_to_x': &mut &i32 |
78 | 338..339 'x': &i32 | 78 | 338..339 'x': &i32 |
79 | 349..350 'k': &mut &i32 | 79 | 349..350 'k': &mut &i32 |
80 | 353..365 'mut_ref_to_x': &mut &i32 | 80 | 353..365 'mut_ref_to_x': &mut &i32 |
81 | "### | 81 | "#]], |
82 | ); | 82 | ); |
83 | } | 83 | } |
84 | 84 | ||
85 | #[test] | 85 | #[test] |
86 | fn infer_literal_pattern() { | 86 | fn infer_literal_pattern() { |
87 | assert_snapshot!( | 87 | check_infer_with_mismatches( |
88 | infer_with_mismatches(r#" | 88 | r#" |
89 | fn any<T>() -> T { loop {} } | 89 | fn any<T>() -> T { loop {} } |
90 | fn test(x: &i32) { | 90 | fn test(x: &i32) { |
91 | if let "foo" = any() {} | 91 | if let "foo" = any() {} |
92 | if let 1 = any() {} | 92 | if let 1 = any() {} |
93 | if let 1u32 = any() {} | 93 | if let 1u32 = any() {} |
94 | if let 1f32 = any() {} | 94 | if let 1f32 = any() {} |
95 | if let 1.0 = any() {} | 95 | if let 1.0 = any() {} |
96 | if let true = any() {} | 96 | if let true = any() {} |
97 | } | 97 | } |
98 | "#, true), | 98 | "#, |
99 | @r###" | 99 | expect![[r#" |
100 | 17..28 '{ loop {} }': T | 100 | 17..28 '{ loop {} }': T |
101 | 19..26 'loop {}': ! | 101 | 19..26 'loop {}': ! |
102 | 24..26 '{}': () | 102 | 24..26 '{}': () |
103 | 37..38 'x': &i32 | 103 | 37..38 'x': &i32 |
104 | 46..208 '{ ...) {} }': () | 104 | 46..208 '{ ...) {} }': () |
105 | 52..75 'if let...y() {}': () | 105 | 52..75 'if let...y() {}': () |
106 | 59..64 '"foo"': &str | 106 | 59..64 '"foo"': &str |
107 | 59..64 '"foo"': &str | 107 | 59..64 '"foo"': &str |
108 | 67..70 'any': fn any<&str>() -> &str | 108 | 67..70 'any': fn any<&str>() -> &str |
109 | 67..72 'any()': &str | 109 | 67..72 'any()': &str |
110 | 73..75 '{}': () | 110 | 73..75 '{}': () |
111 | 80..99 'if let...y() {}': () | 111 | 80..99 'if let...y() {}': () |
112 | 87..88 '1': i32 | 112 | 87..88 '1': i32 |
113 | 87..88 '1': i32 | 113 | 87..88 '1': i32 |
114 | 91..94 'any': fn any<i32>() -> i32 | 114 | 91..94 'any': fn any<i32>() -> i32 |
115 | 91..96 'any()': i32 | 115 | 91..96 'any()': i32 |
116 | 97..99 '{}': () | 116 | 97..99 '{}': () |
117 | 104..126 'if let...y() {}': () | 117 | 104..126 'if let...y() {}': () |
118 | 111..115 '1u32': u32 | 118 | 111..115 '1u32': u32 |
119 | 111..115 '1u32': u32 | 119 | 111..115 '1u32': u32 |
120 | 118..121 'any': fn any<u32>() -> u32 | 120 | 118..121 'any': fn any<u32>() -> u32 |
121 | 118..123 'any()': u32 | 121 | 118..123 'any()': u32 |
122 | 124..126 '{}': () | 122 | 124..126 '{}': () |
123 | 131..153 'if let...y() {}': () | 123 | 131..153 'if let...y() {}': () |
124 | 138..142 '1f32': f32 | 124 | 138..142 '1f32': f32 |
125 | 138..142 '1f32': f32 | 125 | 138..142 '1f32': f32 |
126 | 145..148 'any': fn any<f32>() -> f32 | 126 | 145..148 'any': fn any<f32>() -> f32 |
127 | 145..150 'any()': f32 | 127 | 145..150 'any()': f32 |
128 | 151..153 '{}': () | 128 | 151..153 '{}': () |
129 | 158..179 'if let...y() {}': () | 129 | 158..179 'if let...y() {}': () |
130 | 165..168 '1.0': f64 | 130 | 165..168 '1.0': f64 |
131 | 165..168 '1.0': f64 | 131 | 165..168 '1.0': f64 |
132 | 171..174 'any': fn any<f64>() -> f64 | 132 | 171..174 'any': fn any<f64>() -> f64 |
133 | 171..176 'any()': f64 | 133 | 171..176 'any()': f64 |
134 | 177..179 '{}': () | 134 | 177..179 '{}': () |
135 | 184..206 'if let...y() {}': () | 135 | 184..206 'if let...y() {}': () |
136 | 191..195 'true': bool | 136 | 191..195 'true': bool |
137 | 191..195 'true': bool | 137 | 191..195 'true': bool |
138 | 198..201 'any': fn any<bool>() -> bool | 138 | 198..201 'any': fn any<bool>() -> bool |
139 | 198..203 'any()': bool | 139 | 198..203 'any()': bool |
140 | 204..206 '{}': () | 140 | 204..206 '{}': () |
141 | "### | 141 | "#]], |
142 | ); | 142 | ); |
143 | } | 143 | } |
144 | 144 | ||
145 | #[test] | 145 | #[test] |
146 | fn infer_range_pattern() { | 146 | fn infer_range_pattern() { |
147 | assert_snapshot!( | 147 | check_infer_with_mismatches( |
148 | infer_with_mismatches(r#" | 148 | r#" |
149 | fn test(x: &i32) { | 149 | fn test(x: &i32) { |
150 | if let 1..76 = 2u32 {} | 150 | if let 1..76 = 2u32 {} |
151 | if let 1..=76 = 2u32 {} | 151 | if let 1..=76 = 2u32 {} |
152 | } | 152 | } |
153 | "#, true), | 153 | "#, |
154 | @r###" | 154 | expect![[r#" |
155 | 8..9 'x': &i32 | 155 | 8..9 'x': &i32 |
156 | 17..75 '{ ...2 {} }': () | 156 | 17..75 '{ ...2 {} }': () |
157 | 23..45 'if let...u32 {}': () | 157 | 23..45 'if let...u32 {}': () |
158 | 30..35 '1..76': u32 | 158 | 30..35 '1..76': u32 |
159 | 38..42 '2u32': u32 | 159 | 38..42 '2u32': u32 |
160 | 43..45 '{}': () | 160 | 43..45 '{}': () |
161 | 50..73 'if let...u32 {}': () | 161 | 50..73 'if let...u32 {}': () |
162 | 57..63 '1..=76': u32 | 162 | 57..63 '1..=76': u32 |
163 | 66..70 '2u32': u32 | 163 | 66..70 '2u32': u32 |
164 | 71..73 '{}': () | 164 | 71..73 '{}': () |
165 | "### | 165 | "#]], |
166 | ); | 166 | ); |
167 | } | 167 | } |
168 | 168 | ||
169 | #[test] | 169 | #[test] |
170 | fn infer_pattern_match_ergonomics() { | 170 | fn infer_pattern_match_ergonomics() { |
171 | assert_snapshot!( | 171 | check_infer( |
172 | infer(r#" | 172 | r#" |
173 | struct A<T>(T); | 173 | struct A<T>(T); |
174 | 174 | ||
175 | fn test() { | 175 | fn test() { |
176 | let A(n) = &A(1); | 176 | let A(n) = &A(1); |
177 | let A(n) = &mut A(1); | 177 | let A(n) = &mut A(1); |
178 | } | 178 | } |
179 | "#), | 179 | "#, |
180 | @r###" | 180 | expect![[r#" |
181 | 27..78 '{ ...(1); }': () | 181 | 27..78 '{ ...(1); }': () |
182 | 37..41 'A(n)': A<i32> | 182 | 37..41 'A(n)': A<i32> |
183 | 39..40 'n': &i32 | 183 | 39..40 'n': &i32 |
184 | 44..49 '&A(1)': &A<i32> | 184 | 44..49 '&A(1)': &A<i32> |
185 | 45..46 'A': A<i32>(i32) -> A<i32> | 185 | 45..46 'A': A<i32>(i32) -> A<i32> |
186 | 45..49 'A(1)': A<i32> | 186 | 45..49 'A(1)': A<i32> |
187 | 47..48 '1': i32 | 187 | 47..48 '1': i32 |
188 | 59..63 'A(n)': A<i32> | 188 | 59..63 'A(n)': A<i32> |
189 | 61..62 'n': &mut i32 | 189 | 61..62 'n': &mut i32 |
190 | 66..75 '&mut A(1)': &mut A<i32> | 190 | 66..75 '&mut A(1)': &mut A<i32> |
191 | 71..72 'A': A<i32>(i32) -> A<i32> | 191 | 71..72 'A': A<i32>(i32) -> A<i32> |
192 | 71..75 'A(1)': A<i32> | 192 | 71..75 'A(1)': A<i32> |
193 | 73..74 '1': i32 | 193 | 73..74 '1': i32 |
194 | "### | 194 | "#]], |
195 | ); | 195 | ); |
196 | } | 196 | } |
197 | 197 | ||
198 | #[test] | 198 | #[test] |
199 | fn infer_pattern_match_ergonomics_ref() { | 199 | fn infer_pattern_match_ergonomics_ref() { |
200 | mark::check!(match_ergonomics_ref); | 200 | mark::check!(match_ergonomics_ref); |
201 | assert_snapshot!( | 201 | check_infer( |
202 | infer(r#" | 202 | r#" |
203 | fn test() { | 203 | fn test() { |
204 | let v = &(1, &2); | 204 | let v = &(1, &2); |
205 | let (_, &w) = v; | 205 | let (_, &w) = v; |
206 | } | 206 | } |
207 | "#), | 207 | "#, |
208 | @r###" | 208 | expect![[r#" |
209 | 10..56 '{ ...= v; }': () | 209 | 10..56 '{ ...= v; }': () |
210 | 20..21 'v': &(i32, &i32) | 210 | 20..21 'v': &(i32, &i32) |
211 | 24..32 '&(1, &2)': &(i32, &i32) | 211 | 24..32 '&(1, &2)': &(i32, &i32) |
212 | 25..32 '(1, &2)': (i32, &i32) | 212 | 25..32 '(1, &2)': (i32, &i32) |
213 | 26..27 '1': i32 | 213 | 26..27 '1': i32 |
214 | 29..31 '&2': &i32 | 214 | 29..31 '&2': &i32 |
215 | 30..31 '2': i32 | 215 | 30..31 '2': i32 |
216 | 42..49 '(_, &w)': (i32, &i32) | 216 | 42..49 '(_, &w)': (i32, &i32) |
217 | 43..44 '_': i32 | 217 | 43..44 '_': i32 |
218 | 46..48 '&w': &i32 | 218 | 46..48 '&w': &i32 |
219 | 47..48 'w': i32 | 219 | 47..48 'w': i32 |
220 | 52..53 'v': &(i32, &i32) | 220 | 52..53 'v': &(i32, &i32) |
221 | "### | 221 | "#]], |
222 | ); | 222 | ); |
223 | } | 223 | } |
224 | 224 | ||
225 | #[test] | 225 | #[test] |
226 | fn infer_pattern_match_slice() { | 226 | fn infer_pattern_match_slice() { |
227 | assert_snapshot!( | 227 | check_infer( |
228 | infer(r#" | 228 | r#" |
229 | fn test() { | 229 | fn test() { |
230 | let slice: &[f64] = &[0.0]; | 230 | let slice: &[f64] = &[0.0]; |
231 | match slice { | 231 | match slice { |
232 | &[] => {}, | 232 | &[] => {}, |
233 | &[a] => { | 233 | &[a] => { |
234 | a; | 234 | a; |
235 | }, | 235 | }, |
236 | &[b, c] => { | 236 | &[b, c] => { |
237 | b; | 237 | b; |
238 | c; | 238 | c; |
239 | } | ||
240 | _ => {} | ||
241 | } | ||
239 | } | 242 | } |
240 | _ => {} | 243 | "#, |
241 | } | 244 | expect![[r#" |
242 | } | 245 | 10..209 '{ ... } }': () |
243 | "#), | 246 | 20..25 'slice': &[f64] |
244 | @r###" | 247 | 36..42 '&[0.0]': &[f64; _] |
245 | 10..209 '{ ... } }': () | 248 | 37..42 '[0.0]': [f64; _] |
246 | 20..25 'slice': &[f64] | 249 | 38..41 '0.0': f64 |
247 | 36..42 '&[0.0]': &[f64; _] | 250 | 48..207 'match ... }': () |
248 | 37..42 '[0.0]': [f64; _] | 251 | 54..59 'slice': &[f64] |
249 | 38..41 '0.0': f64 | 252 | 70..73 '&[]': &[f64] |
250 | 48..207 'match ... }': () | 253 | 71..73 '[]': [f64] |
251 | 54..59 'slice': &[f64] | 254 | 77..79 '{}': () |
252 | 70..73 '&[]': &[f64] | 255 | 89..93 '&[a]': &[f64] |
253 | 71..73 '[]': [f64] | 256 | 90..93 '[a]': [f64] |
254 | 77..79 '{}': () | 257 | 91..92 'a': f64 |
255 | 89..93 '&[a]': &[f64] | 258 | 97..123 '{ ... }': () |
256 | 90..93 '[a]': [f64] | 259 | 111..112 'a': f64 |
257 | 91..92 'a': f64 | 260 | 133..140 '&[b, c]': &[f64] |
258 | 97..123 '{ ... }': () | 261 | 134..140 '[b, c]': [f64] |
259 | 111..112 'a': f64 | 262 | 135..136 'b': f64 |
260 | 133..140 '&[b, c]': &[f64] | 263 | 138..139 'c': f64 |
261 | 134..140 '[b, c]': [f64] | 264 | 144..185 '{ ... }': () |
262 | 135..136 'b': f64 | 265 | 158..159 'b': f64 |
263 | 138..139 'c': f64 | 266 | 173..174 'c': f64 |
264 | 144..185 '{ ... }': () | 267 | 194..195 '_': &[f64] |
265 | 158..159 'b': f64 | 268 | 199..201 '{}': () |
266 | 173..174 'c': f64 | 269 | "#]], |
267 | 194..195 '_': &[f64] | ||
268 | 199..201 '{}': () | ||
269 | "### | ||
270 | ); | 270 | ); |
271 | } | 271 | } |
272 | 272 | ||
273 | #[test] | 273 | #[test] |
274 | fn infer_pattern_match_string_literal() { | 274 | fn infer_pattern_match_string_literal() { |
275 | assert_snapshot!( | 275 | check_infer_with_mismatches( |
276 | infer_with_mismatches(r#" | 276 | r#" |
277 | fn test() { | 277 | fn test() { |
278 | let s: &str = "hello"; | 278 | let s: &str = "hello"; |
279 | match s { | 279 | match s { |
280 | "hello" => {} | 280 | "hello" => {} |
281 | _ => {} | 281 | _ => {} |
282 | } | 282 | } |
283 | } | 283 | } |
284 | "#, true), | 284 | "#, |
285 | @r###" | 285 | expect![[r#" |
286 | 10..98 '{ ... } }': () | 286 | 10..98 '{ ... } }': () |
287 | 20..21 's': &str | 287 | 20..21 's': &str |
288 | 30..37 '"hello"': &str | 288 | 30..37 '"hello"': &str |
289 | 43..96 'match ... }': () | 289 | 43..96 'match ... }': () |
290 | 49..50 's': &str | 290 | 49..50 's': &str |
291 | 61..68 '"hello"': &str | 291 | 61..68 '"hello"': &str |
292 | 61..68 '"hello"': &str | 292 | 61..68 '"hello"': &str |
293 | 72..74 '{}': () | 293 | 72..74 '{}': () |
294 | 83..84 '_': &str | 294 | 83..84 '_': &str |
295 | 88..90 '{}': () | 295 | 88..90 '{}': () |
296 | "### | 296 | "#]], |
297 | ); | 297 | ); |
298 | } | 298 | } |
299 | 299 | ||
300 | #[test] | 300 | #[test] |
301 | fn infer_pattern_match_or() { | 301 | fn infer_pattern_match_or() { |
302 | assert_snapshot!( | 302 | check_infer_with_mismatches( |
303 | infer_with_mismatches(r#" | 303 | r#" |
304 | fn test() { | 304 | fn test() { |
305 | let s: &str = "hello"; | 305 | let s: &str = "hello"; |
306 | match s { | 306 | match s { |
307 | "hello" | "world" => {} | 307 | "hello" | "world" => {} |
308 | _ => {} | 308 | _ => {} |
309 | } | 309 | } |
310 | } | 310 | } |
311 | "#, true), | 311 | "#, |
312 | @r###" | 312 | expect![[r#" |
313 | 10..108 '{ ... } }': () | 313 | 10..108 '{ ... } }': () |
314 | 20..21 's': &str | 314 | 20..21 's': &str |
315 | 30..37 '"hello"': &str | 315 | 30..37 '"hello"': &str |
316 | 43..106 'match ... }': () | 316 | 43..106 'match ... }': () |
317 | 49..50 's': &str | 317 | 49..50 's': &str |
318 | 61..68 '"hello"': &str | 318 | 61..68 '"hello"': &str |
319 | 61..68 '"hello"': &str | 319 | 61..68 '"hello"': &str |
320 | 61..78 '"hello...world"': &str | 320 | 61..78 '"hello...world"': &str |
321 | 71..78 '"world"': &str | 321 | 71..78 '"world"': &str |
322 | 71..78 '"world"': &str | 322 | 71..78 '"world"': &str |
323 | 82..84 '{}': () | 323 | 82..84 '{}': () |
324 | 93..94 '_': &str | 324 | 93..94 '_': &str |
325 | 98..100 '{}': () | 325 | 98..100 '{}': () |
326 | "### | 326 | "#]], |
327 | ); | 327 | ); |
328 | } | 328 | } |
329 | 329 | ||
330 | #[test] | 330 | #[test] |
331 | fn infer_pattern_match_arr() { | 331 | fn infer_pattern_match_arr() { |
332 | assert_snapshot!( | 332 | check_infer( |
333 | infer(r#" | 333 | r#" |
334 | fn test() { | 334 | fn test() { |
335 | let arr: [f64; 2] = [0.0, 1.0]; | 335 | let arr: [f64; 2] = [0.0, 1.0]; |
336 | match arr { | 336 | match arr { |
337 | [1.0, a] => { | 337 | [1.0, a] => { |
338 | a; | 338 | a; |
339 | }, | 339 | }, |
340 | [b, c] => { | 340 | [b, c] => { |
341 | b; | 341 | b; |
342 | c; | 342 | c; |
343 | } | ||
344 | } | ||
343 | } | 345 | } |
344 | } | 346 | "#, |
345 | } | 347 | expect![[r#" |
346 | "#), | 348 | 10..179 '{ ... } }': () |
347 | @r###" | 349 | 20..23 'arr': [f64; _] |
348 | 10..179 '{ ... } }': () | 350 | 36..46 '[0.0, 1.0]': [f64; _] |
349 | 20..23 'arr': [f64; _] | 351 | 37..40 '0.0': f64 |
350 | 36..46 '[0.0, 1.0]': [f64; _] | 352 | 42..45 '1.0': f64 |
351 | 37..40 '0.0': f64 | 353 | 52..177 'match ... }': () |
352 | 42..45 '1.0': f64 | 354 | 58..61 'arr': [f64; _] |
353 | 52..177 'match ... }': () | 355 | 72..80 '[1.0, a]': [f64; _] |
354 | 58..61 'arr': [f64; _] | 356 | 73..76 '1.0': f64 |
355 | 72..80 '[1.0, a]': [f64; _] | 357 | 73..76 '1.0': f64 |
356 | 73..76 '1.0': f64 | 358 | 78..79 'a': f64 |
357 | 73..76 '1.0': f64 | 359 | 84..110 '{ ... }': () |
358 | 78..79 'a': f64 | 360 | 98..99 'a': f64 |
359 | 84..110 '{ ... }': () | 361 | 120..126 '[b, c]': [f64; _] |
360 | 98..99 'a': f64 | 362 | 121..122 'b': f64 |
361 | 120..126 '[b, c]': [f64; _] | 363 | 124..125 'c': f64 |
362 | 121..122 'b': f64 | 364 | 130..171 '{ ... }': () |
363 | 124..125 'c': f64 | 365 | 144..145 'b': f64 |
364 | 130..171 '{ ... }': () | 366 | 159..160 'c': f64 |
365 | 144..145 'b': f64 | 367 | "#]], |
366 | 159..160 'c': f64 | ||
367 | "### | ||
368 | ); | 368 | ); |
369 | } | 369 | } |
370 | 370 | ||
371 | #[test] | 371 | #[test] |
372 | fn infer_adt_pattern() { | 372 | fn infer_adt_pattern() { |
373 | assert_snapshot!( | 373 | check_infer( |
374 | infer(r#" | 374 | r#" |
375 | enum E { | 375 | enum E { |
376 | A { x: usize }, | 376 | A { x: usize }, |
377 | B | 377 | B |
378 | } | 378 | } |
379 | 379 | ||
380 | struct S(u32, E); | 380 | struct S(u32, E); |
381 | 381 | ||
382 | fn test() { | 382 | fn test() { |
383 | let e = E::A { x: 3 }; | 383 | let e = E::A { x: 3 }; |
384 | 384 | ||
385 | let S(y, z) = foo; | 385 | let S(y, z) = foo; |
386 | let E::A { x: new_var } = e; | 386 | let E::A { x: new_var } = e; |
387 | 387 | ||
388 | match e { | 388 | match e { |
389 | E::A { x } => x, | 389 | E::A { x } => x, |
390 | E::B if foo => 1, | 390 | E::B if foo => 1, |
391 | E::B => 10, | 391 | E::B => 10, |
392 | }; | 392 | }; |
393 | 393 | ||
394 | let ref d @ E::A { .. } = e; | 394 | let ref d @ E::A { .. } = e; |
395 | d; | 395 | d; |
396 | } | 396 | } |
397 | "#), | 397 | "#, |
398 | @r###" | 398 | expect![[r#" |
399 | 67..288 '{ ... d; }': () | 399 | 67..288 '{ ... d; }': () |
400 | 77..78 'e': E | 400 | 77..78 'e': E |
401 | 81..94 'E::A { x: 3 }': E | 401 | 81..94 'E::A { x: 3 }': E |
402 | 91..92 '3': usize | 402 | 91..92 '3': usize |
403 | 105..112 'S(y, z)': S | 403 | 105..112 'S(y, z)': S |
404 | 107..108 'y': u32 | 404 | 107..108 'y': u32 |
405 | 110..111 'z': E | 405 | 110..111 'z': E |
406 | 115..118 'foo': S | 406 | 115..118 'foo': S |
407 | 128..147 'E::A {..._var }': E | 407 | 128..147 'E::A {..._var }': E |
408 | 138..145 'new_var': usize | 408 | 138..145 'new_var': usize |
409 | 150..151 'e': E | 409 | 150..151 'e': E |
410 | 158..244 'match ... }': usize | 410 | 158..244 'match ... }': usize |
411 | 164..165 'e': E | 411 | 164..165 'e': E |
412 | 176..186 'E::A { x }': E | 412 | 176..186 'E::A { x }': E |
413 | 183..184 'x': usize | 413 | 183..184 'x': usize |
414 | 190..191 'x': usize | 414 | 190..191 'x': usize |
415 | 201..205 'E::B': E | 415 | 201..205 'E::B': E |
416 | 209..212 'foo': bool | 416 | 209..212 'foo': bool |
417 | 216..217 '1': usize | 417 | 216..217 '1': usize |
418 | 227..231 'E::B': E | 418 | 227..231 'E::B': E |
419 | 235..237 '10': usize | 419 | 235..237 '10': usize |
420 | 255..274 'ref d ...{ .. }': &E | 420 | 255..274 'ref d ...{ .. }': &E |
421 | 263..274 'E::A { .. }': E | 421 | 263..274 'E::A { .. }': E |
422 | 277..278 'e': E | 422 | 277..278 'e': E |
423 | 284..285 'd': &E | 423 | 284..285 'd': &E |
424 | "### | 424 | "#]], |
425 | ); | 425 | ); |
426 | } | 426 | } |
427 | 427 | ||
428 | #[test] | 428 | #[test] |
429 | fn enum_variant_through_self_in_pattern() { | 429 | fn enum_variant_through_self_in_pattern() { |
430 | assert_snapshot!( | 430 | check_infer( |
431 | infer(r#" | 431 | r#" |
432 | enum E { | 432 | enum E { |
433 | A { x: usize }, | 433 | A { x: usize }, |
434 | B(usize), | 434 | B(usize), |
435 | C | 435 | C |
436 | } | 436 | } |
437 | 437 | ||
438 | impl E { | 438 | impl E { |
439 | fn test() { | 439 | fn test() { |
440 | match (loop {}) { | 440 | match (loop {}) { |
441 | Self::A { x } => { x; }, | 441 | Self::A { x } => { x; }, |
442 | Self::B(x) => { x; }, | 442 | Self::B(x) => { x; }, |
443 | Self::C => {}, | 443 | Self::C => {}, |
444 | }; | 444 | }; |
445 | } | 445 | } |
446 | } | 446 | } |
447 | "#), | 447 | "#, |
448 | @r###" | 448 | expect![[r#" |
449 | 75..217 '{ ... }': () | 449 | 75..217 '{ ... }': () |
450 | 85..210 'match ... }': () | 450 | 85..210 'match ... }': () |
451 | 92..99 'loop {}': ! | 451 | 92..99 'loop {}': ! |
452 | 97..99 '{}': () | 452 | 97..99 '{}': () |
453 | 115..128 'Self::A { x }': E | 453 | 115..128 'Self::A { x }': E |
454 | 125..126 'x': usize | 454 | 125..126 'x': usize |
455 | 132..138 '{ x; }': () | 455 | 132..138 '{ x; }': () |
456 | 134..135 'x': usize | 456 | 134..135 'x': usize |
457 | 152..162 'Self::B(x)': E | 457 | 152..162 'Self::B(x)': E |
458 | 160..161 'x': usize | 458 | 160..161 'x': usize |
459 | 166..172 '{ x; }': () | 459 | 166..172 '{ x; }': () |
460 | 168..169 'x': usize | 460 | 168..169 'x': usize |
461 | 186..193 'Self::C': E | 461 | 186..193 'Self::C': E |
462 | 197..199 '{}': () | 462 | 197..199 '{}': () |
463 | "### | 463 | "#]], |
464 | ); | 464 | ); |
465 | } | 465 | } |
466 | 466 | ||
467 | #[test] | 467 | #[test] |
468 | fn infer_generics_in_patterns() { | 468 | fn infer_generics_in_patterns() { |
469 | assert_snapshot!( | 469 | check_infer( |
470 | infer(r#" | 470 | r#" |
471 | struct A<T> { | 471 | struct A<T> { |
472 | x: T, | 472 | x: T, |
473 | } | 473 | } |
474 | 474 | ||
475 | enum Option<T> { | 475 | enum Option<T> { |
476 | Some(T), | 476 | Some(T), |
477 | None, | 477 | None, |
478 | } | 478 | } |
479 | 479 | ||
480 | fn test(a1: A<u32>, o: Option<u64>) { | 480 | fn test(a1: A<u32>, o: Option<u64>) { |
481 | let A { x: x2 } = a1; | 481 | let A { x: x2 } = a1; |
482 | let A::<i64> { x: x3 } = A { x: 1 }; | 482 | let A::<i64> { x: x3 } = A { x: 1 }; |
483 | match o { | 483 | match o { |
484 | Option::Some(t) => t, | 484 | Option::Some(t) => t, |
485 | _ => 1, | 485 | _ => 1, |
486 | }; | 486 | }; |
487 | } | 487 | } |
488 | "#), | 488 | "#, |
489 | @r###" | 489 | expect![[r#" |
490 | 78..80 'a1': A<u32> | 490 | 78..80 'a1': A<u32> |
491 | 90..91 'o': Option<u64> | 491 | 90..91 'o': Option<u64> |
492 | 106..243 '{ ... }; }': () | 492 | 106..243 '{ ... }; }': () |
493 | 116..127 'A { x: x2 }': A<u32> | 493 | 116..127 'A { x: x2 }': A<u32> |
494 | 123..125 'x2': u32 | 494 | 123..125 'x2': u32 |
495 | 130..132 'a1': A<u32> | 495 | 130..132 'a1': A<u32> |
496 | 142..160 'A::<i6...: x3 }': A<i64> | 496 | 142..160 'A::<i6...: x3 }': A<i64> |
497 | 156..158 'x3': i64 | 497 | 156..158 'x3': i64 |
498 | 163..173 'A { x: 1 }': A<i64> | 498 | 163..173 'A { x: 1 }': A<i64> |
499 | 170..171 '1': i64 | 499 | 170..171 '1': i64 |
500 | 179..240 'match ... }': u64 | 500 | 179..240 'match ... }': u64 |
501 | 185..186 'o': Option<u64> | 501 | 185..186 'o': Option<u64> |
502 | 197..212 'Option::Some(t)': Option<u64> | 502 | 197..212 'Option::Some(t)': Option<u64> |
503 | 210..211 't': u64 | 503 | 210..211 't': u64 |
504 | 216..217 't': u64 | 504 | 216..217 't': u64 |
505 | 227..228 '_': Option<u64> | 505 | 227..228 '_': Option<u64> |
506 | 232..233 '1': u64 | 506 | 232..233 '1': u64 |
507 | "### | 507 | "#]], |
508 | ); | 508 | ); |
509 | } | 509 | } |
510 | 510 | ||
511 | #[test] | 511 | #[test] |
512 | fn infer_const_pattern() { | 512 | fn infer_const_pattern() { |
513 | assert_snapshot!( | 513 | check_infer_with_mismatches( |
514 | infer_with_mismatches(r#" | 514 | r#" |
515 | enum Option<T> { None } | 515 | enum Option<T> { None } |
516 | use Option::None; | 516 | use Option::None; |
517 | struct Foo; | 517 | struct Foo; |
518 | const Bar: usize = 1; | 518 | const Bar: usize = 1; |
519 | 519 | ||
520 | fn test() { | 520 | fn test() { |
521 | let a: Option<u32> = None; | 521 | let a: Option<u32> = None; |
522 | let b: Option<i64> = match a { | 522 | let b: Option<i64> = match a { |
523 | None => None, | 523 | None => None, |
524 | }; | 524 | }; |
525 | let _: () = match () { Foo => Foo }; // Expected mismatch | 525 | let _: () = match () { Foo => Foo }; // Expected mismatch |
526 | let _: () = match () { Bar => Bar }; // Expected mismatch | 526 | let _: () = match () { Bar => Bar }; // Expected mismatch |
527 | } | 527 | } |
528 | "#, true), | 528 | "#, |
529 | @r###" | 529 | expect![[r#" |
530 | 73..74 '1': usize | 530 | 73..74 '1': usize |
531 | 87..309 '{ ...atch }': () | 531 | 87..309 '{ ...atch }': () |
532 | 97..98 'a': Option<u32> | 532 | 97..98 'a': Option<u32> |
533 | 114..118 'None': Option<u32> | 533 | 114..118 'None': Option<u32> |
534 | 128..129 'b': Option<i64> | 534 | 128..129 'b': Option<i64> |
535 | 145..182 'match ... }': Option<i64> | 535 | 145..182 'match ... }': Option<i64> |
536 | 151..152 'a': Option<u32> | 536 | 151..152 'a': Option<u32> |
537 | 163..167 'None': Option<u32> | 537 | 163..167 'None': Option<u32> |
538 | 171..175 'None': Option<i64> | 538 | 171..175 'None': Option<i64> |
539 | 192..193 '_': () | 539 | 192..193 '_': () |
540 | 200..223 'match ... Foo }': Foo | 540 | 200..223 'match ... Foo }': Foo |
541 | 206..208 '()': () | 541 | 206..208 '()': () |
542 | 211..214 'Foo': Foo | 542 | 211..214 'Foo': Foo |
543 | 218..221 'Foo': Foo | 543 | 218..221 'Foo': Foo |
544 | 254..255 '_': () | 544 | 254..255 '_': () |
545 | 262..285 'match ... Bar }': usize | 545 | 262..285 'match ... Bar }': usize |
546 | 268..270 '()': () | 546 | 268..270 '()': () |
547 | 273..276 'Bar': usize | 547 | 273..276 'Bar': usize |
548 | 280..283 'Bar': usize | 548 | 280..283 'Bar': usize |
549 | 200..223: expected (), got Foo | 549 | 200..223: expected (), got Foo |
550 | 262..285: expected (), got usize | 550 | 262..285: expected (), got usize |
551 | "### | 551 | "#]], |
552 | ); | 552 | ); |
553 | } | 553 | } |
554 | 554 | ||
555 | #[test] | 555 | #[test] |
556 | fn infer_guard() { | 556 | fn infer_guard() { |
557 | assert_snapshot!( | 557 | check_infer( |
558 | infer(r#" | 558 | r#" |
559 | struct S; | 559 | struct S; |
560 | impl S { fn foo(&self) -> bool { false } } | 560 | impl S { fn foo(&self) -> bool { false } } |
561 | 561 | ||
@@ -564,91 +564,93 @@ fn main() { | |||
564 | s if s.foo() => (), | 564 | s if s.foo() => (), |
565 | } | 565 | } |
566 | } | 566 | } |
567 | "#), @r###" | 567 | "#, |
568 | 27..31 'self': &S | 568 | expect![[r#" |
569 | 41..50 '{ false }': bool | 569 | 27..31 'self': &S |
570 | 43..48 'false': bool | 570 | 41..50 '{ false }': bool |
571 | 64..115 '{ ... } }': () | 571 | 43..48 'false': bool |
572 | 70..113 'match ... }': () | 572 | 64..115 '{ ... } }': () |
573 | 76..77 'S': S | 573 | 70..113 'match ... }': () |
574 | 88..89 's': S | 574 | 76..77 'S': S |
575 | 93..94 's': S | 575 | 88..89 's': S |
576 | 93..100 's.foo()': bool | 576 | 93..94 's': S |
577 | 104..106 '()': () | 577 | 93..100 's.foo()': bool |
578 | "###) | 578 | 104..106 '()': () |
579 | "#]], | ||
580 | ) | ||
579 | } | 581 | } |
580 | 582 | ||
581 | #[test] | 583 | #[test] |
582 | fn match_ergonomics_in_closure_params() { | 584 | fn match_ergonomics_in_closure_params() { |
583 | assert_snapshot!( | 585 | check_infer( |
584 | infer(r#" | 586 | r#" |
585 | #[lang = "fn_once"] | 587 | #[lang = "fn_once"] |
586 | trait FnOnce<Args> { | 588 | trait FnOnce<Args> { |
587 | type Output; | 589 | type Output; |
588 | } | 590 | } |
589 | 591 | ||
590 | fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} } | 592 | fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} } |
591 | 593 | ||
592 | fn test() { | 594 | fn test() { |
593 | foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics | 595 | foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics |
594 | foo(&(1, "a"), |(x, y)| x); | 596 | foo(&(1, "a"), |(x, y)| x); |
595 | } | 597 | } |
596 | "#), | 598 | "#, |
597 | @r###" | 599 | expect![[r#" |
598 | 93..94 't': T | 600 | 93..94 't': T |
599 | 99..100 'f': F | 601 | 99..100 'f': F |
600 | 110..121 '{ loop {} }': U | 602 | 110..121 '{ loop {} }': U |
601 | 112..119 'loop {}': ! | 603 | 112..119 'loop {}': ! |
602 | 117..119 '{}': () | 604 | 117..119 '{}': () |
603 | 133..232 '{ ... x); }': () | 605 | 133..232 '{ ... x); }': () |
604 | 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 | 606 | 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 |
605 | 139..166 'foo(&(...y)| x)': i32 | 607 | 139..166 'foo(&(...y)| x)': i32 |
606 | 143..152 '&(1, "a")': &(i32, &str) | 608 | 143..152 '&(1, "a")': &(i32, &str) |
607 | 144..152 '(1, "a")': (i32, &str) | 609 | 144..152 '(1, "a")': (i32, &str) |
608 | 145..146 '1': i32 | 610 | 145..146 '1': i32 |
609 | 148..151 '"a"': &str | 611 | 148..151 '"a"': &str |
610 | 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 | 612 | 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 |
611 | 155..162 '&(x, y)': &(i32, &str) | 613 | 155..162 '&(x, y)': &(i32, &str) |
612 | 156..162 '(x, y)': (i32, &str) | 614 | 156..162 '(x, y)': (i32, &str) |
613 | 157..158 'x': i32 | 615 | 157..158 'x': i32 |
614 | 160..161 'y': &str | 616 | 160..161 'y': &str |
615 | 164..165 'x': i32 | 617 | 164..165 'x': i32 |
616 | 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 | 618 | 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 |
617 | 203..229 'foo(&(...y)| x)': &i32 | 619 | 203..229 'foo(&(...y)| x)': &i32 |
618 | 207..216 '&(1, "a")': &(i32, &str) | 620 | 207..216 '&(1, "a")': &(i32, &str) |
619 | 208..216 '(1, "a")': (i32, &str) | 621 | 208..216 '(1, "a")': (i32, &str) |
620 | 209..210 '1': i32 | 622 | 209..210 '1': i32 |
621 | 212..215 '"a"': &str | 623 | 212..215 '"a"': &str |
622 | 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 | 624 | 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 |
623 | 219..225 '(x, y)': (i32, &str) | 625 | 219..225 '(x, y)': (i32, &str) |
624 | 220..221 'x': &i32 | 626 | 220..221 'x': &i32 |
625 | 223..224 'y': &&str | 627 | 223..224 'y': &&str |
626 | 227..228 'x': &i32 | 628 | 227..228 'x': &i32 |
627 | "### | 629 | "#]], |
628 | ); | 630 | ); |
629 | } | 631 | } |
630 | 632 | ||
631 | #[test] | 633 | #[test] |
632 | fn slice_tail_pattern() { | 634 | fn slice_tail_pattern() { |
633 | assert_snapshot!( | 635 | check_infer( |
634 | infer(r#" | 636 | r#" |
635 | fn foo(params: &[i32]) { | 637 | fn foo(params: &[i32]) { |
636 | match params { | 638 | match params { |
637 | [head, tail @ ..] => { | 639 | [head, tail @ ..] => { |
640 | } | ||
641 | } | ||
638 | } | 642 | } |
639 | } | 643 | "#, |
640 | } | 644 | expect![[r#" |
641 | "#), | 645 | 7..13 'params': &[i32] |
642 | @r###" | 646 | 23..92 '{ ... } }': () |
643 | 7..13 'params': &[i32] | 647 | 29..90 'match ... }': () |
644 | 23..92 '{ ... } }': () | 648 | 35..41 'params': &[i32] |
645 | 29..90 'match ... }': () | 649 | 52..69 '[head,... @ ..]': [i32] |
646 | 35..41 'params': &[i32] | 650 | 53..57 'head': &i32 |
647 | 52..69 '[head,... @ ..]': [i32] | 651 | 59..68 'tail @ ..': &[i32] |
648 | 53..57 'head': &i32 | 652 | 66..68 '..': [i32] |
649 | 59..68 'tail @ ..': &[i32] | 653 | 73..84 '{ }': () |
650 | 66..68 '..': [i32] | 654 | "#]], |
651 | 73..84 '{ }': () | ||
652 | "### | ||
653 | ); | 655 | ); |
654 | } | 656 | } |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index d806e0ffb..b9ab0f357 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -1,87 +1,87 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{check_types, infer}; | 4 | use super::{check_infer, check_types}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn bug_484() { | 7 | fn bug_484() { |
8 | assert_snapshot!( | 8 | check_infer( |
9 | infer(r#" | 9 | r#" |
10 | fn test() { | 10 | fn test() { |
11 | let x = if true {}; | 11 | let x = if true {}; |
12 | } | 12 | } |
13 | "#), | 13 | "#, |
14 | @r###" | 14 | expect![[r#" |
15 | 10..36 '{ l... {}; }': () | 15 | 10..37 '{ ... {}; }': () |
16 | 19..20 'x': () | 16 | 20..21 'x': () |
17 | 23..33 'if true {}': () | 17 | 24..34 'if true {}': () |
18 | 26..30 'true': bool | 18 | 27..31 'true': bool |
19 | 31..33 '{}': () | 19 | 32..34 '{}': () |
20 | "### | 20 | "#]], |
21 | ); | 21 | ); |
22 | } | 22 | } |
23 | 23 | ||
24 | #[test] | 24 | #[test] |
25 | fn no_panic_on_field_of_enum() { | 25 | fn no_panic_on_field_of_enum() { |
26 | assert_snapshot!( | 26 | check_infer( |
27 | infer(r#" | 27 | r#" |
28 | enum X {} | 28 | enum X {} |
29 | 29 | ||
30 | fn test(x: X) { | 30 | fn test(x: X) { |
31 | x.some_field; | 31 | x.some_field; |
32 | } | 32 | } |
33 | "#), | 33 | "#, |
34 | @r###" | 34 | expect![[r#" |
35 | 19..20 'x': X | 35 | 19..20 'x': X |
36 | 25..46 '{ ...eld; }': () | 36 | 25..46 '{ ...eld; }': () |
37 | 31..32 'x': X | 37 | 31..32 'x': X |
38 | 31..43 'x.some_field': {unknown} | 38 | 31..43 'x.some_field': {unknown} |
39 | "### | 39 | "#]], |
40 | ); | 40 | ); |
41 | } | 41 | } |
42 | 42 | ||
43 | #[test] | 43 | #[test] |
44 | fn bug_585() { | 44 | fn bug_585() { |
45 | assert_snapshot!( | 45 | check_infer( |
46 | infer(r#" | 46 | r#" |
47 | fn test() { | 47 | fn test() { |
48 | X {}; | 48 | X {}; |
49 | match x { | 49 | match x { |
50 | A::B {} => (), | 50 | A::B {} => (), |
51 | A::Y() => (), | 51 | A::Y() => (), |
52 | } | 52 | } |
53 | } | 53 | } |
54 | "#), | 54 | "#, |
55 | @r###" | 55 | expect![[r#" |
56 | 10..88 '{ ... } }': () | 56 | 10..88 '{ ... } }': () |
57 | 16..20 'X {}': {unknown} | 57 | 16..20 'X {}': {unknown} |
58 | 26..86 'match ... }': () | 58 | 26..86 'match ... }': () |
59 | 32..33 'x': {unknown} | 59 | 32..33 'x': {unknown} |
60 | 44..51 'A::B {}': {unknown} | 60 | 44..51 'A::B {}': {unknown} |
61 | 55..57 '()': () | 61 | 55..57 '()': () |
62 | 67..73 'A::Y()': {unknown} | 62 | 67..73 'A::Y()': {unknown} |
63 | 77..79 '()': () | 63 | 77..79 '()': () |
64 | "### | 64 | "#]], |
65 | ); | 65 | ); |
66 | } | 66 | } |
67 | 67 | ||
68 | #[test] | 68 | #[test] |
69 | fn bug_651() { | 69 | fn bug_651() { |
70 | assert_snapshot!( | 70 | check_infer( |
71 | infer(r#" | 71 | r#" |
72 | fn quux() { | 72 | fn quux() { |
73 | let y = 92; | 73 | let y = 92; |
74 | 1 + y; | 74 | 1 + y; |
75 | } | 75 | } |
76 | "#), | 76 | "#, |
77 | @r###" | 77 | expect![[r#" |
78 | 10..40 '{ ...+ y; }': () | 78 | 10..40 '{ ...+ y; }': () |
79 | 20..21 'y': i32 | 79 | 20..21 'y': i32 |
80 | 24..26 '92': i32 | 80 | 24..26 '92': i32 |
81 | 32..33 '1': i32 | 81 | 32..33 '1': i32 |
82 | 32..37 '1 + y': i32 | 82 | 32..37 '1 + y': i32 |
83 | 36..37 'y': i32 | 83 | 36..37 'y': i32 |
84 | "### | 84 | "#]], |
85 | ); | 85 | ); |
86 | } | 86 | } |
87 | 87 | ||
@@ -89,78 +89,78 @@ fn quux() { | |||
89 | fn recursive_vars() { | 89 | fn recursive_vars() { |
90 | mark::check!(type_var_cycles_resolve_completely); | 90 | mark::check!(type_var_cycles_resolve_completely); |
91 | mark::check!(type_var_cycles_resolve_as_possible); | 91 | mark::check!(type_var_cycles_resolve_as_possible); |
92 | assert_snapshot!( | 92 | check_infer( |
93 | infer(r#" | 93 | r#" |
94 | fn test() { | 94 | fn test() { |
95 | let y = unknown; | 95 | let y = unknown; |
96 | [y, &y]; | 96 | [y, &y]; |
97 | } | 97 | } |
98 | "#), | 98 | "#, |
99 | @r###" | 99 | expect![[r#" |
100 | 10..47 '{ ...&y]; }': () | 100 | 10..47 '{ ...&y]; }': () |
101 | 20..21 'y': &{unknown} | 101 | 20..21 'y': &{unknown} |
102 | 24..31 'unknown': &{unknown} | 102 | 24..31 'unknown': &{unknown} |
103 | 37..44 '[y, &y]': [&&{unknown}; _] | 103 | 37..44 '[y, &y]': [&&{unknown}; _] |
104 | 38..39 'y': &{unknown} | 104 | 38..39 'y': &{unknown} |
105 | 41..43 '&y': &&{unknown} | 105 | 41..43 '&y': &&{unknown} |
106 | 42..43 'y': &{unknown} | 106 | 42..43 'y': &{unknown} |
107 | "### | 107 | "#]], |
108 | ); | 108 | ); |
109 | } | 109 | } |
110 | 110 | ||
111 | #[test] | 111 | #[test] |
112 | fn recursive_vars_2() { | 112 | fn recursive_vars_2() { |
113 | assert_snapshot!( | 113 | check_infer( |
114 | infer(r#" | 114 | r#" |
115 | fn test() { | 115 | fn test() { |
116 | let x = unknown; | 116 | let x = unknown; |
117 | let y = unknown; | 117 | let y = unknown; |
118 | [(x, y), (&y, &x)]; | 118 | [(x, y), (&y, &x)]; |
119 | } | 119 | } |
120 | "#), | 120 | "#, |
121 | @r###" | 121 | expect![[r#" |
122 | 10..79 '{ ...x)]; }': () | 122 | 10..79 '{ ...x)]; }': () |
123 | 20..21 'x': &&{unknown} | 123 | 20..21 'x': &&{unknown} |
124 | 24..31 'unknown': &&{unknown} | 124 | 24..31 'unknown': &&{unknown} |
125 | 41..42 'y': &&{unknown} | 125 | 41..42 'y': &&{unknown} |
126 | 45..52 'unknown': &&{unknown} | 126 | 45..52 'unknown': &&{unknown} |
127 | 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] | 127 | 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] |
128 | 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) | 128 | 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) |
129 | 60..61 'x': &&{unknown} | 129 | 60..61 'x': &&{unknown} |
130 | 63..64 'y': &&{unknown} | 130 | 63..64 'y': &&{unknown} |
131 | 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) | 131 | 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) |
132 | 68..70 '&y': &&&{unknown} | 132 | 68..70 '&y': &&&{unknown} |
133 | 69..70 'y': &&{unknown} | 133 | 69..70 'y': &&{unknown} |
134 | 72..74 '&x': &&&{unknown} | 134 | 72..74 '&x': &&&{unknown} |
135 | 73..74 'x': &&{unknown} | 135 | 73..74 'x': &&{unknown} |
136 | "### | 136 | "#]], |
137 | ); | 137 | ); |
138 | } | 138 | } |
139 | 139 | ||
140 | #[test] | 140 | #[test] |
141 | fn infer_std_crash_1() { | 141 | fn infer_std_crash_1() { |
142 | // caused stack overflow, taken from std | 142 | // caused stack overflow, taken from std |
143 | assert_snapshot!( | 143 | check_infer( |
144 | infer(r#" | 144 | r#" |
145 | enum Maybe<T> { | 145 | enum Maybe<T> { |
146 | Real(T), | 146 | Real(T), |
147 | Fake, | 147 | Fake, |
148 | } | 148 | } |
149 | 149 | ||
150 | fn write() { | 150 | fn write() { |
151 | match something_unknown { | 151 | match something_unknown { |
152 | Maybe::Real(ref mut something) => (), | 152 | Maybe::Real(ref mut something) => (), |
153 | } | 153 | } |
154 | } | 154 | } |
155 | "#), | 155 | "#, |
156 | @r###" | 156 | expect![[r#" |
157 | 53..138 '{ ... } }': () | 157 | 53..138 '{ ... } }': () |
158 | 59..136 'match ... }': () | 158 | 59..136 'match ... }': () |
159 | 65..82 'someth...nknown': Maybe<{unknown}> | 159 | 65..82 'someth...nknown': Maybe<{unknown}> |
160 | 93..123 'Maybe:...thing)': Maybe<{unknown}> | 160 | 93..123 'Maybe:...thing)': Maybe<{unknown}> |
161 | 105..122 'ref mu...ething': &mut {unknown} | 161 | 105..122 'ref mu...ething': &mut {unknown} |
162 | 127..129 '()': () | 162 | 127..129 '()': () |
163 | "### | 163 | "#]], |
164 | ); | 164 | ); |
165 | } | 165 | } |
166 | 166 | ||
@@ -168,234 +168,235 @@ fn write() { | |||
168 | fn infer_std_crash_2() { | 168 | fn infer_std_crash_2() { |
169 | mark::check!(type_var_resolves_to_int_var); | 169 | mark::check!(type_var_resolves_to_int_var); |
170 | // caused "equating two type variables, ...", taken from std | 170 | // caused "equating two type variables, ...", taken from std |
171 | assert_snapshot!( | 171 | check_infer( |
172 | infer(r#" | 172 | r#" |
173 | fn test_line_buffer() { | 173 | fn test_line_buffer() { |
174 | &[0, b'\n', 1, b'\n']; | 174 | &[0, b'\n', 1, b'\n']; |
175 | } | 175 | } |
176 | "#), | 176 | "#, |
177 | @r###" | 177 | expect![[r#" |
178 | 22..52 '{ ...n']; }': () | 178 | 22..52 '{ ...n']; }': () |
179 | 28..49 '&[0, b...b'\n']': &[u8; _] | 179 | 28..49 '&[0, b...b'\n']': &[u8; _] |
180 | 29..49 '[0, b'...b'\n']': [u8; _] | 180 | 29..49 '[0, b'...b'\n']': [u8; _] |
181 | 30..31 '0': u8 | 181 | 30..31 '0': u8 |
182 | 33..38 'b'\n'': u8 | 182 | 33..38 'b'\n'': u8 |
183 | 40..41 '1': u8 | 183 | 40..41 '1': u8 |
184 | 43..48 'b'\n'': u8 | 184 | 43..48 'b'\n'': u8 |
185 | "### | 185 | "#]], |
186 | ); | 186 | ); |
187 | } | 187 | } |
188 | 188 | ||
189 | #[test] | 189 | #[test] |
190 | fn infer_std_crash_3() { | 190 | fn infer_std_crash_3() { |
191 | // taken from rustc | 191 | // taken from rustc |
192 | assert_snapshot!( | 192 | check_infer( |
193 | infer(r#" | 193 | r#" |
194 | pub fn compute() { | 194 | pub fn compute() { |
195 | match nope!() { | 195 | match nope!() { |
196 | SizeSkeleton::Pointer { non_zero: true, tail } => {} | 196 | SizeSkeleton::Pointer { non_zero: true, tail } => {} |
197 | } | 197 | } |
198 | } | 198 | } |
199 | "#), | 199 | "#, |
200 | @r###" | 200 | expect![[r#" |
201 | 17..107 '{ ... } }': () | 201 | 17..107 '{ ... } }': () |
202 | 23..105 'match ... }': () | 202 | 23..105 'match ... }': () |
203 | 29..36 'nope!()': {unknown} | 203 | 29..36 'nope!()': {unknown} |
204 | 47..93 'SizeSk...tail }': {unknown} | 204 | 47..93 'SizeSk...tail }': {unknown} |
205 | 81..85 'true': bool | 205 | 81..85 'true': bool |
206 | 81..85 'true': bool | 206 | 81..85 'true': bool |
207 | 87..91 'tail': {unknown} | 207 | 87..91 'tail': {unknown} |
208 | 97..99 '{}': () | 208 | 97..99 '{}': () |
209 | "### | 209 | "#]], |
210 | ); | 210 | ); |
211 | } | 211 | } |
212 | 212 | ||
213 | #[test] | 213 | #[test] |
214 | fn infer_std_crash_4() { | 214 | fn infer_std_crash_4() { |
215 | // taken from rustc | 215 | // taken from rustc |
216 | assert_snapshot!( | 216 | check_infer( |
217 | infer(r#" | 217 | r#" |
218 | pub fn primitive_type() { | 218 | pub fn primitive_type() { |
219 | match *self { | 219 | match *self { |
220 | BorrowedRef { type_: Primitive(p), ..} => {}, | 220 | BorrowedRef { type_: Primitive(p), ..} => {}, |
221 | } | 221 | } |
222 | } | 222 | } |
223 | "#), | 223 | "#, |
224 | @r###" | 224 | expect![[r#" |
225 | 24..105 '{ ... } }': () | 225 | 24..105 '{ ... } }': () |
226 | 30..103 'match ... }': () | 226 | 30..103 'match ... }': () |
227 | 36..41 '*self': {unknown} | 227 | 36..41 '*self': {unknown} |
228 | 37..41 'self': {unknown} | 228 | 37..41 'self': {unknown} |
229 | 52..90 'Borrow...), ..}': {unknown} | 229 | 52..90 'Borrow...), ..}': {unknown} |
230 | 73..85 'Primitive(p)': {unknown} | 230 | 73..85 'Primitive(p)': {unknown} |
231 | 83..84 'p': {unknown} | 231 | 83..84 'p': {unknown} |
232 | 94..96 '{}': () | 232 | 94..96 '{}': () |
233 | "### | 233 | "#]], |
234 | ); | 234 | ); |
235 | } | 235 | } |
236 | 236 | ||
237 | #[test] | 237 | #[test] |
238 | fn infer_std_crash_5() { | 238 | fn infer_std_crash_5() { |
239 | // taken from rustc | 239 | // taken from rustc |
240 | assert_snapshot!( | 240 | check_infer( |
241 | infer(r#" | 241 | r#" |
242 | fn extra_compiler_flags() { | 242 | fn extra_compiler_flags() { |
243 | for content in doesnt_matter { | 243 | for content in doesnt_matter { |
244 | let name = if doesnt_matter { | 244 | let name = if doesnt_matter { |
245 | first | 245 | first |
246 | } else { | 246 | } else { |
247 | &content | 247 | &content |
248 | }; | 248 | }; |
249 | 249 | ||
250 | let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { | 250 | let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { |
251 | name | 251 | name |
252 | } else { | 252 | } else { |
253 | content | 253 | content |
254 | }; | 254 | }; |
255 | } | 255 | } |
256 | } | 256 | } |
257 | "#), | 257 | "#, |
258 | @r###" | 258 | expect![[r#" |
259 | 26..322 '{ ... } }': () | 259 | 26..322 '{ ... } }': () |
260 | 32..320 'for co... }': () | 260 | 32..320 'for co... }': () |
261 | 36..43 'content': &{unknown} | 261 | 36..43 'content': &{unknown} |
262 | 47..60 'doesnt_matter': {unknown} | 262 | 47..60 'doesnt_matter': {unknown} |
263 | 61..320 '{ ... }': () | 263 | 61..320 '{ ... }': () |
264 | 75..79 'name': &&{unknown} | 264 | 75..79 'name': &&{unknown} |
265 | 82..166 'if doe... }': &&{unknown} | 265 | 82..166 'if doe... }': &&{unknown} |
266 | 85..98 'doesnt_matter': bool | 266 | 85..98 'doesnt_matter': bool |
267 | 99..128 '{ ... }': &&{unknown} | 267 | 99..128 '{ ... }': &&{unknown} |
268 | 113..118 'first': &&{unknown} | 268 | 113..118 'first': &&{unknown} |
269 | 134..166 '{ ... }': &&{unknown} | 269 | 134..166 '{ ... }': &&{unknown} |
270 | 148..156 '&content': &&{unknown} | 270 | 148..156 '&content': &&{unknown} |
271 | 149..156 'content': &{unknown} | 271 | 149..156 'content': &{unknown} |
272 | 181..188 'content': &{unknown} | 272 | 181..188 'content': &{unknown} |
273 | 191..313 'if ICE... }': &{unknown} | 273 | 191..313 'if ICE... }': &{unknown} |
274 | 194..231 'ICE_RE..._VALUE': {unknown} | 274 | 194..231 'ICE_RE..._VALUE': {unknown} |
275 | 194..247 'ICE_RE...&name)': bool | 275 | 194..247 'ICE_RE...&name)': bool |
276 | 241..246 '&name': &&&{unknown} | 276 | 241..246 '&name': &&&{unknown} |
277 | 242..246 'name': &&{unknown} | 277 | 242..246 'name': &&{unknown} |
278 | 248..276 '{ ... }': &&{unknown} | 278 | 248..276 '{ ... }': &&{unknown} |
279 | 262..266 'name': &&{unknown} | 279 | 262..266 'name': &&{unknown} |
280 | 282..313 '{ ... }': &{unknown} | 280 | 282..313 '{ ... }': &{unknown} |
281 | 296..303 'content': &{unknown} | 281 | 296..303 'content': &{unknown} |
282 | "### | 282 | "#]], |
283 | ); | 283 | ); |
284 | } | 284 | } |
285 | 285 | ||
286 | #[test] | 286 | #[test] |
287 | fn infer_nested_generics_crash() { | 287 | fn infer_nested_generics_crash() { |
288 | // another crash found typechecking rustc | 288 | // another crash found typechecking rustc |
289 | assert_snapshot!( | 289 | check_infer( |
290 | infer(r#" | 290 | r#" |
291 | struct Canonical<V> { | 291 | struct Canonical<V> { |
292 | value: V, | 292 | value: V, |
293 | } | 293 | } |
294 | struct QueryResponse<V> { | 294 | struct QueryResponse<V> { |
295 | value: V, | 295 | value: V, |
296 | } | 296 | } |
297 | fn test<R>(query_response: Canonical<QueryResponse<R>>) { | 297 | fn test<R>(query_response: Canonical<QueryResponse<R>>) { |
298 | &query_response.value; | 298 | &query_response.value; |
299 | } | 299 | } |
300 | "#), | 300 | "#, |
301 | @r###" | 301 | expect![[r#" |
302 | 91..105 'query_response': Canonical<QueryResponse<R>> | 302 | 91..105 'query_response': Canonical<QueryResponse<R>> |
303 | 136..166 '{ ...lue; }': () | 303 | 136..166 '{ ...lue; }': () |
304 | 142..163 '&query....value': &QueryResponse<R> | 304 | 142..163 '&query....value': &QueryResponse<R> |
305 | 143..157 'query_response': Canonical<QueryResponse<R>> | 305 | 143..157 'query_response': Canonical<QueryResponse<R>> |
306 | 143..163 'query_....value': QueryResponse<R> | 306 | 143..163 'query_....value': QueryResponse<R> |
307 | "### | 307 | "#]], |
308 | ); | 308 | ); |
309 | } | 309 | } |
310 | 310 | ||
311 | #[test] | 311 | #[test] |
312 | fn infer_paren_macro_call() { | 312 | fn infer_paren_macro_call() { |
313 | assert_snapshot!( | 313 | check_infer( |
314 | infer(r#" | 314 | r#" |
315 | macro_rules! bar { () => {0u32} } | 315 | macro_rules! bar { () => {0u32} } |
316 | fn test() { | 316 | fn test() { |
317 | let a = (bar!()); | 317 | let a = (bar!()); |
318 | } | 318 | } |
319 | "#), | 319 | "#, |
320 | @r###" | 320 | expect![[r#" |
321 | !0..4 '0u32': u32 | 321 | !0..4 '0u32': u32 |
322 | 44..69 '{ ...()); }': () | 322 | 44..69 '{ ...()); }': () |
323 | 54..55 'a': u32 | 323 | 54..55 'a': u32 |
324 | "### | 324 | "#]], |
325 | ); | 325 | ); |
326 | } | 326 | } |
327 | 327 | ||
328 | #[test] | 328 | #[test] |
329 | fn bug_1030() { | 329 | fn bug_1030() { |
330 | assert_snapshot!(infer(r#" | 330 | check_infer( |
331 | struct HashSet<T, H>; | 331 | r#" |
332 | struct FxHasher; | 332 | struct HashSet<T, H>; |
333 | type FxHashSet<T> = HashSet<T, FxHasher>; | 333 | struct FxHasher; |
334 | type FxHashSet<T> = HashSet<T, FxHasher>; | ||
334 | 335 | ||
335 | impl<T, H> HashSet<T, H> { | 336 | impl<T, H> HashSet<T, H> { |
336 | fn default() -> HashSet<T, H> {} | 337 | fn default() -> HashSet<T, H> {} |
337 | } | 338 | } |
338 | 339 | ||
339 | pub fn main_loop() { | 340 | pub fn main_loop() { |
340 | FxHashSet::default(); | 341 | FxHashSet::default(); |
341 | } | 342 | } |
342 | "#), | 343 | "#, |
343 | @r###" | 344 | expect![[r#" |
344 | 143..145 '{}': () | 345 | 143..145 '{}': () |
345 | 168..197 '{ ...t(); }': () | 346 | 168..197 '{ ...t(); }': () |
346 | 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> | 347 | 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> |
347 | 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> | 348 | 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> |
348 | "### | 349 | "#]], |
349 | ); | 350 | ); |
350 | } | 351 | } |
351 | 352 | ||
352 | #[test] | 353 | #[test] |
353 | fn issue_2669() { | 354 | fn issue_2669() { |
354 | assert_snapshot!( | 355 | check_infer( |
355 | infer( | 356 | r#" |
356 | r#"trait A {} | 357 | trait A {} |
357 | trait Write {} | 358 | trait Write {} |
358 | struct Response<T> {} | 359 | struct Response<T> {} |
359 | |||
360 | trait D { | ||
361 | fn foo(); | ||
362 | } | ||
363 | 360 | ||
364 | impl<T:A> D for Response<T> { | 361 | trait D { |
365 | fn foo() { | 362 | fn foo(); |
366 | end(); | 363 | } |
367 | fn end<W: Write>() { | 364 | |
368 | let _x: T = loop {}; | 365 | impl<T:A> D for Response<T> { |
366 | fn foo() { | ||
367 | end(); | ||
368 | fn end<W: Write>() { | ||
369 | let _x: T = loop {}; | ||
370 | } | ||
369 | } | 371 | } |
370 | } | 372 | } |
371 | }"# | 373 | "#, |
372 | ), | 374 | expect![[r#" |
373 | @r###" | 375 | 119..214 '{ ... }': () |
374 | 147..262 '{ ... }': () | 376 | 129..132 'end': fn end<{unknown}>() |
375 | 161..164 'end': fn end<{unknown}>() | 377 | 129..134 'end()': () |
376 | 161..166 'end()': () | 378 | 163..208 '{ ... }': () |
377 | 199..252 '{ ... }': () | 379 | 181..183 '_x': ! |
378 | 221..223 '_x': ! | 380 | 190..197 'loop {}': ! |
379 | 230..237 'loop {}': ! | 381 | 195..197 '{}': () |
380 | 235..237 '{}': () | 382 | "#]], |
381 | "### | ||
382 | ) | 383 | ) |
383 | } | 384 | } |
384 | 385 | ||
385 | #[test] | 386 | #[test] |
386 | fn issue_2705() { | 387 | fn issue_2705() { |
387 | assert_snapshot!( | 388 | check_infer( |
388 | infer(r#" | 389 | r#" |
389 | trait Trait {} | 390 | trait Trait {} |
390 | fn test() { | 391 | fn test() { |
391 | <Trait<u32>>::foo() | 392 | <Trait<u32>>::foo() |
392 | } | 393 | } |
393 | "#), | 394 | "#, |
394 | @r###" | 395 | expect![[r#" |
395 | 25..52 '{ ...oo() }': () | 396 | 25..52 '{ ...oo() }': () |
396 | 31..48 '<Trait...>::foo': {unknown} | 397 | 31..48 '<Trait...>::foo': {unknown} |
397 | 31..50 '<Trait...:foo()': () | 398 | 31..50 '<Trait...:foo()': () |
398 | "### | 399 | "#]], |
399 | ); | 400 | ); |
400 | } | 401 | } |
401 | 402 | ||
@@ -479,25 +480,25 @@ fn main() { | |||
479 | 480 | ||
480 | #[test] | 481 | #[test] |
481 | fn issue_3999_slice() { | 482 | fn issue_3999_slice() { |
482 | assert_snapshot!( | 483 | check_infer( |
483 | infer(r#" | 484 | r#" |
484 | fn foo(params: &[usize]) { | 485 | fn foo(params: &[usize]) { |
485 | match params { | 486 | match params { |
486 | [ps @ .., _] => {} | 487 | [ps @ .., _] => {} |
487 | } | 488 | } |
488 | } | 489 | } |
489 | "#), | 490 | "#, |
490 | @r###" | 491 | expect![[r#" |
491 | 7..13 'params': &[usize] | 492 | 7..13 'params': &[usize] |
492 | 25..80 '{ ... } }': () | 493 | 25..80 '{ ... } }': () |
493 | 31..78 'match ... }': () | 494 | 31..78 'match ... }': () |
494 | 37..43 'params': &[usize] | 495 | 37..43 'params': &[usize] |
495 | 54..66 '[ps @ .., _]': [usize] | 496 | 54..66 '[ps @ .., _]': [usize] |
496 | 55..62 'ps @ ..': &[usize] | 497 | 55..62 'ps @ ..': &[usize] |
497 | 60..62 '..': [usize] | 498 | 60..62 '..': [usize] |
498 | 64..65 '_': usize | 499 | 64..65 '_': usize |
499 | 70..72 '{}': () | 500 | 70..72 '{}': () |
500 | "### | 501 | "#]], |
501 | ); | 502 | ); |
502 | } | 503 | } |
503 | 504 | ||
@@ -505,277 +506,337 @@ fn foo(params: &[usize]) { | |||
505 | fn issue_3999_struct() { | 506 | fn issue_3999_struct() { |
506 | // rust-analyzer should not panic on seeing this malformed | 507 | // rust-analyzer should not panic on seeing this malformed |
507 | // record pattern. | 508 | // record pattern. |
508 | assert_snapshot!( | 509 | check_infer( |
509 | infer(r#" | 510 | r#" |
510 | struct Bar { | 511 | struct Bar { |
511 | a: bool, | 512 | a: bool, |
512 | } | 513 | } |
513 | fn foo(b: Bar) { | 514 | fn foo(b: Bar) { |
514 | match b { | 515 | match b { |
515 | Bar { a: .. } => {}, | 516 | Bar { a: .. } => {}, |
516 | } | 517 | } |
517 | } | 518 | } |
518 | "#), | 519 | "#, |
519 | @r###" | 520 | expect![[r#" |
520 | 35..36 'b': Bar | 521 | 35..36 'b': Bar |
521 | 43..95 '{ ... } }': () | 522 | 43..95 '{ ... } }': () |
522 | 49..93 'match ... }': () | 523 | 49..93 'match ... }': () |
523 | 55..56 'b': Bar | 524 | 55..56 'b': Bar |
524 | 67..80 'Bar { a: .. }': Bar | 525 | 67..80 'Bar { a: .. }': Bar |
525 | 76..78 '..': bool | 526 | 76..78 '..': bool |
526 | 84..86 '{}': () | 527 | 84..86 '{}': () |
527 | "### | 528 | "#]], |
528 | ); | 529 | ); |
529 | } | 530 | } |
530 | 531 | ||
531 | #[test] | 532 | #[test] |
532 | fn issue_4235_name_conflicts() { | 533 | fn issue_4235_name_conflicts() { |
533 | assert_snapshot!( | 534 | check_infer( |
534 | infer(r#" | 535 | r#" |
535 | struct FOO {} | 536 | struct FOO {} |
536 | static FOO:FOO = FOO {}; | 537 | static FOO:FOO = FOO {}; |
537 | 538 | ||
538 | impl FOO { | 539 | impl FOO { |
539 | fn foo(&self) {} | 540 | fn foo(&self) {} |
540 | } | 541 | } |
541 | 542 | ||
542 | fn main() { | 543 | fn main() { |
543 | let a = &FOO; | 544 | let a = &FOO; |
544 | a.foo(); | 545 | a.foo(); |
545 | } | 546 | } |
546 | "#), @r###" | 547 | "#, |
547 | 31..37 'FOO {}': FOO | 548 | expect![[r#" |
548 | 63..67 'self': &FOO | 549 | 31..37 'FOO {}': FOO |
549 | 69..71 '{}': () | 550 | 63..67 'self': &FOO |
550 | 85..119 '{ ...o(); }': () | 551 | 69..71 '{}': () |
551 | 95..96 'a': &FOO | 552 | 85..119 '{ ...o(); }': () |
552 | 99..103 '&FOO': &FOO | 553 | 95..96 'a': &FOO |
553 | 100..103 'FOO': FOO | 554 | 99..103 '&FOO': &FOO |
554 | 109..110 'a': &FOO | 555 | 100..103 'FOO': FOO |
555 | 109..116 'a.foo()': () | 556 | 109..110 'a': &FOO |
556 | "### | 557 | 109..116 'a.foo()': () |
558 | "#]], | ||
557 | ); | 559 | ); |
558 | } | 560 | } |
559 | 561 | ||
560 | #[test] | 562 | #[test] |
561 | fn issue_4465_dollar_crate_at_type() { | 563 | fn issue_4465_dollar_crate_at_type() { |
562 | assert_snapshot!( | 564 | check_infer( |
563 | infer(r#" | 565 | r#" |
564 | pub struct Foo {} | 566 | pub struct Foo {} |
565 | pub fn anything<T>() -> T { | 567 | pub fn anything<T>() -> T { |
566 | loop {} | 568 | loop {} |
567 | } | 569 | } |
568 | macro_rules! foo { | 570 | macro_rules! foo { |
569 | () => {{ | 571 | () => {{ |
570 | let r: $crate::Foo = anything(); | 572 | let r: $crate::Foo = anything(); |
571 | r | 573 | r |
572 | }}; | 574 | }}; |
573 | } | 575 | } |
574 | fn main() { | 576 | fn main() { |
575 | let _a = foo!(); | 577 | let _a = foo!(); |
576 | } | 578 | } |
577 | "#), @r###" | 579 | "#, |
578 | 44..59 '{ loop {} }': T | 580 | expect![[r#" |
579 | 50..57 'loop {}': ! | 581 | 44..59 '{ loop {} }': T |
580 | 55..57 '{}': () | 582 | 50..57 'loop {}': ! |
581 | !0..31 '{letr:...g();r}': Foo | 583 | 55..57 '{}': () |
582 | !4..5 'r': Foo | 584 | !0..31 '{letr:...g();r}': Foo |
583 | !18..26 'anything': fn anything<Foo>() -> Foo | 585 | !4..5 'r': Foo |
584 | !18..28 'anything()': Foo | 586 | !18..26 'anything': fn anything<Foo>() -> Foo |
585 | !29..30 'r': Foo | 587 | !18..28 'anything()': Foo |
586 | 163..187 '{ ...!(); }': () | 588 | !29..30 'r': Foo |
587 | 173..175 '_a': Foo | 589 | 163..187 '{ ...!(); }': () |
588 | "###); | 590 | 173..175 '_a': Foo |
591 | "#]], | ||
592 | ); | ||
589 | } | 593 | } |
590 | 594 | ||
591 | #[test] | 595 | #[test] |
592 | fn issue_4053_diesel_where_clauses() { | 596 | fn issue_4053_diesel_where_clauses() { |
593 | assert_snapshot!( | 597 | check_infer( |
594 | infer(r#" | 598 | r#" |
595 | trait BoxedDsl<DB> { | 599 | trait BoxedDsl<DB> { |
596 | type Output; | 600 | type Output; |
597 | fn internal_into_boxed(self) -> Self::Output; | 601 | fn internal_into_boxed(self) -> Self::Output; |
598 | } | 602 | } |
599 | 603 | ||
600 | struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> { | 604 | struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> { |
601 | order: Order, | 605 | order: Order, |
602 | } | 606 | } |
603 | 607 | ||
604 | trait QueryFragment<DB: Backend> {} | 608 | trait QueryFragment<DB: Backend> {} |
605 | 609 | ||
606 | trait Into<T> { fn into(self) -> T; } | 610 | trait Into<T> { fn into(self) -> T; } |
607 | 611 | ||
608 | impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB> | 612 | impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB> |
609 | for SelectStatement<F, S, D, W, O, LOf, G> | 613 | for SelectStatement<F, S, D, W, O, LOf, G> |
610 | where | 614 | where |
611 | O: Into<dyn QueryFragment<DB>>, | 615 | O: Into<dyn QueryFragment<DB>>, |
612 | { | 616 | { |
613 | type Output = XXX; | 617 | type Output = XXX; |
614 | 618 | ||
615 | fn internal_into_boxed(self) -> Self::Output { | 619 | fn internal_into_boxed(self) -> Self::Output { |
616 | self.order.into(); | 620 | self.order.into(); |
617 | } | 621 | } |
618 | } | 622 | } |
619 | "#), | 623 | "#, |
620 | @r###" | 624 | expect![[r#" |
621 | 65..69 'self': Self | 625 | 65..69 'self': Self |
622 | 267..271 'self': Self | 626 | 267..271 'self': Self |
623 | 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> | 627 | 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> |
624 | 488..522 '{ ... }': () | 628 | 488..522 '{ ... }': () |
625 | 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> | 629 | 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> |
626 | 498..508 'self.order': O | 630 | 498..508 'self.order': O |
627 | 498..515 'self.o...into()': dyn QueryFragment<DB> | 631 | 498..515 'self.o...into()': dyn QueryFragment<DB> |
628 | "### | 632 | "#]], |
629 | ); | 633 | ); |
630 | } | 634 | } |
631 | 635 | ||
632 | #[test] | 636 | #[test] |
633 | fn issue_4953() { | 637 | fn issue_4953() { |
634 | assert_snapshot!( | 638 | check_infer( |
635 | infer(r#" | 639 | r#" |
636 | pub struct Foo(pub i64); | 640 | pub struct Foo(pub i64); |
637 | impl Foo { | 641 | impl Foo { |
638 | fn test() -> Self { Self(0i64) } | 642 | fn test() -> Self { Self(0i64) } |
639 | } | 643 | } |
640 | "#), | 644 | "#, |
641 | @r###" | 645 | expect![[r#" |
642 | 58..72 '{ Self(0i64) }': Foo | 646 | 58..72 '{ Self(0i64) }': Foo |
643 | 60..64 'Self': Foo(i64) -> Foo | 647 | 60..64 'Self': Foo(i64) -> Foo |
644 | 60..70 'Self(0i64)': Foo | 648 | 60..70 'Self(0i64)': Foo |
645 | 65..69 '0i64': i64 | 649 | 65..69 '0i64': i64 |
646 | "### | 650 | "#]], |
647 | ); | 651 | ); |
648 | assert_snapshot!( | 652 | check_infer( |
649 | infer(r#" | 653 | r#" |
650 | pub struct Foo<T>(pub T); | 654 | pub struct Foo<T>(pub T); |
651 | impl Foo<i64> { | 655 | impl Foo<i64> { |
652 | fn test() -> Self { Self(0i64) } | 656 | fn test() -> Self { Self(0i64) } |
653 | } | 657 | } |
654 | "#), | 658 | "#, |
655 | @r###" | 659 | expect![[r#" |
656 | 64..78 '{ Self(0i64) }': Foo<i64> | 660 | 64..78 '{ Self(0i64) }': Foo<i64> |
657 | 66..70 'Self': Foo<i64>(i64) -> Foo<i64> | 661 | 66..70 'Self': Foo<i64>(i64) -> Foo<i64> |
658 | 66..76 'Self(0i64)': Foo<i64> | 662 | 66..76 'Self(0i64)': Foo<i64> |
659 | 71..75 '0i64': i64 | 663 | 71..75 '0i64': i64 |
660 | "### | 664 | "#]], |
661 | ); | 665 | ); |
662 | } | 666 | } |
663 | 667 | ||
664 | #[test] | 668 | #[test] |
665 | fn issue_4931() { | 669 | fn issue_4931() { |
666 | assert_snapshot!( | 670 | check_infer( |
667 | infer(r#" | 671 | r#" |
668 | trait Div<T> { | 672 | trait Div<T> { |
669 | type Output; | 673 | type Output; |
670 | } | 674 | } |
671 | 675 | ||
672 | trait CheckedDiv: Div<()> {} | 676 | trait CheckedDiv: Div<()> {} |
673 | 677 | ||
674 | trait PrimInt: CheckedDiv<Output = ()> { | 678 | trait PrimInt: CheckedDiv<Output = ()> { |
675 | fn pow(self); | 679 | fn pow(self); |
676 | } | 680 | } |
677 | 681 | ||
678 | fn check<T: PrimInt>(i: T) { | 682 | fn check<T: PrimInt>(i: T) { |
679 | i.pow(); | 683 | i.pow(); |
680 | } | 684 | } |
681 | "#), | 685 | "#, |
682 | @r###" | 686 | expect![[r#" |
683 | 117..121 'self': Self | 687 | 117..121 'self': Self |
684 | 148..149 'i': T | 688 | 148..149 'i': T |
685 | 154..170 '{ ...w(); }': () | 689 | 154..170 '{ ...w(); }': () |
686 | 160..161 'i': T | 690 | 160..161 'i': T |
687 | 160..167 'i.pow()': () | 691 | 160..167 'i.pow()': () |
688 | "### | 692 | "#]], |
689 | ); | 693 | ); |
690 | } | 694 | } |
691 | 695 | ||
692 | #[test] | 696 | #[test] |
693 | fn issue_4885() { | 697 | fn issue_4885() { |
694 | assert_snapshot!( | 698 | check_infer( |
695 | infer(r#" | 699 | r#" |
696 | #[lang = "coerce_unsized"] | 700 | #[lang = "coerce_unsized"] |
697 | pub trait CoerceUnsized<T> {} | 701 | pub trait CoerceUnsized<T> {} |
698 | 702 | ||
699 | trait Future { | 703 | trait Future { |
700 | type Output; | 704 | type Output; |
701 | } | 705 | } |
702 | trait Foo<R> { | 706 | trait Foo<R> { |
703 | type Bar; | 707 | type Bar; |
704 | } | 708 | } |
705 | fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> | 709 | fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> |
706 | where | 710 | where |
707 | K: Foo<R>, | 711 | K: Foo<R>, |
708 | { | 712 | { |
709 | bar(key) | 713 | bar(key) |
710 | } | 714 | } |
711 | fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> | 715 | fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> |
712 | where | 716 | where |
713 | K: Foo<R>, | 717 | K: Foo<R>, |
714 | { | 718 | { |
715 | } | 719 | } |
716 | "#), | 720 | "#, |
717 | @r###" | 721 | expect![[r#" |
718 | 136..139 'key': &K | 722 | 136..139 'key': &K |
719 | 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> | 723 | 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> |
720 | 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> | 724 | 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> |
721 | 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> | 725 | 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> |
722 | 208..211 'key': &K | 726 | 208..211 'key': &K |
723 | 228..231 'key': &K | 727 | 228..231 'key': &K |
724 | 290..293 '{ }': () | 728 | 290..293 '{ }': () |
725 | "### | 729 | "#]], |
726 | ); | 730 | ); |
727 | } | 731 | } |
728 | 732 | ||
729 | #[test] | 733 | #[test] |
730 | fn issue_4800() { | 734 | fn issue_4800() { |
731 | assert_snapshot!( | 735 | check_infer( |
732 | infer(r#" | 736 | r#" |
733 | trait Debug {} | 737 | trait Debug {} |
734 | 738 | ||
735 | struct Foo<T>; | 739 | struct Foo<T>; |
736 | 740 | ||
737 | type E1<T> = (T, T, T); | 741 | type E1<T> = (T, T, T); |
738 | type E2<T> = E1<E1<E1<(T, T, T)>>>; | 742 | type E2<T> = E1<E1<E1<(T, T, T)>>>; |
739 | 743 | ||
740 | impl Debug for Foo<E2<()>> {} | 744 | impl Debug for Foo<E2<()>> {} |
741 | 745 | ||
742 | struct Request; | 746 | struct Request; |
743 | 747 | ||
744 | pub trait Future { | 748 | pub trait Future { |
745 | type Output; | 749 | type Output; |
746 | } | 750 | } |
747 | 751 | ||
748 | pub struct PeerSet<D>; | 752 | pub struct PeerSet<D>; |
749 | 753 | ||
750 | impl<D> Service<Request> for PeerSet<D> | 754 | impl<D> Service<Request> for PeerSet<D> |
751 | where | 755 | where |
752 | D: Discover, | 756 | D: Discover, |
753 | D::Key: Debug, | 757 | D::Key: Debug, |
754 | { | 758 | { |
755 | type Error = (); | 759 | type Error = (); |
756 | type Future = dyn Future<Output = Self::Error>; | 760 | type Future = dyn Future<Output = Self::Error>; |
757 | 761 | ||
758 | fn call(&mut self) -> Self::Future { | 762 | fn call(&mut self) -> Self::Future { |
759 | loop {} | 763 | loop {} |
760 | } | 764 | } |
761 | } | 765 | } |
762 | 766 | ||
763 | pub trait Discover { | 767 | pub trait Discover { |
764 | type Key; | 768 | type Key; |
765 | } | 769 | } |
766 | 770 | ||
767 | pub trait Service<Request> { | 771 | pub trait Service<Request> { |
768 | type Error; | 772 | type Error; |
769 | type Future: Future<Output = Self::Error>; | 773 | type Future: Future<Output = Self::Error>; |
770 | fn call(&mut self) -> Self::Future; | 774 | fn call(&mut self) -> Self::Future; |
775 | } | ||
776 | "#, | ||
777 | expect![[r#" | ||
778 | 379..383 'self': &mut PeerSet<D> | ||
779 | 401..424 '{ ... }': dyn Future<Output = ()> | ||
780 | 411..418 'loop {}': ! | ||
781 | 416..418 '{}': () | ||
782 | 575..579 'self': &mut Self | ||
783 | "#]], | ||
784 | ); | ||
771 | } | 785 | } |
772 | "#), | 786 | |
773 | @r###" | 787 | #[test] |
774 | 379..383 'self': &mut PeerSet<D> | 788 | fn issue_4966() { |
775 | 401..424 '{ ... }': dyn Future<Output = ()> | 789 | check_infer( |
776 | 411..418 'loop {}': ! | 790 | r#" |
777 | 416..418 '{}': () | 791 | pub trait IntoIterator { |
778 | 575..579 'self': &mut Self | 792 | type Item; |
779 | "### | 793 | } |
794 | |||
795 | struct Repeat<A> { element: A } | ||
796 | |||
797 | struct Map<F> { f: F } | ||
798 | |||
799 | struct Vec<T> {} | ||
800 | |||
801 | #[lang = "deref"] | ||
802 | pub trait Deref { | ||
803 | type Target; | ||
804 | } | ||
805 | |||
806 | impl<T> Deref for Vec<T> { | ||
807 | type Target = [T]; | ||
808 | } | ||
809 | |||
810 | fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {} | ||
811 | |||
812 | fn main() { | ||
813 | let inner = Map { f: |_: &f64| 0.0 }; | ||
814 | |||
815 | let repeat = Repeat { element: inner }; | ||
816 | |||
817 | let vec = from_iter(repeat); | ||
818 | |||
819 | vec.foo_bar(); | ||
820 | } | ||
821 | "#, | ||
822 | expect![[r#" | ||
823 | 270..274 'iter': T | ||
824 | 289..291 '{}': () | ||
825 | 303..447 '{ ...r(); }': () | ||
826 | 313..318 'inner': Map<|&f64| -> f64> | ||
827 | 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> | ||
828 | 330..343 '|_: &f64| 0.0': |&f64| -> f64 | ||
829 | 331..332 '_': &f64 | ||
830 | 340..343 '0.0': f64 | ||
831 | 356..362 'repeat': Repeat<Map<|&f64| -> f64>> | ||
832 | 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> | ||
833 | 383..388 'inner': Map<|&f64| -> f64> | ||
834 | 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
835 | 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
836 | 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
837 | 417..423 'repeat': Repeat<Map<|&f64| -> f64>> | ||
838 | 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | ||
839 | 431..444 'vec.foo_bar()': {unknown} | ||
840 | "#]], | ||
780 | ); | 841 | ); |
781 | } | 842 | } |
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index de63f4cce..3fd7d5cd4 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer}; | 3 | use super::{check_infer, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_box() { | 6 | fn infer_box() { |
@@ -45,43 +45,44 @@ fn test() { | |||
45 | 45 | ||
46 | #[test] | 46 | #[test] |
47 | fn self_in_struct_lit() { | 47 | fn self_in_struct_lit() { |
48 | assert_snapshot!(infer( | 48 | check_infer( |
49 | r#" | 49 | r#" |
50 | //- /main.rs | 50 | //- /main.rs |
51 | struct S<T> { x: T } | 51 | struct S<T> { x: T } |
52 | 52 | ||
53 | impl S<u32> { | 53 | impl S<u32> { |
54 | fn foo() { | 54 | fn foo() { |
55 | Self { x: 1 }; | 55 | Self { x: 1 }; |
56 | } | 56 | } |
57 | } | 57 | } |
58 | "#, | 58 | "#, |
59 | ), @r###" | 59 | expect![[r#" |
60 | 49..79 '{ ... }': () | 60 | 49..79 '{ ... }': () |
61 | 59..72 'Self { x: 1 }': S<u32> | 61 | 59..72 'Self { x: 1 }': S<u32> |
62 | 69..70 '1': u32 | 62 | 69..70 '1': u32 |
63 | "###); | 63 | "#]], |
64 | ); | ||
64 | } | 65 | } |
65 | 66 | ||
66 | #[test] | 67 | #[test] |
67 | fn type_alias_in_struct_lit() { | 68 | fn type_alias_in_struct_lit() { |
68 | assert_snapshot!(infer( | 69 | check_infer( |
69 | r#" | 70 | r#" |
70 | //- /main.rs | 71 | //- /main.rs |
71 | struct S<T> { x: T } | 72 | struct S<T> { x: T } |
72 | 73 | ||
73 | type SS = S<u32>; | 74 | type SS = S<u32>; |
74 | 75 | ||
75 | fn foo() { | 76 | fn foo() { |
76 | SS { x: 1 }; | 77 | SS { x: 1 }; |
77 | } | 78 | } |
78 | 79 | "#, | |
79 | "#, | 80 | expect![[r#" |
80 | ), @r###" | 81 | 50..70 '{ ...1 }; }': () |
81 | 50..70 '{ ...1 }; }': () | 82 | 56..67 'SS { x: 1 }': S<u32> |
82 | 56..67 'SS { x: 1 }': S<u32> | 83 | 64..65 '1': u32 |
83 | 64..65 '1': u32 | 84 | "#]], |
84 | "###); | 85 | ); |
85 | } | 86 | } |
86 | 87 | ||
87 | #[test] | 88 | #[test] |
@@ -148,1526 +149,1549 @@ fn test() { | |||
148 | 149 | ||
149 | #[test] | 150 | #[test] |
150 | fn infer_basics() { | 151 | fn infer_basics() { |
151 | assert_snapshot!( | 152 | check_infer( |
152 | infer(r#" | 153 | r#" |
153 | fn test(a: u32, b: isize, c: !, d: &str) { | 154 | fn test(a: u32, b: isize, c: !, d: &str) { |
154 | a; | 155 | a; |
155 | b; | 156 | b; |
156 | c; | 157 | c; |
157 | d; | 158 | d; |
158 | 1usize; | 159 | 1usize; |
159 | 1isize; | 160 | 1isize; |
160 | "test"; | 161 | "test"; |
161 | 1.0f32; | 162 | 1.0f32; |
162 | }"#), | 163 | }"#, |
163 | @r###" | 164 | expect![[r#" |
164 | 8..9 'a': u32 | 165 | 8..9 'a': u32 |
165 | 16..17 'b': isize | 166 | 16..17 'b': isize |
166 | 26..27 'c': ! | 167 | 26..27 'c': ! |
167 | 32..33 'd': &str | 168 | 32..33 'd': &str |
168 | 41..120 '{ ...f32; }': () | 169 | 41..120 '{ ...f32; }': () |
169 | 47..48 'a': u32 | 170 | 47..48 'a': u32 |
170 | 54..55 'b': isize | 171 | 54..55 'b': isize |
171 | 61..62 'c': ! | 172 | 61..62 'c': ! |
172 | 68..69 'd': &str | 173 | 68..69 'd': &str |
173 | 75..81 '1usize': usize | 174 | 75..81 '1usize': usize |
174 | 87..93 '1isize': isize | 175 | 87..93 '1isize': isize |
175 | 99..105 '"test"': &str | 176 | 99..105 '"test"': &str |
176 | 111..117 '1.0f32': f32 | 177 | 111..117 '1.0f32': f32 |
177 | "### | 178 | "#]], |
178 | ); | 179 | ); |
179 | } | 180 | } |
180 | 181 | ||
181 | #[test] | 182 | #[test] |
182 | fn infer_let() { | 183 | fn infer_let() { |
183 | assert_snapshot!( | 184 | check_infer( |
184 | infer(r#" | 185 | r#" |
185 | fn test() { | 186 | fn test() { |
186 | let a = 1isize; | 187 | let a = 1isize; |
187 | let b: usize = 1; | 188 | let b: usize = 1; |
188 | let c = b; | 189 | let c = b; |
189 | let d: u32; | 190 | let d: u32; |
190 | let e; | 191 | let e; |
191 | let f: i32 = e; | 192 | let f: i32 = e; |
192 | } | 193 | } |
193 | "#), | 194 | "#, |
194 | @r###" | 195 | expect![[r#" |
195 | 10..117 '{ ...= e; }': () | 196 | 10..117 '{ ...= e; }': () |
196 | 20..21 'a': isize | 197 | 20..21 'a': isize |
197 | 24..30 '1isize': isize | 198 | 24..30 '1isize': isize |
198 | 40..41 'b': usize | 199 | 40..41 'b': usize |
199 | 51..52 '1': usize | 200 | 51..52 '1': usize |
200 | 62..63 'c': usize | 201 | 62..63 'c': usize |
201 | 66..67 'b': usize | 202 | 66..67 'b': usize |
202 | 77..78 'd': u32 | 203 | 77..78 'd': u32 |
203 | 93..94 'e': i32 | 204 | 93..94 'e': i32 |
204 | 104..105 'f': i32 | 205 | 104..105 'f': i32 |
205 | 113..114 'e': i32 | 206 | 113..114 'e': i32 |
206 | "### | 207 | "#]], |
207 | ); | 208 | ); |
208 | } | 209 | } |
209 | 210 | ||
210 | #[test] | 211 | #[test] |
211 | fn infer_paths() { | 212 | fn infer_paths() { |
212 | assert_snapshot!( | 213 | check_infer( |
213 | infer(r#" | 214 | r#" |
214 | fn a() -> u32 { 1 } | 215 | fn a() -> u32 { 1 } |
215 | 216 | ||
216 | mod b { | 217 | mod b { |
217 | fn c() -> u32 { 1 } | 218 | fn c() -> u32 { 1 } |
218 | } | 219 | } |
219 | 220 | ||
220 | fn test() { | 221 | fn test() { |
221 | a(); | 222 | a(); |
222 | b::c(); | 223 | b::c(); |
223 | } | 224 | } |
224 | "#), | 225 | "#, |
225 | @r###" | 226 | expect![[r#" |
226 | 14..19 '{ 1 }': u32 | 227 | 14..19 '{ 1 }': u32 |
227 | 16..17 '1': u32 | 228 | 16..17 '1': u32 |
228 | 47..52 '{ 1 }': u32 | 229 | 47..52 '{ 1 }': u32 |
229 | 49..50 '1': u32 | 230 | 49..50 '1': u32 |
230 | 66..90 '{ ...c(); }': () | 231 | 66..90 '{ ...c(); }': () |
231 | 72..73 'a': fn a() -> u32 | 232 | 72..73 'a': fn a() -> u32 |
232 | 72..75 'a()': u32 | 233 | 72..75 'a()': u32 |
233 | 81..85 'b::c': fn c() -> u32 | 234 | 81..85 'b::c': fn c() -> u32 |
234 | 81..87 'b::c()': u32 | 235 | 81..87 'b::c()': u32 |
235 | "### | 236 | "#]], |
236 | ); | 237 | ); |
237 | } | 238 | } |
238 | 239 | ||
239 | #[test] | 240 | #[test] |
240 | fn infer_path_type() { | 241 | fn infer_path_type() { |
241 | assert_snapshot!( | 242 | check_infer( |
242 | infer(r#" | 243 | r#" |
243 | struct S; | 244 | struct S; |
244 | 245 | ||
245 | impl S { | 246 | impl S { |
246 | fn foo() -> i32 { 1 } | 247 | fn foo() -> i32 { 1 } |
247 | } | 248 | } |
248 | 249 | ||
249 | fn test() { | 250 | fn test() { |
250 | S::foo(); | 251 | S::foo(); |
251 | <S>::foo(); | 252 | <S>::foo(); |
252 | } | 253 | } |
253 | "#), | 254 | "#, |
254 | @r###" | 255 | expect![[r#" |
255 | 40..45 '{ 1 }': i32 | 256 | 40..45 '{ 1 }': i32 |
256 | 42..43 '1': i32 | 257 | 42..43 '1': i32 |
257 | 59..92 '{ ...o(); }': () | 258 | 59..92 '{ ...o(); }': () |
258 | 65..71 'S::foo': fn foo() -> i32 | 259 | 65..71 'S::foo': fn foo() -> i32 |
259 | 65..73 'S::foo()': i32 | 260 | 65..73 'S::foo()': i32 |
260 | 79..87 '<S>::foo': fn foo() -> i32 | 261 | 79..87 '<S>::foo': fn foo() -> i32 |
261 | 79..89 '<S>::foo()': i32 | 262 | 79..89 '<S>::foo()': i32 |
262 | "### | 263 | "#]], |
263 | ); | 264 | ); |
264 | } | 265 | } |
265 | 266 | ||
266 | #[test] | 267 | #[test] |
267 | fn infer_struct() { | 268 | fn infer_struct() { |
268 | assert_snapshot!( | 269 | check_infer( |
269 | infer(r#" | 270 | r#" |
270 | struct A { | 271 | struct A { |
271 | b: B, | 272 | b: B, |
272 | c: C, | 273 | c: C, |
273 | } | 274 | } |
274 | struct B; | 275 | struct B; |
275 | struct C(usize); | 276 | struct C(usize); |
276 | 277 | ||
277 | fn test() { | 278 | fn test() { |
278 | let c = C(1); | 279 | let c = C(1); |
279 | B; | 280 | B; |
280 | let a: A = A { b: B, c: C(1) }; | 281 | let a: A = A { b: B, c: C(1) }; |
281 | a.b; | 282 | a.b; |
282 | a.c; | 283 | a.c; |
283 | } | 284 | } |
284 | "#), | 285 | "#, |
285 | @r###" | 286 | expect![[r#" |
286 | 71..153 '{ ...a.c; }': () | 287 | 71..153 '{ ...a.c; }': () |
287 | 81..82 'c': C | 288 | 81..82 'c': C |
288 | 85..86 'C': C(usize) -> C | 289 | 85..86 'C': C(usize) -> C |
289 | 85..89 'C(1)': C | 290 | 85..89 'C(1)': C |
290 | 87..88 '1': usize | 291 | 87..88 '1': usize |
291 | 95..96 'B': B | 292 | 95..96 'B': B |
292 | 106..107 'a': A | 293 | 106..107 'a': A |
293 | 113..132 'A { b:...C(1) }': A | 294 | 113..132 'A { b:...C(1) }': A |
294 | 120..121 'B': B | 295 | 120..121 'B': B |
295 | 126..127 'C': C(usize) -> C | 296 | 126..127 'C': C(usize) -> C |
296 | 126..130 'C(1)': C | 297 | 126..130 'C(1)': C |
297 | 128..129 '1': usize | 298 | 128..129 '1': usize |
298 | 138..139 'a': A | 299 | 138..139 'a': A |
299 | 138..141 'a.b': B | 300 | 138..141 'a.b': B |
300 | 147..148 'a': A | 301 | 147..148 'a': A |
301 | 147..150 'a.c': C | 302 | 147..150 'a.c': C |
302 | "### | 303 | "#]], |
303 | ); | 304 | ); |
304 | } | 305 | } |
305 | 306 | ||
306 | #[test] | 307 | #[test] |
307 | fn infer_enum() { | 308 | fn infer_enum() { |
308 | assert_snapshot!( | 309 | check_infer( |
309 | infer(r#" | 310 | r#" |
310 | enum E { | 311 | enum E { |
311 | V1 { field: u32 }, | 312 | V1 { field: u32 }, |
312 | V2 | 313 | V2 |
314 | } | ||
315 | fn test() { | ||
316 | E::V1 { field: 1 }; | ||
317 | E::V2; | ||
318 | }"#, | ||
319 | expect![[r#" | ||
320 | 51..89 '{ ...:V2; }': () | ||
321 | 57..75 'E::V1 ...d: 1 }': E | ||
322 | 72..73 '1': u32 | ||
323 | 81..86 'E::V2': E | ||
324 | "#]], | ||
325 | ); | ||
313 | } | 326 | } |
314 | fn test() { | 327 | |
315 | E::V1 { field: 1 }; | 328 | #[test] |
316 | E::V2; | 329 | fn infer_union() { |
317 | }"#), | 330 | check_infer( |
318 | @r###" | 331 | r#" |
319 | 47..81 '{ E:...:V2; }': () | 332 | union MyUnion { |
320 | 51..69 'E::V1 ...d: 1 }': E | 333 | foo: u32, |
321 | 66..67 '1': u32 | 334 | bar: f32, |
322 | 73..78 'E::V2': E | 335 | } |
323 | "### | 336 | |
337 | unsafe fn baz(u: MyUnion) { | ||
338 | let inner = u.foo; | ||
339 | } | ||
340 | "#, | ||
341 | expect![[r#" | ||
342 | 61..62 'u': MyUnion | ||
343 | 73..99 '{ ...foo; }': () | ||
344 | 83..88 'inner': u32 | ||
345 | 91..92 'u': MyUnion | ||
346 | 91..96 'u.foo': u32 | ||
347 | "#]], | ||
324 | ); | 348 | ); |
325 | } | 349 | } |
326 | 350 | ||
327 | #[test] | 351 | #[test] |
328 | fn infer_refs() { | 352 | fn infer_refs() { |
329 | assert_snapshot!( | 353 | check_infer( |
330 | infer(r#" | 354 | r#" |
331 | fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { | 355 | fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { |
332 | a; | 356 | a; |
333 | *a; | 357 | *a; |
334 | &a; | 358 | &a; |
335 | &mut a; | 359 | &mut a; |
336 | b; | 360 | b; |
337 | *b; | 361 | *b; |
338 | &b; | 362 | &b; |
339 | c; | 363 | c; |
340 | *c; | 364 | *c; |
341 | d; | 365 | d; |
342 | *d; | 366 | *d; |
343 | } | 367 | } |
344 | "#), | 368 | "#, |
345 | @r###" | 369 | expect![[r#" |
346 | 8..9 'a': &u32 | 370 | 8..9 'a': &u32 |
347 | 17..18 'b': &mut u32 | 371 | 17..18 'b': &mut u32 |
348 | 30..31 'c': *const u32 | 372 | 30..31 'c': *const u32 |
349 | 45..46 'd': *mut u32 | 373 | 45..46 'd': *mut u32 |
350 | 58..149 '{ ... *d; }': () | 374 | 58..149 '{ ... *d; }': () |
351 | 64..65 'a': &u32 | 375 | 64..65 'a': &u32 |
352 | 71..73 '*a': u32 | 376 | 71..73 '*a': u32 |
353 | 72..73 'a': &u32 | 377 | 72..73 'a': &u32 |
354 | 79..81 '&a': &&u32 | 378 | 79..81 '&a': &&u32 |
355 | 80..81 'a': &u32 | 379 | 80..81 'a': &u32 |
356 | 87..93 '&mut a': &mut &u32 | 380 | 87..93 '&mut a': &mut &u32 |
357 | 92..93 'a': &u32 | 381 | 92..93 'a': &u32 |
358 | 99..100 'b': &mut u32 | 382 | 99..100 'b': &mut u32 |
359 | 106..108 '*b': u32 | 383 | 106..108 '*b': u32 |
360 | 107..108 'b': &mut u32 | 384 | 107..108 'b': &mut u32 |
361 | 114..116 '&b': &&mut u32 | 385 | 114..116 '&b': &&mut u32 |
362 | 115..116 'b': &mut u32 | 386 | 115..116 'b': &mut u32 |
363 | 122..123 'c': *const u32 | 387 | 122..123 'c': *const u32 |
364 | 129..131 '*c': u32 | 388 | 129..131 '*c': u32 |
365 | 130..131 'c': *const u32 | 389 | 130..131 'c': *const u32 |
366 | 137..138 'd': *mut u32 | 390 | 137..138 'd': *mut u32 |
367 | 144..146 '*d': u32 | 391 | 144..146 '*d': u32 |
368 | 145..146 'd': *mut u32 | 392 | 145..146 'd': *mut u32 |
369 | "### | 393 | "#]], |
370 | ); | 394 | ); |
371 | } | 395 | } |
372 | 396 | ||
373 | #[test] | 397 | #[test] |
374 | fn infer_raw_ref() { | 398 | fn infer_raw_ref() { |
375 | assert_snapshot!( | 399 | check_infer( |
376 | infer(r#" | 400 | r#" |
377 | fn test(a: i32) { | 401 | fn test(a: i32) { |
378 | &raw mut a; | 402 | &raw mut a; |
379 | &raw const a; | 403 | &raw const a; |
380 | } | 404 | } |
381 | "#), | 405 | "#, |
382 | @r###" | 406 | expect![[r#" |
383 | 8..9 'a': i32 | 407 | 8..9 'a': i32 |
384 | 16..53 '{ ...t a; }': () | 408 | 16..53 '{ ...t a; }': () |
385 | 22..32 '&raw mut a': *mut i32 | 409 | 22..32 '&raw mut a': *mut i32 |
386 | 31..32 'a': i32 | 410 | 31..32 'a': i32 |
387 | 38..50 '&raw const a': *const i32 | 411 | 38..50 '&raw const a': *const i32 |
388 | 49..50 'a': i32 | 412 | 49..50 'a': i32 |
389 | "### | 413 | "#]], |
390 | ); | 414 | ); |
391 | } | 415 | } |
392 | 416 | ||
393 | #[test] | 417 | #[test] |
394 | fn infer_literals() { | 418 | fn infer_literals() { |
395 | assert_snapshot!( | 419 | check_infer( |
396 | infer(r##" | 420 | r##" |
397 | fn test() { | 421 | fn test() { |
398 | 5i32; | 422 | 5i32; |
399 | 5f32; | 423 | 5f32; |
400 | 5f64; | 424 | 5f64; |
401 | "hello"; | 425 | "hello"; |
402 | b"bytes"; | 426 | b"bytes"; |
403 | 'c'; | 427 | 'c'; |
404 | b'b'; | 428 | b'b'; |
405 | 3.14; | 429 | 3.14; |
406 | 5000; | 430 | 5000; |
407 | false; | 431 | false; |
408 | true; | 432 | true; |
409 | r#" | 433 | r#" |
410 | //! doc | 434 | //! doc |
411 | // non-doc | 435 | // non-doc |
412 | mod foo {} | 436 | mod foo {} |
413 | "#; | 437 | "#; |
414 | br#"yolo"#; | 438 | br#"yolo"#; |
415 | } | 439 | } |
416 | "##), | 440 | "##, |
417 | @r###" | 441 | expect![[r##" |
418 | 10..220 '{ ...o"#; }': () | 442 | 10..216 '{ ...o"#; }': () |
419 | 16..20 '5i32': i32 | 443 | 16..20 '5i32': i32 |
420 | 26..30 '5f32': f32 | 444 | 26..30 '5f32': f32 |
421 | 36..40 '5f64': f64 | 445 | 36..40 '5f64': f64 |
422 | 46..53 '"hello"': &str | 446 | 46..53 '"hello"': &str |
423 | 59..67 'b"bytes"': &[u8; _] | 447 | 59..67 'b"bytes"': &[u8; _] |
424 | 73..76 ''c'': char | 448 | 73..76 ''c'': char |
425 | 82..86 'b'b'': u8 | 449 | 82..86 'b'b'': u8 |
426 | 92..96 '3.14': f64 | 450 | 92..96 '3.14': f64 |
427 | 102..106 '5000': i32 | 451 | 102..106 '5000': i32 |
428 | 112..117 'false': bool | 452 | 112..117 'false': bool |
429 | 123..127 'true': bool | 453 | 123..127 'true': bool |
430 | 133..201 'r#" ... "#': &str | 454 | 133..197 'r#" ... "#': &str |
431 | 207..217 'br#"yolo"#': &[u8; _] | 455 | 203..213 'br#"yolo"#': &[u8; _] |
432 | "### | 456 | "##]], |
433 | ); | 457 | ); |
434 | } | 458 | } |
435 | 459 | ||
436 | #[test] | 460 | #[test] |
437 | fn infer_unary_op() { | 461 | fn infer_unary_op() { |
438 | assert_snapshot!( | 462 | check_infer( |
439 | infer(r#" | 463 | r#" |
440 | enum SomeType {} | 464 | enum SomeType {} |
441 | 465 | ||
442 | fn test(x: SomeType) { | 466 | fn test(x: SomeType) { |
443 | let b = false; | 467 | let b = false; |
444 | let c = !b; | 468 | let c = !b; |
445 | let a = 100; | 469 | let a = 100; |
446 | let d: i128 = -a; | 470 | let d: i128 = -a; |
447 | let e = -100; | 471 | let e = -100; |
448 | let f = !!!true; | 472 | let f = !!!true; |
449 | let g = !42; | 473 | let g = !42; |
450 | let h = !10u32; | 474 | let h = !10u32; |
451 | let j = !a; | 475 | let j = !a; |
452 | -3.14; | 476 | -3.14; |
453 | !3; | 477 | !3; |
454 | -x; | 478 | -x; |
455 | !x; | 479 | !x; |
456 | -"hello"; | 480 | -"hello"; |
457 | !"hello"; | 481 | !"hello"; |
458 | } | 482 | } |
459 | "#), | 483 | "#, |
460 | @r###" | 484 | expect![[r#" |
461 | 26..27 'x': SomeType | 485 | 26..27 'x': SomeType |
462 | 39..271 '{ ...lo"; }': () | 486 | 39..271 '{ ...lo"; }': () |
463 | 49..50 'b': bool | 487 | 49..50 'b': bool |
464 | 53..58 'false': bool | 488 | 53..58 'false': bool |
465 | 68..69 'c': bool | 489 | 68..69 'c': bool |
466 | 72..74 '!b': bool | 490 | 72..74 '!b': bool |
467 | 73..74 'b': bool | 491 | 73..74 'b': bool |
468 | 84..85 'a': i128 | 492 | 84..85 'a': i128 |
469 | 88..91 '100': i128 | 493 | 88..91 '100': i128 |
470 | 101..102 'd': i128 | 494 | 101..102 'd': i128 |
471 | 111..113 '-a': i128 | 495 | 111..113 '-a': i128 |
472 | 112..113 'a': i128 | 496 | 112..113 'a': i128 |
473 | 123..124 'e': i32 | 497 | 123..124 'e': i32 |
474 | 127..131 '-100': i32 | 498 | 127..131 '-100': i32 |
475 | 128..131 '100': i32 | 499 | 128..131 '100': i32 |
476 | 141..142 'f': bool | 500 | 141..142 'f': bool |
477 | 145..152 '!!!true': bool | 501 | 145..152 '!!!true': bool |
478 | 146..152 '!!true': bool | 502 | 146..152 '!!true': bool |
479 | 147..152 '!true': bool | 503 | 147..152 '!true': bool |
480 | 148..152 'true': bool | 504 | 148..152 'true': bool |
481 | 162..163 'g': i32 | 505 | 162..163 'g': i32 |
482 | 166..169 '!42': i32 | 506 | 166..169 '!42': i32 |
483 | 167..169 '42': i32 | 507 | 167..169 '42': i32 |
484 | 179..180 'h': u32 | 508 | 179..180 'h': u32 |
485 | 183..189 '!10u32': u32 | 509 | 183..189 '!10u32': u32 |
486 | 184..189 '10u32': u32 | 510 | 184..189 '10u32': u32 |
487 | 199..200 'j': i128 | 511 | 199..200 'j': i128 |
488 | 203..205 '!a': i128 | 512 | 203..205 '!a': i128 |
489 | 204..205 'a': i128 | 513 | 204..205 'a': i128 |
490 | 211..216 '-3.14': f64 | 514 | 211..216 '-3.14': f64 |
491 | 212..216 '3.14': f64 | 515 | 212..216 '3.14': f64 |
492 | 222..224 '!3': i32 | 516 | 222..224 '!3': i32 |
493 | 223..224 '3': i32 | 517 | 223..224 '3': i32 |
494 | 230..232 '-x': {unknown} | 518 | 230..232 '-x': {unknown} |
495 | 231..232 'x': SomeType | 519 | 231..232 'x': SomeType |
496 | 238..240 '!x': {unknown} | 520 | 238..240 '!x': {unknown} |
497 | 239..240 'x': SomeType | 521 | 239..240 'x': SomeType |
498 | 246..254 '-"hello"': {unknown} | 522 | 246..254 '-"hello"': {unknown} |
499 | 247..254 '"hello"': &str | 523 | 247..254 '"hello"': &str |
500 | 260..268 '!"hello"': {unknown} | 524 | 260..268 '!"hello"': {unknown} |
501 | 261..268 '"hello"': &str | 525 | 261..268 '"hello"': &str |
502 | "### | 526 | "#]], |
503 | ); | 527 | ); |
504 | } | 528 | } |
505 | 529 | ||
506 | #[test] | 530 | #[test] |
507 | fn infer_backwards() { | 531 | fn infer_backwards() { |
508 | assert_snapshot!( | 532 | check_infer( |
509 | infer(r#" | 533 | r#" |
510 | fn takes_u32(x: u32) {} | 534 | fn takes_u32(x: u32) {} |
511 | 535 | ||
512 | struct S { i32_field: i32 } | 536 | struct S { i32_field: i32 } |
513 | 537 | ||
514 | fn test() -> &mut &f64 { | 538 | fn test() -> &mut &f64 { |
515 | let a = unknown_function(); | 539 | let a = unknown_function(); |
516 | takes_u32(a); | 540 | takes_u32(a); |
517 | let b = unknown_function(); | 541 | let b = unknown_function(); |
518 | S { i32_field: b }; | 542 | S { i32_field: b }; |
519 | let c = unknown_function(); | 543 | let c = unknown_function(); |
520 | &mut &c | 544 | &mut &c |
521 | } | 545 | } |
522 | "#), | 546 | "#, |
523 | @r###" | 547 | expect![[r#" |
524 | 13..14 'x': u32 | 548 | 13..14 'x': u32 |
525 | 21..23 '{}': () | 549 | 21..23 '{}': () |
526 | 77..230 '{ ...t &c }': &mut &f64 | 550 | 77..230 '{ ...t &c }': &mut &f64 |
527 | 87..88 'a': u32 | 551 | 87..88 'a': u32 |
528 | 91..107 'unknow...nction': {unknown} | 552 | 91..107 'unknow...nction': {unknown} |
529 | 91..109 'unknow...tion()': u32 | 553 | 91..109 'unknow...tion()': u32 |
530 | 115..124 'takes_u32': fn takes_u32(u32) | 554 | 115..124 'takes_u32': fn takes_u32(u32) |
531 | 115..127 'takes_u32(a)': () | 555 | 115..127 'takes_u32(a)': () |
532 | 125..126 'a': u32 | 556 | 125..126 'a': u32 |
533 | 137..138 'b': i32 | 557 | 137..138 'b': i32 |
534 | 141..157 'unknow...nction': {unknown} | 558 | 141..157 'unknow...nction': {unknown} |
535 | 141..159 'unknow...tion()': i32 | 559 | 141..159 'unknow...tion()': i32 |
536 | 165..183 'S { i3...d: b }': S | 560 | 165..183 'S { i3...d: b }': S |
537 | 180..181 'b': i32 | 561 | 180..181 'b': i32 |
538 | 193..194 'c': f64 | 562 | 193..194 'c': f64 |
539 | 197..213 'unknow...nction': {unknown} | 563 | 197..213 'unknow...nction': {unknown} |
540 | 197..215 'unknow...tion()': f64 | 564 | 197..215 'unknow...tion()': f64 |
541 | 221..228 '&mut &c': &mut &f64 | 565 | 221..228 '&mut &c': &mut &f64 |
542 | 226..228 '&c': &f64 | 566 | 226..228 '&c': &f64 |
543 | 227..228 'c': f64 | 567 | 227..228 'c': f64 |
544 | "### | 568 | "#]], |
545 | ); | 569 | ); |
546 | } | 570 | } |
547 | 571 | ||
548 | #[test] | 572 | #[test] |
549 | fn infer_self() { | 573 | fn infer_self() { |
550 | assert_snapshot!( | 574 | check_infer( |
551 | infer(r#" | 575 | r#" |
552 | struct S; | 576 | struct S; |
553 | 577 | ||
554 | impl S { | 578 | impl S { |
555 | fn test(&self) { | 579 | fn test(&self) { |
556 | self; | 580 | self; |
557 | } | 581 | } |
558 | fn test2(self: &Self) { | 582 | fn test2(self: &Self) { |
559 | self; | 583 | self; |
560 | } | 584 | } |
561 | fn test3() -> Self { | 585 | fn test3() -> Self { |
562 | S {} | 586 | S {} |
563 | } | 587 | } |
564 | fn test4() -> Self { | 588 | fn test4() -> Self { |
565 | Self {} | 589 | Self {} |
566 | } | 590 | } |
567 | } | 591 | } |
568 | "#), | 592 | "#, |
569 | @r###" | 593 | expect![[r#" |
570 | 33..37 'self': &S | 594 | 33..37 'self': &S |
571 | 39..60 '{ ... }': () | 595 | 39..60 '{ ... }': () |
572 | 49..53 'self': &S | 596 | 49..53 'self': &S |
573 | 74..78 'self': &S | 597 | 74..78 'self': &S |
574 | 87..108 '{ ... }': () | 598 | 87..108 '{ ... }': () |
575 | 97..101 'self': &S | 599 | 97..101 'self': &S |
576 | 132..152 '{ ... }': S | 600 | 132..152 '{ ... }': S |
577 | 142..146 'S {}': S | 601 | 142..146 'S {}': S |
578 | 176..199 '{ ... }': S | 602 | 176..199 '{ ... }': S |
579 | 186..193 'Self {}': S | 603 | 186..193 'Self {}': S |
580 | "### | 604 | "#]], |
581 | ); | 605 | ); |
582 | } | 606 | } |
583 | 607 | ||
584 | #[test] | 608 | #[test] |
585 | fn infer_self_as_path() { | 609 | fn infer_self_as_path() { |
586 | assert_snapshot!( | 610 | check_infer( |
587 | infer(r#" | 611 | r#" |
588 | struct S1; | 612 | struct S1; |
589 | struct S2(isize); | 613 | struct S2(isize); |
590 | enum E { | 614 | enum E { |
591 | V1, | 615 | V1, |
592 | V2(u32), | 616 | V2(u32), |
593 | } | 617 | } |
594 | 618 | ||
595 | impl S1 { | 619 | impl S1 { |
596 | fn test() { | 620 | fn test() { |
597 | Self; | 621 | Self; |
598 | } | 622 | } |
599 | } | 623 | } |
600 | impl S2 { | 624 | impl S2 { |
601 | fn test() { | 625 | fn test() { |
602 | Self(1); | 626 | Self(1); |
603 | } | 627 | } |
604 | } | 628 | } |
605 | impl E { | 629 | impl E { |
606 | fn test() { | 630 | fn test() { |
607 | Self::V1; | 631 | Self::V1; |
608 | Self::V2(1); | 632 | Self::V2(1); |
609 | } | 633 | } |
610 | } | 634 | } |
611 | "#), | 635 | "#, |
612 | @r###" | 636 | expect![[r#" |
613 | 86..107 '{ ... }': () | 637 | 86..107 '{ ... }': () |
614 | 96..100 'Self': S1 | 638 | 96..100 'Self': S1 |
615 | 134..158 '{ ... }': () | 639 | 134..158 '{ ... }': () |
616 | 144..148 'Self': S2(isize) -> S2 | 640 | 144..148 'Self': S2(isize) -> S2 |
617 | 144..151 'Self(1)': S2 | 641 | 144..151 'Self(1)': S2 |
618 | 149..150 '1': isize | 642 | 149..150 '1': isize |
619 | 184..230 '{ ... }': () | 643 | 184..230 '{ ... }': () |
620 | 194..202 'Self::V1': E | 644 | 194..202 'Self::V1': E |
621 | 212..220 'Self::V2': V2(u32) -> E | 645 | 212..220 'Self::V2': V2(u32) -> E |
622 | 212..223 'Self::V2(1)': E | 646 | 212..223 'Self::V2(1)': E |
623 | 221..222 '1': u32 | 647 | 221..222 '1': u32 |
624 | "### | 648 | "#]], |
625 | ); | 649 | ); |
626 | } | 650 | } |
627 | 651 | ||
628 | #[test] | 652 | #[test] |
629 | fn infer_binary_op() { | 653 | fn infer_binary_op() { |
630 | assert_snapshot!( | 654 | check_infer( |
631 | infer(r#" | 655 | r#" |
632 | fn f(x: bool) -> i32 { | 656 | fn f(x: bool) -> i32 { |
633 | 0i32 | 657 | 0i32 |
634 | } | 658 | } |
635 | 659 | ||
636 | fn test() -> bool { | 660 | fn test() -> bool { |
637 | let x = a && b; | 661 | let x = a && b; |
638 | let y = true || false; | 662 | let y = true || false; |
639 | let z = x == y; | 663 | let z = x == y; |
640 | let t = x != y; | 664 | let t = x != y; |
641 | let minus_forty: isize = -40isize; | 665 | let minus_forty: isize = -40isize; |
642 | let h = minus_forty <= CONST_2; | 666 | let h = minus_forty <= CONST_2; |
643 | let c = f(z || y) + 5; | 667 | let c = f(z || y) + 5; |
644 | let d = b; | 668 | let d = b; |
645 | let g = minus_forty ^= i; | 669 | let g = minus_forty ^= i; |
646 | let ten: usize = 10; | 670 | let ten: usize = 10; |
647 | let ten_is_eleven = ten == some_num; | 671 | let ten_is_eleven = ten == some_num; |
648 | 672 | ||
649 | ten < 3 | 673 | ten < 3 |
650 | } | 674 | } |
651 | "#), | 675 | "#, |
652 | @r###" | 676 | expect![[r#" |
653 | 5..6 'x': bool | 677 | 5..6 'x': bool |
654 | 21..33 '{ 0i32 }': i32 | 678 | 21..33 '{ 0i32 }': i32 |
655 | 27..31 '0i32': i32 | 679 | 27..31 '0i32': i32 |
656 | 53..369 '{ ... < 3 }': bool | 680 | 53..369 '{ ... < 3 }': bool |
657 | 63..64 'x': bool | 681 | 63..64 'x': bool |
658 | 67..68 'a': bool | 682 | 67..68 'a': bool |
659 | 67..73 'a && b': bool | 683 | 67..73 'a && b': bool |
660 | 72..73 'b': bool | 684 | 72..73 'b': bool |
661 | 83..84 'y': bool | 685 | 83..84 'y': bool |
662 | 87..91 'true': bool | 686 | 87..91 'true': bool |
663 | 87..100 'true || false': bool | 687 | 87..100 'true || false': bool |
664 | 95..100 'false': bool | 688 | 95..100 'false': bool |
665 | 110..111 'z': bool | 689 | 110..111 'z': bool |
666 | 114..115 'x': bool | 690 | 114..115 'x': bool |
667 | 114..120 'x == y': bool | 691 | 114..120 'x == y': bool |
668 | 119..120 'y': bool | 692 | 119..120 'y': bool |
669 | 130..131 't': bool | 693 | 130..131 't': bool |
670 | 134..135 'x': bool | 694 | 134..135 'x': bool |
671 | 134..140 'x != y': bool | 695 | 134..140 'x != y': bool |
672 | 139..140 'y': bool | 696 | 139..140 'y': bool |
673 | 150..161 'minus_forty': isize | 697 | 150..161 'minus_forty': isize |
674 | 171..179 '-40isize': isize | 698 | 171..179 '-40isize': isize |
675 | 172..179 '40isize': isize | 699 | 172..179 '40isize': isize |
676 | 189..190 'h': bool | 700 | 189..190 'h': bool |
677 | 193..204 'minus_forty': isize | 701 | 193..204 'minus_forty': isize |
678 | 193..215 'minus_...ONST_2': bool | 702 | 193..215 'minus_...ONST_2': bool |
679 | 208..215 'CONST_2': isize | 703 | 208..215 'CONST_2': isize |
680 | 225..226 'c': i32 | 704 | 225..226 'c': i32 |
681 | 229..230 'f': fn f(bool) -> i32 | 705 | 229..230 'f': fn f(bool) -> i32 |
682 | 229..238 'f(z || y)': i32 | 706 | 229..238 'f(z || y)': i32 |
683 | 229..242 'f(z || y) + 5': i32 | 707 | 229..242 'f(z || y) + 5': i32 |
684 | 231..232 'z': bool | 708 | 231..232 'z': bool |
685 | 231..237 'z || y': bool | 709 | 231..237 'z || y': bool |
686 | 236..237 'y': bool | 710 | 236..237 'y': bool |
687 | 241..242 '5': i32 | 711 | 241..242 '5': i32 |
688 | 252..253 'd': {unknown} | 712 | 252..253 'd': {unknown} |
689 | 256..257 'b': {unknown} | 713 | 256..257 'b': {unknown} |
690 | 267..268 'g': () | 714 | 267..268 'g': () |
691 | 271..282 'minus_forty': isize | 715 | 271..282 'minus_forty': isize |
692 | 271..287 'minus_...y ^= i': () | 716 | 271..287 'minus_...y ^= i': () |
693 | 286..287 'i': isize | 717 | 286..287 'i': isize |
694 | 297..300 'ten': usize | 718 | 297..300 'ten': usize |
695 | 310..312 '10': usize | 719 | 310..312 '10': usize |
696 | 322..335 'ten_is_eleven': bool | 720 | 322..335 'ten_is_eleven': bool |
697 | 338..341 'ten': usize | 721 | 338..341 'ten': usize |
698 | 338..353 'ten == some_num': bool | 722 | 338..353 'ten == some_num': bool |
699 | 345..353 'some_num': usize | 723 | 345..353 'some_num': usize |
700 | 360..363 'ten': usize | 724 | 360..363 'ten': usize |
701 | 360..367 'ten < 3': bool | 725 | 360..367 'ten < 3': bool |
702 | 366..367 '3': usize | 726 | 366..367 '3': usize |
703 | "### | 727 | "#]], |
704 | ); | 728 | ); |
705 | } | 729 | } |
706 | 730 | ||
707 | #[test] | 731 | #[test] |
708 | fn infer_shift_op() { | 732 | fn infer_shift_op() { |
709 | assert_snapshot!( | 733 | check_infer( |
710 | infer(r#" | 734 | r#" |
711 | fn test() { | 735 | fn test() { |
712 | 1u32 << 5u8; | 736 | 1u32 << 5u8; |
713 | 1u32 >> 5u8; | 737 | 1u32 >> 5u8; |
714 | } | 738 | } |
715 | "#), | 739 | "#, |
716 | @r###" | 740 | expect![[r#" |
717 | 10..47 '{ ...5u8; }': () | 741 | 10..47 '{ ...5u8; }': () |
718 | 16..20 '1u32': u32 | 742 | 16..20 '1u32': u32 |
719 | 16..27 '1u32 << 5u8': u32 | 743 | 16..27 '1u32 << 5u8': u32 |
720 | 24..27 '5u8': u8 | 744 | 24..27 '5u8': u8 |
721 | 33..37 '1u32': u32 | 745 | 33..37 '1u32': u32 |
722 | 33..44 '1u32 >> 5u8': u32 | 746 | 33..44 '1u32 >> 5u8': u32 |
723 | 41..44 '5u8': u8 | 747 | 41..44 '5u8': u8 |
724 | "### | 748 | "#]], |
725 | ); | 749 | ); |
726 | } | 750 | } |
727 | 751 | ||
728 | #[test] | 752 | #[test] |
729 | fn infer_field_autoderef() { | 753 | fn infer_field_autoderef() { |
730 | assert_snapshot!( | 754 | check_infer( |
731 | infer(r#" | 755 | r#" |
732 | struct A { | 756 | struct A { |
733 | b: B, | 757 | b: B, |
734 | } | 758 | } |
735 | struct B; | 759 | struct B; |
736 | 760 | ||
737 | fn test1(a: A) { | 761 | fn test1(a: A) { |
738 | let a1 = a; | 762 | let a1 = a; |
739 | a1.b; | 763 | a1.b; |
740 | let a2 = &a; | 764 | let a2 = &a; |
741 | a2.b; | 765 | a2.b; |
742 | let a3 = &mut a; | 766 | let a3 = &mut a; |
743 | a3.b; | 767 | a3.b; |
744 | let a4 = &&&&&&&a; | 768 | let a4 = &&&&&&&a; |
745 | a4.b; | 769 | a4.b; |
746 | let a5 = &mut &&mut &&mut a; | 770 | let a5 = &mut &&mut &&mut a; |
747 | a5.b; | 771 | a5.b; |
748 | } | 772 | } |
749 | 773 | ||
750 | fn test2(a1: *const A, a2: *mut A) { | 774 | fn test2(a1: *const A, a2: *mut A) { |
751 | a1.b; | 775 | a1.b; |
752 | a2.b; | 776 | a2.b; |
753 | } | 777 | } |
754 | "#), | 778 | "#, |
755 | @r###" | 779 | expect![[r#" |
756 | 43..44 'a': A | 780 | 43..44 'a': A |
757 | 49..212 '{ ...5.b; }': () | 781 | 49..212 '{ ...5.b; }': () |
758 | 59..61 'a1': A | 782 | 59..61 'a1': A |
759 | 64..65 'a': A | 783 | 64..65 'a': A |
760 | 71..73 'a1': A | 784 | 71..73 'a1': A |
761 | 71..75 'a1.b': B | 785 | 71..75 'a1.b': B |
762 | 85..87 'a2': &A | 786 | 85..87 'a2': &A |
763 | 90..92 '&a': &A | 787 | 90..92 '&a': &A |
764 | 91..92 'a': A | 788 | 91..92 'a': A |
765 | 98..100 'a2': &A | 789 | 98..100 'a2': &A |
766 | 98..102 'a2.b': B | 790 | 98..102 'a2.b': B |
767 | 112..114 'a3': &mut A | 791 | 112..114 'a3': &mut A |
768 | 117..123 '&mut a': &mut A | 792 | 117..123 '&mut a': &mut A |
769 | 122..123 'a': A | 793 | 122..123 'a': A |
770 | 129..131 'a3': &mut A | 794 | 129..131 'a3': &mut A |
771 | 129..133 'a3.b': B | 795 | 129..133 'a3.b': B |
772 | 143..145 'a4': &&&&&&&A | 796 | 143..145 'a4': &&&&&&&A |
773 | 148..156 '&&&&&&&a': &&&&&&&A | 797 | 148..156 '&&&&&&&a': &&&&&&&A |
774 | 149..156 '&&&&&&a': &&&&&&A | 798 | 149..156 '&&&&&&a': &&&&&&A |
775 | 150..156 '&&&&&a': &&&&&A | 799 | 150..156 '&&&&&a': &&&&&A |
776 | 151..156 '&&&&a': &&&&A | 800 | 151..156 '&&&&a': &&&&A |
777 | 152..156 '&&&a': &&&A | 801 | 152..156 '&&&a': &&&A |
778 | 153..156 '&&a': &&A | 802 | 153..156 '&&a': &&A |
779 | 154..156 '&a': &A | 803 | 154..156 '&a': &A |
780 | 155..156 'a': A | 804 | 155..156 'a': A |
781 | 162..164 'a4': &&&&&&&A | 805 | 162..164 'a4': &&&&&&&A |
782 | 162..166 'a4.b': B | 806 | 162..166 'a4.b': B |
783 | 176..178 'a5': &mut &&mut &&mut A | 807 | 176..178 'a5': &mut &&mut &&mut A |
784 | 181..199 '&mut &...&mut a': &mut &&mut &&mut A | 808 | 181..199 '&mut &...&mut a': &mut &&mut &&mut A |
785 | 186..199 '&&mut &&mut a': &&mut &&mut A | 809 | 186..199 '&&mut &&mut a': &&mut &&mut A |
786 | 187..199 '&mut &&mut a': &mut &&mut A | 810 | 187..199 '&mut &&mut a': &mut &&mut A |
787 | 192..199 '&&mut a': &&mut A | 811 | 192..199 '&&mut a': &&mut A |
788 | 193..199 '&mut a': &mut A | 812 | 193..199 '&mut a': &mut A |
789 | 198..199 'a': A | 813 | 198..199 'a': A |
790 | 205..207 'a5': &mut &&mut &&mut A | 814 | 205..207 'a5': &mut &&mut &&mut A |
791 | 205..209 'a5.b': B | 815 | 205..209 'a5.b': B |
792 | 223..225 'a1': *const A | 816 | 223..225 'a1': *const A |
793 | 237..239 'a2': *mut A | 817 | 237..239 'a2': *mut A |
794 | 249..272 '{ ...2.b; }': () | 818 | 249..272 '{ ...2.b; }': () |
795 | 255..257 'a1': *const A | 819 | 255..257 'a1': *const A |
796 | 255..259 'a1.b': B | 820 | 255..259 'a1.b': B |
797 | 265..267 'a2': *mut A | 821 | 265..267 'a2': *mut A |
798 | 265..269 'a2.b': B | 822 | 265..269 'a2.b': B |
799 | "### | 823 | "#]], |
800 | ); | 824 | ); |
801 | } | 825 | } |
802 | 826 | ||
803 | #[test] | 827 | #[test] |
804 | fn infer_argument_autoderef() { | 828 | fn infer_argument_autoderef() { |
805 | assert_snapshot!( | 829 | check_infer( |
806 | infer(r#" | 830 | r#" |
807 | #[lang = "deref"] | 831 | #[lang = "deref"] |
808 | pub trait Deref { | 832 | pub trait Deref { |
809 | type Target; | 833 | type Target; |
810 | fn deref(&self) -> &Self::Target; | 834 | fn deref(&self) -> &Self::Target; |
811 | } | 835 | } |
812 | 836 | ||
813 | struct A<T>(T); | 837 | struct A<T>(T); |
814 | 838 | ||
815 | impl<T> A<T> { | 839 | impl<T> A<T> { |
816 | fn foo(&self) -> &T { | 840 | fn foo(&self) -> &T { |
817 | &self.0 | 841 | &self.0 |
818 | } | 842 | } |
819 | } | 843 | } |
820 | 844 | ||
821 | struct B<T>(T); | 845 | struct B<T>(T); |
822 | 846 | ||
823 | impl<T> Deref for B<T> { | 847 | impl<T> Deref for B<T> { |
824 | type Target = T; | 848 | type Target = T; |
825 | fn deref(&self) -> &Self::Target { | 849 | fn deref(&self) -> &Self::Target { |
826 | &self.0 | 850 | &self.0 |
827 | } | 851 | } |
828 | } | 852 | } |
829 | 853 | ||
830 | fn test() { | 854 | fn test() { |
831 | let t = A::foo(&&B(B(A(42)))); | 855 | let t = A::foo(&&B(B(A(42)))); |
832 | } | 856 | } |
833 | "#), | 857 | "#, |
834 | @r###" | 858 | expect![[r#" |
835 | 67..71 'self': &Self | 859 | 67..71 'self': &Self |
836 | 138..142 'self': &A<T> | 860 | 138..142 'self': &A<T> |
837 | 150..173 '{ ... }': &T | 861 | 150..173 '{ ... }': &T |
838 | 160..167 '&self.0': &T | 862 | 160..167 '&self.0': &T |
839 | 161..165 'self': &A<T> | 863 | 161..165 'self': &A<T> |
840 | 161..167 'self.0': T | 864 | 161..167 'self.0': T |
841 | 254..258 'self': &B<T> | 865 | 254..258 'self': &B<T> |
842 | 277..300 '{ ... }': &T | 866 | 277..300 '{ ... }': &T |
843 | 287..294 '&self.0': &T | 867 | 287..294 '&self.0': &T |
844 | 288..292 'self': &B<T> | 868 | 288..292 'self': &B<T> |
845 | 288..294 'self.0': T | 869 | 288..294 'self.0': T |
846 | 314..352 '{ ...))); }': () | 870 | 314..352 '{ ...))); }': () |
847 | 324..325 't': &i32 | 871 | 324..325 't': &i32 |
848 | 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32 | 872 | 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32 |
849 | 328..349 'A::foo...42))))': &i32 | 873 | 328..349 'A::foo...42))))': &i32 |
850 | 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>> | 874 | 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>> |
851 | 336..348 '&B(B(A(42)))': &B<B<A<i32>>> | 875 | 336..348 '&B(B(A(42)))': &B<B<A<i32>>> |
852 | 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> | 876 | 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> |
853 | 337..348 'B(B(A(42)))': B<B<A<i32>>> | 877 | 337..348 'B(B(A(42)))': B<B<A<i32>>> |
854 | 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>> | 878 | 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>> |
855 | 339..347 'B(A(42))': B<A<i32>> | 879 | 339..347 'B(A(42))': B<A<i32>> |
856 | 341..342 'A': A<i32>(i32) -> A<i32> | 880 | 341..342 'A': A<i32>(i32) -> A<i32> |
857 | 341..346 'A(42)': A<i32> | 881 | 341..346 'A(42)': A<i32> |
858 | 343..345 '42': i32 | 882 | 343..345 '42': i32 |
859 | "### | 883 | "#]], |
860 | ); | 884 | ); |
861 | } | 885 | } |
862 | 886 | ||
863 | #[test] | 887 | #[test] |
864 | fn infer_method_argument_autoderef() { | 888 | fn infer_method_argument_autoderef() { |
865 | assert_snapshot!( | 889 | check_infer( |
866 | infer(r#" | 890 | r#" |
867 | #[lang = "deref"] | 891 | #[lang = "deref"] |
868 | pub trait Deref { | 892 | pub trait Deref { |
869 | type Target; | 893 | type Target; |
870 | fn deref(&self) -> &Self::Target; | 894 | fn deref(&self) -> &Self::Target; |
871 | } | 895 | } |
872 | 896 | ||
873 | struct A<T>(*mut T); | 897 | struct A<T>(*mut T); |
874 | 898 | ||
875 | impl<T> A<T> { | 899 | impl<T> A<T> { |
876 | fn foo(&self, x: &A<T>) -> &T { | 900 | fn foo(&self, x: &A<T>) -> &T { |
877 | &*x.0 | 901 | &*x.0 |
878 | } | 902 | } |
879 | } | 903 | } |
880 | 904 | ||
881 | struct B<T>(T); | 905 | struct B<T>(T); |
882 | 906 | ||
883 | impl<T> Deref for B<T> { | 907 | impl<T> Deref for B<T> { |
884 | type Target = T; | 908 | type Target = T; |
885 | fn deref(&self) -> &Self::Target { | 909 | fn deref(&self) -> &Self::Target { |
886 | &self.0 | 910 | &self.0 |
887 | } | 911 | } |
888 | } | 912 | } |
889 | 913 | ||
890 | fn test(a: A<i32>) { | 914 | fn test(a: A<i32>) { |
891 | let t = A(0 as *mut _).foo(&&B(B(a))); | 915 | let t = A(0 as *mut _).foo(&&B(B(a))); |
892 | } | 916 | } |
893 | "#), | 917 | "#, |
894 | @r###" | 918 | expect![[r#" |
895 | 67..71 'self': &Self | 919 | 67..71 'self': &Self |
896 | 143..147 'self': &A<T> | 920 | 143..147 'self': &A<T> |
897 | 149..150 'x': &A<T> | 921 | 149..150 'x': &A<T> |
898 | 165..186 '{ ... }': &T | 922 | 165..186 '{ ... }': &T |
899 | 175..180 '&*x.0': &T | 923 | 175..180 '&*x.0': &T |
900 | 176..180 '*x.0': T | 924 | 176..180 '*x.0': T |
901 | 177..178 'x': &A<T> | 925 | 177..178 'x': &A<T> |
902 | 177..180 'x.0': *mut T | 926 | 177..180 'x.0': *mut T |
903 | 267..271 'self': &B<T> | 927 | 267..271 'self': &B<T> |
904 | 290..313 '{ ... }': &T | 928 | 290..313 '{ ... }': &T |
905 | 300..307 '&self.0': &T | 929 | 300..307 '&self.0': &T |
906 | 301..305 'self': &B<T> | 930 | 301..305 'self': &B<T> |
907 | 301..307 'self.0': T | 931 | 301..307 'self.0': T |
908 | 325..326 'a': A<i32> | 932 | 325..326 'a': A<i32> |
909 | 336..382 '{ ...))); }': () | 933 | 336..382 '{ ...))); }': () |
910 | 346..347 't': &i32 | 934 | 346..347 't': &i32 |
911 | 350..351 'A': A<i32>(*mut i32) -> A<i32> | 935 | 350..351 'A': A<i32>(*mut i32) -> A<i32> |
912 | 350..364 'A(0 as *mut _)': A<i32> | 936 | 350..364 'A(0 as *mut _)': A<i32> |
913 | 350..379 'A(0 as...B(a)))': &i32 | 937 | 350..379 'A(0 as...B(a)))': &i32 |
914 | 352..353 '0': i32 | 938 | 352..353 '0': i32 |
915 | 352..363 '0 as *mut _': *mut i32 | 939 | 352..363 '0 as *mut _': *mut i32 |
916 | 369..378 '&&B(B(a))': &&B<B<A<i32>>> | 940 | 369..378 '&&B(B(a))': &&B<B<A<i32>>> |
917 | 370..378 '&B(B(a))': &B<B<A<i32>>> | 941 | 370..378 '&B(B(a))': &B<B<A<i32>>> |
918 | 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> | 942 | 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> |
919 | 371..378 'B(B(a))': B<B<A<i32>>> | 943 | 371..378 'B(B(a))': B<B<A<i32>>> |
920 | 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>> | 944 | 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>> |
921 | 373..377 'B(a)': B<A<i32>> | 945 | 373..377 'B(a)': B<A<i32>> |
922 | 375..376 'a': A<i32> | 946 | 375..376 'a': A<i32> |
923 | "### | 947 | "#]], |
924 | ); | 948 | ); |
925 | } | 949 | } |
926 | 950 | ||
927 | #[test] | 951 | #[test] |
928 | fn infer_in_elseif() { | 952 | fn infer_in_elseif() { |
929 | assert_snapshot!( | 953 | check_infer( |
930 | infer(r#" | 954 | r#" |
931 | struct Foo { field: i32 } | 955 | struct Foo { field: i32 } |
932 | fn main(foo: Foo) { | 956 | fn main(foo: Foo) { |
933 | if true { | 957 | if true { |
934 | 958 | ||
935 | } else if false { | 959 | } else if false { |
936 | foo.field | 960 | foo.field |
937 | } | 961 | } |
938 | } | 962 | } |
939 | "#), | 963 | "#, |
940 | @r###" | 964 | expect![[r#" |
941 | 34..37 'foo': Foo | 965 | 34..37 'foo': Foo |
942 | 44..108 '{ ... } }': () | 966 | 44..108 '{ ... } }': () |
943 | 50..106 'if tru... }': () | 967 | 50..106 'if tru... }': () |
944 | 53..57 'true': bool | 968 | 53..57 'true': bool |
945 | 58..66 '{ }': () | 969 | 58..66 '{ }': () |
946 | 72..106 'if fal... }': i32 | 970 | 72..106 'if fal... }': i32 |
947 | 75..80 'false': bool | 971 | 75..80 'false': bool |
948 | 81..106 '{ ... }': i32 | 972 | 81..106 '{ ... }': i32 |
949 | 91..94 'foo': Foo | 973 | 91..94 'foo': Foo |
950 | 91..100 'foo.field': i32 | 974 | 91..100 'foo.field': i32 |
951 | "### | 975 | "#]], |
952 | ) | 976 | ) |
953 | } | 977 | } |
954 | 978 | ||
955 | #[test] | 979 | #[test] |
956 | fn infer_if_match_with_return() { | 980 | fn infer_if_match_with_return() { |
957 | assert_snapshot!( | 981 | check_infer( |
958 | infer(r#" | 982 | r#" |
959 | fn foo() { | 983 | fn foo() { |
960 | let _x1 = if true { | 984 | let _x1 = if true { |
961 | 1 | 985 | 1 |
962 | } else { | 986 | } else { |
963 | return; | 987 | return; |
964 | }; | 988 | }; |
965 | let _x2 = if true { | 989 | let _x2 = if true { |
966 | 2 | 990 | 2 |
967 | } else { | 991 | } else { |
968 | return | 992 | return |
969 | }; | 993 | }; |
970 | let _x3 = match true { | 994 | let _x3 = match true { |
971 | true => 3, | 995 | true => 3, |
972 | _ => { | 996 | _ => { |
973 | return; | 997 | return; |
974 | } | 998 | } |
975 | }; | 999 | }; |
976 | let _x4 = match true { | 1000 | let _x4 = match true { |
977 | true => 4, | 1001 | true => 4, |
978 | _ => return | 1002 | _ => return |
979 | }; | 1003 | }; |
980 | }"#), | 1004 | }"#, |
981 | @r###" | 1005 | expect![[r#" |
982 | 9..322 '{ ... }; }': () | 1006 | 9..322 '{ ... }; }': () |
983 | 19..22 '_x1': i32 | 1007 | 19..22 '_x1': i32 |
984 | 25..79 'if tru... }': i32 | 1008 | 25..79 'if tru... }': i32 |
985 | 28..32 'true': bool | 1009 | 28..32 'true': bool |
986 | 33..50 '{ ... }': i32 | 1010 | 33..50 '{ ... }': i32 |
987 | 43..44 '1': i32 | 1011 | 43..44 '1': i32 |
988 | 56..79 '{ ... }': i32 | 1012 | 56..79 '{ ... }': i32 |
989 | 66..72 'return': ! | 1013 | 66..72 'return': ! |
990 | 89..92 '_x2': i32 | 1014 | 89..92 '_x2': i32 |
991 | 95..148 'if tru... }': i32 | 1015 | 95..148 'if tru... }': i32 |
992 | 98..102 'true': bool | 1016 | 98..102 'true': bool |
993 | 103..120 '{ ... }': i32 | 1017 | 103..120 '{ ... }': i32 |
994 | 113..114 '2': i32 | 1018 | 113..114 '2': i32 |
995 | 126..148 '{ ... }': ! | 1019 | 126..148 '{ ... }': ! |
996 | 136..142 'return': ! | 1020 | 136..142 'return': ! |
997 | 158..161 '_x3': i32 | 1021 | 158..161 '_x3': i32 |
998 | 164..246 'match ... }': i32 | 1022 | 164..246 'match ... }': i32 |
999 | 170..174 'true': bool | 1023 | 170..174 'true': bool |
1000 | 185..189 'true': bool | 1024 | 185..189 'true': bool |
1001 | 185..189 'true': bool | 1025 | 185..189 'true': bool |
1002 | 193..194 '3': i32 | 1026 | 193..194 '3': i32 |
1003 | 204..205 '_': bool | 1027 | 204..205 '_': bool |
1004 | 209..240 '{ ... }': i32 | 1028 | 209..240 '{ ... }': i32 |
1005 | 223..229 'return': ! | 1029 | 223..229 'return': ! |
1006 | 256..259 '_x4': i32 | 1030 | 256..259 '_x4': i32 |
1007 | 262..319 'match ... }': i32 | 1031 | 262..319 'match ... }': i32 |
1008 | 268..272 'true': bool | 1032 | 268..272 'true': bool |
1009 | 283..287 'true': bool | 1033 | 283..287 'true': bool |
1010 | 283..287 'true': bool | 1034 | 283..287 'true': bool |
1011 | 291..292 '4': i32 | 1035 | 291..292 '4': i32 |
1012 | 302..303 '_': bool | 1036 | 302..303 '_': bool |
1013 | 307..313 'return': ! | 1037 | 307..313 'return': ! |
1014 | "### | 1038 | "#]], |
1015 | ) | 1039 | ) |
1016 | } | 1040 | } |
1017 | 1041 | ||
1018 | #[test] | 1042 | #[test] |
1019 | fn infer_inherent_method() { | 1043 | fn infer_inherent_method() { |
1020 | assert_snapshot!( | 1044 | check_infer( |
1021 | infer(r#" | 1045 | r#" |
1022 | struct A; | 1046 | struct A; |
1023 | 1047 | ||
1024 | impl A { | 1048 | impl A { |
1025 | fn foo(self, x: u32) -> i32 {} | 1049 | fn foo(self, x: u32) -> i32 {} |
1026 | } | 1050 | } |
1027 | 1051 | ||
1028 | mod b { | 1052 | mod b { |
1029 | impl super::A { | 1053 | impl super::A { |
1030 | fn bar(&self, x: u64) -> i64 {} | 1054 | fn bar(&self, x: u64) -> i64 {} |
1031 | } | 1055 | } |
1032 | } | 1056 | } |
1033 | 1057 | ||
1034 | fn test(a: A) { | 1058 | fn test(a: A) { |
1035 | a.foo(1); | 1059 | a.foo(1); |
1036 | (&a).bar(1); | 1060 | (&a).bar(1); |
1037 | a.bar(1); | 1061 | a.bar(1); |
1038 | } | 1062 | } |
1039 | "#), | 1063 | "#, |
1040 | @r###" | 1064 | expect![[r#" |
1041 | 31..35 'self': A | 1065 | 31..35 'self': A |
1042 | 37..38 'x': u32 | 1066 | 37..38 'x': u32 |
1043 | 52..54 '{}': () | 1067 | 52..54 '{}': () |
1044 | 102..106 'self': &A | 1068 | 102..106 'self': &A |
1045 | 108..109 'x': u64 | 1069 | 108..109 'x': u64 |
1046 | 123..125 '{}': () | 1070 | 123..125 '{}': () |
1047 | 143..144 'a': A | 1071 | 143..144 'a': A |
1048 | 149..197 '{ ...(1); }': () | 1072 | 149..197 '{ ...(1); }': () |
1049 | 155..156 'a': A | 1073 | 155..156 'a': A |
1050 | 155..163 'a.foo(1)': i32 | 1074 | 155..163 'a.foo(1)': i32 |
1051 | 161..162 '1': u32 | 1075 | 161..162 '1': u32 |
1052 | 169..180 '(&a).bar(1)': i64 | 1076 | 169..180 '(&a).bar(1)': i64 |
1053 | 170..172 '&a': &A | 1077 | 170..172 '&a': &A |
1054 | 171..172 'a': A | 1078 | 171..172 'a': A |
1055 | 178..179 '1': u64 | 1079 | 178..179 '1': u64 |
1056 | 186..187 'a': A | 1080 | 186..187 'a': A |
1057 | 186..194 'a.bar(1)': i64 | 1081 | 186..194 'a.bar(1)': i64 |
1058 | 192..193 '1': u64 | 1082 | 192..193 '1': u64 |
1059 | "### | 1083 | "#]], |
1060 | ); | 1084 | ); |
1061 | } | 1085 | } |
1062 | 1086 | ||
1063 | #[test] | 1087 | #[test] |
1064 | fn infer_inherent_method_str() { | 1088 | fn infer_inherent_method_str() { |
1065 | assert_snapshot!( | 1089 | check_infer( |
1066 | infer(r#" | 1090 | r#" |
1067 | #[lang = "str"] | 1091 | #[lang = "str"] |
1068 | impl str { | 1092 | impl str { |
1069 | fn foo(&self) -> i32 {} | 1093 | fn foo(&self) -> i32 {} |
1070 | } | 1094 | } |
1071 | 1095 | ||
1072 | fn test() { | 1096 | fn test() { |
1073 | "foo".foo(); | 1097 | "foo".foo(); |
1074 | } | 1098 | } |
1075 | "#), | 1099 | "#, |
1076 | @r###" | 1100 | expect![[r#" |
1077 | 39..43 'self': &str | 1101 | 39..43 'self': &str |
1078 | 52..54 '{}': () | 1102 | 52..54 '{}': () |
1079 | 68..88 '{ ...o(); }': () | 1103 | 68..88 '{ ...o(); }': () |
1080 | 74..79 '"foo"': &str | 1104 | 74..79 '"foo"': &str |
1081 | 74..85 '"foo".foo()': i32 | 1105 | 74..85 '"foo".foo()': i32 |
1082 | "### | 1106 | "#]], |
1083 | ); | 1107 | ); |
1084 | } | 1108 | } |
1085 | 1109 | ||
1086 | #[test] | 1110 | #[test] |
1087 | fn infer_tuple() { | 1111 | fn infer_tuple() { |
1088 | assert_snapshot!( | 1112 | check_infer( |
1089 | infer(r#" | 1113 | r#" |
1090 | fn test(x: &str, y: isize) { | 1114 | fn test(x: &str, y: isize) { |
1091 | let a: (u32, &str) = (1, "a"); | 1115 | let a: (u32, &str) = (1, "a"); |
1092 | let b = (a, x); | 1116 | let b = (a, x); |
1093 | let c = (y, x); | 1117 | let c = (y, x); |
1094 | let d = (c, x); | 1118 | let d = (c, x); |
1095 | let e = (1, "e"); | 1119 | let e = (1, "e"); |
1096 | let f = (e, "d"); | 1120 | let f = (e, "d"); |
1097 | } | 1121 | } |
1098 | "#), | 1122 | "#, |
1099 | @r###" | 1123 | expect![[r#" |
1100 | 8..9 'x': &str | 1124 | 8..9 'x': &str |
1101 | 17..18 'y': isize | 1125 | 17..18 'y': isize |
1102 | 27..169 '{ ...d"); }': () | 1126 | 27..169 '{ ...d"); }': () |
1103 | 37..38 'a': (u32, &str) | 1127 | 37..38 'a': (u32, &str) |
1104 | 54..62 '(1, "a")': (u32, &str) | 1128 | 54..62 '(1, "a")': (u32, &str) |
1105 | 55..56 '1': u32 | 1129 | 55..56 '1': u32 |
1106 | 58..61 '"a"': &str | 1130 | 58..61 '"a"': &str |
1107 | 72..73 'b': ((u32, &str), &str) | 1131 | 72..73 'b': ((u32, &str), &str) |
1108 | 76..82 '(a, x)': ((u32, &str), &str) | 1132 | 76..82 '(a, x)': ((u32, &str), &str) |
1109 | 77..78 'a': (u32, &str) | 1133 | 77..78 'a': (u32, &str) |
1110 | 80..81 'x': &str | 1134 | 80..81 'x': &str |
1111 | 92..93 'c': (isize, &str) | 1135 | 92..93 'c': (isize, &str) |
1112 | 96..102 '(y, x)': (isize, &str) | 1136 | 96..102 '(y, x)': (isize, &str) |
1113 | 97..98 'y': isize | 1137 | 97..98 'y': isize |
1114 | 100..101 'x': &str | 1138 | 100..101 'x': &str |
1115 | 112..113 'd': ((isize, &str), &str) | 1139 | 112..113 'd': ((isize, &str), &str) |
1116 | 116..122 '(c, x)': ((isize, &str), &str) | 1140 | 116..122 '(c, x)': ((isize, &str), &str) |
1117 | 117..118 'c': (isize, &str) | 1141 | 117..118 'c': (isize, &str) |
1118 | 120..121 'x': &str | 1142 | 120..121 'x': &str |
1119 | 132..133 'e': (i32, &str) | 1143 | 132..133 'e': (i32, &str) |
1120 | 136..144 '(1, "e")': (i32, &str) | 1144 | 136..144 '(1, "e")': (i32, &str) |
1121 | 137..138 '1': i32 | 1145 | 137..138 '1': i32 |
1122 | 140..143 '"e"': &str | 1146 | 140..143 '"e"': &str |
1123 | 154..155 'f': ((i32, &str), &str) | 1147 | 154..155 'f': ((i32, &str), &str) |
1124 | 158..166 '(e, "d")': ((i32, &str), &str) | 1148 | 158..166 '(e, "d")': ((i32, &str), &str) |
1125 | 159..160 'e': (i32, &str) | 1149 | 159..160 'e': (i32, &str) |
1126 | 162..165 '"d"': &str | 1150 | 162..165 '"d"': &str |
1127 | "### | 1151 | "#]], |
1128 | ); | 1152 | ); |
1129 | } | 1153 | } |
1130 | 1154 | ||
1131 | #[test] | 1155 | #[test] |
1132 | fn infer_array() { | 1156 | fn infer_array() { |
1133 | assert_snapshot!( | 1157 | check_infer( |
1134 | infer(r#" | 1158 | r#" |
1135 | fn test(x: &str, y: isize) { | 1159 | fn test(x: &str, y: isize) { |
1136 | let a = [x]; | 1160 | let a = [x]; |
1137 | let b = [a, a]; | 1161 | let b = [a, a]; |
1138 | let c = [b, b]; | 1162 | let c = [b, b]; |
1139 | 1163 | ||
1140 | let d = [y, 1, 2, 3]; | 1164 | let d = [y, 1, 2, 3]; |
1141 | let d = [1, y, 2, 3]; | 1165 | let d = [1, y, 2, 3]; |
1142 | let e = [y]; | 1166 | let e = [y]; |
1143 | let f = [d, d]; | 1167 | let f = [d, d]; |
1144 | let g = [e, e]; | 1168 | let g = [e, e]; |
1145 | 1169 | ||
1146 | let h = [1, 2]; | 1170 | let h = [1, 2]; |
1147 | let i = ["a", "b"]; | 1171 | let i = ["a", "b"]; |
1148 | 1172 | ||
1149 | let b = [a, ["b"]]; | 1173 | let b = [a, ["b"]]; |
1150 | let x: [u8; 0] = []; | 1174 | let x: [u8; 0] = []; |
1151 | } | 1175 | } |
1152 | "#), | 1176 | "#, |
1153 | @r###" | 1177 | expect![[r#" |
1154 | 8..9 'x': &str | 1178 | 8..9 'x': &str |
1155 | 17..18 'y': isize | 1179 | 17..18 'y': isize |
1156 | 27..292 '{ ... []; }': () | 1180 | 27..292 '{ ... []; }': () |
1157 | 37..38 'a': [&str; _] | 1181 | 37..38 'a': [&str; _] |
1158 | 41..44 '[x]': [&str; _] | 1182 | 41..44 '[x]': [&str; _] |
1159 | 42..43 'x': &str | 1183 | 42..43 'x': &str |
1160 | 54..55 'b': [[&str; _]; _] | 1184 | 54..55 'b': [[&str; _]; _] |
1161 | 58..64 '[a, a]': [[&str; _]; _] | 1185 | 58..64 '[a, a]': [[&str; _]; _] |
1162 | 59..60 'a': [&str; _] | 1186 | 59..60 'a': [&str; _] |
1163 | 62..63 'a': [&str; _] | 1187 | 62..63 'a': [&str; _] |
1164 | 74..75 'c': [[[&str; _]; _]; _] | 1188 | 74..75 'c': [[[&str; _]; _]; _] |
1165 | 78..84 '[b, b]': [[[&str; _]; _]; _] | 1189 | 78..84 '[b, b]': [[[&str; _]; _]; _] |
1166 | 79..80 'b': [[&str; _]; _] | 1190 | 79..80 'b': [[&str; _]; _] |
1167 | 82..83 'b': [[&str; _]; _] | 1191 | 82..83 'b': [[&str; _]; _] |
1168 | 95..96 'd': [isize; _] | 1192 | 95..96 'd': [isize; _] |
1169 | 99..111 '[y, 1, 2, 3]': [isize; _] | 1193 | 99..111 '[y, 1, 2, 3]': [isize; _] |
1170 | 100..101 'y': isize | 1194 | 100..101 'y': isize |
1171 | 103..104 '1': isize | 1195 | 103..104 '1': isize |
1172 | 106..107 '2': isize | 1196 | 106..107 '2': isize |
1173 | 109..110 '3': isize | 1197 | 109..110 '3': isize |
1174 | 121..122 'd': [isize; _] | 1198 | 121..122 'd': [isize; _] |
1175 | 125..137 '[1, y, 2, 3]': [isize; _] | 1199 | 125..137 '[1, y, 2, 3]': [isize; _] |
1176 | 126..127 '1': isize | 1200 | 126..127 '1': isize |
1177 | 129..130 'y': isize | 1201 | 129..130 'y': isize |
1178 | 132..133 '2': isize | 1202 | 132..133 '2': isize |
1179 | 135..136 '3': isize | 1203 | 135..136 '3': isize |
1180 | 147..148 'e': [isize; _] | 1204 | 147..148 'e': [isize; _] |
1181 | 151..154 '[y]': [isize; _] | 1205 | 151..154 '[y]': [isize; _] |
1182 | 152..153 'y': isize | 1206 | 152..153 'y': isize |
1183 | 164..165 'f': [[isize; _]; _] | 1207 | 164..165 'f': [[isize; _]; _] |
1184 | 168..174 '[d, d]': [[isize; _]; _] | 1208 | 168..174 '[d, d]': [[isize; _]; _] |
1185 | 169..170 'd': [isize; _] | 1209 | 169..170 'd': [isize; _] |
1186 | 172..173 'd': [isize; _] | 1210 | 172..173 'd': [isize; _] |
1187 | 184..185 'g': [[isize; _]; _] | 1211 | 184..185 'g': [[isize; _]; _] |
1188 | 188..194 '[e, e]': [[isize; _]; _] | 1212 | 188..194 '[e, e]': [[isize; _]; _] |
1189 | 189..190 'e': [isize; _] | 1213 | 189..190 'e': [isize; _] |
1190 | 192..193 'e': [isize; _] | 1214 | 192..193 'e': [isize; _] |
1191 | 205..206 'h': [i32; _] | 1215 | 205..206 'h': [i32; _] |
1192 | 209..215 '[1, 2]': [i32; _] | 1216 | 209..215 '[1, 2]': [i32; _] |
1193 | 210..211 '1': i32 | 1217 | 210..211 '1': i32 |
1194 | 213..214 '2': i32 | 1218 | 213..214 '2': i32 |
1195 | 225..226 'i': [&str; _] | 1219 | 225..226 'i': [&str; _] |
1196 | 229..239 '["a", "b"]': [&str; _] | 1220 | 229..239 '["a", "b"]': [&str; _] |
1197 | 230..233 '"a"': &str | 1221 | 230..233 '"a"': &str |
1198 | 235..238 '"b"': &str | 1222 | 235..238 '"b"': &str |
1199 | 250..251 'b': [[&str; _]; _] | 1223 | 250..251 'b': [[&str; _]; _] |
1200 | 254..264 '[a, ["b"]]': [[&str; _]; _] | 1224 | 254..264 '[a, ["b"]]': [[&str; _]; _] |
1201 | 255..256 'a': [&str; _] | 1225 | 255..256 'a': [&str; _] |
1202 | 258..263 '["b"]': [&str; _] | 1226 | 258..263 '["b"]': [&str; _] |
1203 | 259..262 '"b"': &str | 1227 | 259..262 '"b"': &str |
1204 | 274..275 'x': [u8; _] | 1228 | 274..275 'x': [u8; _] |
1205 | 287..289 '[]': [u8; _] | 1229 | 287..289 '[]': [u8; _] |
1206 | "### | 1230 | "#]], |
1207 | ); | 1231 | ); |
1208 | } | 1232 | } |
1209 | 1233 | ||
1210 | #[test] | 1234 | #[test] |
1211 | fn infer_struct_generics() { | 1235 | fn infer_struct_generics() { |
1212 | assert_snapshot!( | 1236 | check_infer( |
1213 | infer(r#" | 1237 | r#" |
1214 | struct A<T> { | 1238 | struct A<T> { |
1215 | x: T, | 1239 | x: T, |
1216 | } | 1240 | } |
1217 | 1241 | ||
1218 | fn test(a1: A<u32>, i: i32) { | 1242 | fn test(a1: A<u32>, i: i32) { |
1219 | a1.x; | 1243 | a1.x; |
1220 | let a2 = A { x: i }; | 1244 | let a2 = A { x: i }; |
1221 | a2.x; | 1245 | a2.x; |
1222 | let a3 = A::<i128> { x: 1 }; | 1246 | let a3 = A::<i128> { x: 1 }; |
1223 | a3.x; | 1247 | a3.x; |
1224 | } | 1248 | } |
1225 | "#), | 1249 | "#, |
1226 | @r###" | 1250 | expect![[r#" |
1227 | 35..37 'a1': A<u32> | 1251 | 35..37 'a1': A<u32> |
1228 | 47..48 'i': i32 | 1252 | 47..48 'i': i32 |
1229 | 55..146 '{ ...3.x; }': () | 1253 | 55..146 '{ ...3.x; }': () |
1230 | 61..63 'a1': A<u32> | 1254 | 61..63 'a1': A<u32> |
1231 | 61..65 'a1.x': u32 | 1255 | 61..65 'a1.x': u32 |
1232 | 75..77 'a2': A<i32> | 1256 | 75..77 'a2': A<i32> |
1233 | 80..90 'A { x: i }': A<i32> | 1257 | 80..90 'A { x: i }': A<i32> |
1234 | 87..88 'i': i32 | 1258 | 87..88 'i': i32 |
1235 | 96..98 'a2': A<i32> | 1259 | 96..98 'a2': A<i32> |
1236 | 96..100 'a2.x': i32 | 1260 | 96..100 'a2.x': i32 |
1237 | 110..112 'a3': A<i128> | 1261 | 110..112 'a3': A<i128> |
1238 | 115..133 'A::<i1...x: 1 }': A<i128> | 1262 | 115..133 'A::<i1...x: 1 }': A<i128> |
1239 | 130..131 '1': i128 | 1263 | 130..131 '1': i128 |
1240 | 139..141 'a3': A<i128> | 1264 | 139..141 'a3': A<i128> |
1241 | 139..143 'a3.x': i128 | 1265 | 139..143 'a3.x': i128 |
1242 | "### | 1266 | "#]], |
1243 | ); | 1267 | ); |
1244 | } | 1268 | } |
1245 | 1269 | ||
1246 | #[test] | 1270 | #[test] |
1247 | fn infer_tuple_struct_generics() { | 1271 | fn infer_tuple_struct_generics() { |
1248 | assert_snapshot!( | 1272 | check_infer( |
1249 | infer(r#" | 1273 | r#" |
1250 | struct A<T>(T); | 1274 | struct A<T>(T); |
1251 | enum Option<T> { Some(T), None } | 1275 | enum Option<T> { Some(T), None } |
1252 | use Option::*; | 1276 | use Option::*; |
1253 | 1277 | ||
1254 | fn test() { | 1278 | fn test() { |
1255 | A(42); | 1279 | A(42); |
1256 | A(42u128); | 1280 | A(42u128); |
1257 | Some("x"); | 1281 | Some("x"); |
1258 | Option::Some("x"); | 1282 | Option::Some("x"); |
1259 | None; | 1283 | None; |
1260 | let x: Option<i64> = None; | 1284 | let x: Option<i64> = None; |
1261 | } | 1285 | } |
1262 | "#), | 1286 | "#, |
1263 | @r###" | 1287 | expect![[r#" |
1264 | 75..183 '{ ...one; }': () | 1288 | 75..183 '{ ...one; }': () |
1265 | 81..82 'A': A<i32>(i32) -> A<i32> | 1289 | 81..82 'A': A<i32>(i32) -> A<i32> |
1266 | 81..86 'A(42)': A<i32> | 1290 | 81..86 'A(42)': A<i32> |
1267 | 83..85 '42': i32 | 1291 | 83..85 '42': i32 |
1268 | 92..93 'A': A<u128>(u128) -> A<u128> | 1292 | 92..93 'A': A<u128>(u128) -> A<u128> |
1269 | 92..101 'A(42u128)': A<u128> | 1293 | 92..101 'A(42u128)': A<u128> |
1270 | 94..100 '42u128': u128 | 1294 | 94..100 '42u128': u128 |
1271 | 107..111 'Some': Some<&str>(&str) -> Option<&str> | 1295 | 107..111 'Some': Some<&str>(&str) -> Option<&str> |
1272 | 107..116 'Some("x")': Option<&str> | 1296 | 107..116 'Some("x")': Option<&str> |
1273 | 112..115 '"x"': &str | 1297 | 112..115 '"x"': &str |
1274 | 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> | 1298 | 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> |
1275 | 122..139 'Option...e("x")': Option<&str> | 1299 | 122..139 'Option...e("x")': Option<&str> |
1276 | 135..138 '"x"': &str | 1300 | 135..138 '"x"': &str |
1277 | 145..149 'None': Option<{unknown}> | 1301 | 145..149 'None': Option<{unknown}> |
1278 | 159..160 'x': Option<i64> | 1302 | 159..160 'x': Option<i64> |
1279 | 176..180 'None': Option<i64> | 1303 | 176..180 'None': Option<i64> |
1280 | "### | 1304 | "#]], |
1281 | ); | 1305 | ); |
1282 | } | 1306 | } |
1283 | 1307 | ||
1284 | #[test] | 1308 | #[test] |
1285 | fn infer_function_generics() { | 1309 | fn infer_function_generics() { |
1286 | assert_snapshot!( | 1310 | check_infer( |
1287 | infer(r#" | 1311 | r#" |
1288 | fn id<T>(t: T) -> T { t } | 1312 | fn id<T>(t: T) -> T { t } |
1289 | 1313 | ||
1290 | fn test() { | 1314 | fn test() { |
1291 | id(1u32); | 1315 | id(1u32); |
1292 | id::<i128>(1); | 1316 | id::<i128>(1); |
1293 | let x: u64 = id(1); | 1317 | let x: u64 = id(1); |
1294 | } | 1318 | } |
1295 | "#), | 1319 | "#, |
1296 | @r###" | 1320 | expect![[r#" |
1297 | 9..10 't': T | 1321 | 9..10 't': T |
1298 | 20..25 '{ t }': T | 1322 | 20..25 '{ t }': T |
1299 | 22..23 't': T | 1323 | 22..23 't': T |
1300 | 37..97 '{ ...(1); }': () | 1324 | 37..97 '{ ...(1); }': () |
1301 | 43..45 'id': fn id<u32>(u32) -> u32 | 1325 | 43..45 'id': fn id<u32>(u32) -> u32 |
1302 | 43..51 'id(1u32)': u32 | 1326 | 43..51 'id(1u32)': u32 |
1303 | 46..50 '1u32': u32 | 1327 | 46..50 '1u32': u32 |
1304 | 57..67 'id::<i128>': fn id<i128>(i128) -> i128 | 1328 | 57..67 'id::<i128>': fn id<i128>(i128) -> i128 |
1305 | 57..70 'id::<i128>(1)': i128 | 1329 | 57..70 'id::<i128>(1)': i128 |
1306 | 68..69 '1': i128 | 1330 | 68..69 '1': i128 |
1307 | 80..81 'x': u64 | 1331 | 80..81 'x': u64 |
1308 | 89..91 'id': fn id<u64>(u64) -> u64 | 1332 | 89..91 'id': fn id<u64>(u64) -> u64 |
1309 | 89..94 'id(1)': u64 | 1333 | 89..94 'id(1)': u64 |
1310 | 92..93 '1': u64 | 1334 | 92..93 '1': u64 |
1311 | "### | 1335 | "#]], |
1312 | ); | 1336 | ); |
1313 | } | 1337 | } |
1314 | 1338 | ||
1315 | #[test] | 1339 | #[test] |
1316 | fn infer_impl_generics_basic() { | 1340 | fn infer_impl_generics_basic() { |
1317 | assert_snapshot!( | 1341 | check_infer( |
1318 | infer(r#" | 1342 | r#" |
1319 | struct A<T1, T2> { | 1343 | struct A<T1, T2> { |
1320 | x: T1, | 1344 | x: T1, |
1321 | y: T2, | 1345 | y: T2, |
1322 | } | 1346 | } |
1323 | impl<Y, X> A<X, Y> { | 1347 | impl<Y, X> A<X, Y> { |
1324 | fn x(self) -> X { | 1348 | fn x(self) -> X { |
1325 | self.x | 1349 | self.x |
1326 | } | 1350 | } |
1327 | fn y(self) -> Y { | 1351 | fn y(self) -> Y { |
1328 | self.y | 1352 | self.y |
1329 | } | 1353 | } |
1330 | fn z<T>(self, t: T) -> (X, Y, T) { | 1354 | fn z<T>(self, t: T) -> (X, Y, T) { |
1331 | (self.x, self.y, t) | 1355 | (self.x, self.y, t) |
1332 | } | 1356 | } |
1333 | } | 1357 | } |
1334 | 1358 | ||
1335 | fn test() -> i128 { | 1359 | fn test() -> i128 { |
1336 | let a = A { x: 1u64, y: 1i64 }; | 1360 | let a = A { x: 1u64, y: 1i64 }; |
1337 | a.x(); | 1361 | a.x(); |
1338 | a.y(); | 1362 | a.y(); |
1339 | a.z(1i128); | 1363 | a.z(1i128); |
1340 | a.z::<u128>(1); | 1364 | a.z::<u128>(1); |
1341 | } | 1365 | } |
1342 | "#), | 1366 | "#, |
1343 | @r###" | 1367 | expect![[r#" |
1344 | 73..77 'self': A<X, Y> | 1368 | 73..77 'self': A<X, Y> |
1345 | 84..106 '{ ... }': X | 1369 | 84..106 '{ ... }': X |
1346 | 94..98 'self': A<X, Y> | 1370 | 94..98 'self': A<X, Y> |
1347 | 94..100 'self.x': X | 1371 | 94..100 'self.x': X |
1348 | 116..120 'self': A<X, Y> | 1372 | 116..120 'self': A<X, Y> |
1349 | 127..149 '{ ... }': Y | 1373 | 127..149 '{ ... }': Y |
1350 | 137..141 'self': A<X, Y> | 1374 | 137..141 'self': A<X, Y> |
1351 | 137..143 'self.y': Y | 1375 | 137..143 'self.y': Y |
1352 | 162..166 'self': A<X, Y> | 1376 | 162..166 'self': A<X, Y> |
1353 | 168..169 't': T | 1377 | 168..169 't': T |
1354 | 187..222 '{ ... }': (X, Y, T) | 1378 | 187..222 '{ ... }': (X, Y, T) |
1355 | 197..216 '(self.....y, t)': (X, Y, T) | 1379 | 197..216 '(self.....y, t)': (X, Y, T) |
1356 | 198..202 'self': A<X, Y> | 1380 | 198..202 'self': A<X, Y> |
1357 | 198..204 'self.x': X | 1381 | 198..204 'self.x': X |
1358 | 206..210 'self': A<X, Y> | 1382 | 206..210 'self': A<X, Y> |
1359 | 206..212 'self.y': Y | 1383 | 206..212 'self.y': Y |
1360 | 214..215 't': T | 1384 | 214..215 't': T |
1361 | 244..341 '{ ...(1); }': () | 1385 | 244..341 '{ ...(1); }': () |
1362 | 254..255 'a': A<u64, i64> | 1386 | 254..255 'a': A<u64, i64> |
1363 | 258..280 'A { x:...1i64 }': A<u64, i64> | 1387 | 258..280 'A { x:...1i64 }': A<u64, i64> |
1364 | 265..269 '1u64': u64 | 1388 | 265..269 '1u64': u64 |
1365 | 274..278 '1i64': i64 | 1389 | 274..278 '1i64': i64 |
1366 | 286..287 'a': A<u64, i64> | 1390 | 286..287 'a': A<u64, i64> |
1367 | 286..291 'a.x()': u64 | 1391 | 286..291 'a.x()': u64 |
1368 | 297..298 'a': A<u64, i64> | 1392 | 297..298 'a': A<u64, i64> |
1369 | 297..302 'a.y()': i64 | 1393 | 297..302 'a.y()': i64 |
1370 | 308..309 'a': A<u64, i64> | 1394 | 308..309 'a': A<u64, i64> |
1371 | 308..318 'a.z(1i128)': (u64, i64, i128) | 1395 | 308..318 'a.z(1i128)': (u64, i64, i128) |
1372 | 312..317 '1i128': i128 | 1396 | 312..317 '1i128': i128 |
1373 | 324..325 'a': A<u64, i64> | 1397 | 324..325 'a': A<u64, i64> |
1374 | 324..338 'a.z::<u128>(1)': (u64, i64, u128) | 1398 | 324..338 'a.z::<u128>(1)': (u64, i64, u128) |
1375 | 336..337 '1': u128 | 1399 | 336..337 '1': u128 |
1376 | "### | 1400 | "#]], |
1377 | ); | 1401 | ); |
1378 | } | 1402 | } |
1379 | 1403 | ||
1380 | #[test] | 1404 | #[test] |
1381 | fn infer_impl_generics_with_autoderef() { | 1405 | fn infer_impl_generics_with_autoderef() { |
1382 | assert_snapshot!( | 1406 | check_infer( |
1383 | infer(r#" | 1407 | r#" |
1384 | enum Option<T> { | 1408 | enum Option<T> { |
1385 | Some(T), | 1409 | Some(T), |
1386 | None, | 1410 | None, |
1387 | } | 1411 | } |
1388 | impl<T> Option<T> { | 1412 | impl<T> Option<T> { |
1389 | fn as_ref(&self) -> Option<&T> {} | 1413 | fn as_ref(&self) -> Option<&T> {} |
1390 | } | 1414 | } |
1391 | fn test(o: Option<u32>) { | 1415 | fn test(o: Option<u32>) { |
1392 | (&o).as_ref(); | 1416 | (&o).as_ref(); |
1393 | o.as_ref(); | 1417 | o.as_ref(); |
1394 | } | 1418 | } |
1395 | "#), | 1419 | "#, |
1396 | @r###" | 1420 | expect![[r#" |
1397 | 77..81 'self': &Option<T> | 1421 | 77..81 'self': &Option<T> |
1398 | 97..99 '{}': () | 1422 | 97..99 '{}': () |
1399 | 110..111 'o': Option<u32> | 1423 | 110..111 'o': Option<u32> |
1400 | 126..164 '{ ...f(); }': () | 1424 | 126..164 '{ ...f(); }': () |
1401 | 132..145 '(&o).as_ref()': Option<&u32> | 1425 | 132..145 '(&o).as_ref()': Option<&u32> |
1402 | 133..135 '&o': &Option<u32> | 1426 | 133..135 '&o': &Option<u32> |
1403 | 134..135 'o': Option<u32> | 1427 | 134..135 'o': Option<u32> |
1404 | 151..152 'o': Option<u32> | 1428 | 151..152 'o': Option<u32> |
1405 | 151..161 'o.as_ref()': Option<&u32> | 1429 | 151..161 'o.as_ref()': Option<&u32> |
1406 | "### | 1430 | "#]], |
1407 | ); | 1431 | ); |
1408 | } | 1432 | } |
1409 | 1433 | ||
1410 | #[test] | 1434 | #[test] |
1411 | fn infer_generic_chain() { | 1435 | fn infer_generic_chain() { |
1412 | assert_snapshot!( | 1436 | check_infer( |
1413 | infer(r#" | 1437 | r#" |
1414 | struct A<T> { | 1438 | struct A<T> { |
1415 | x: T, | 1439 | x: T, |
1416 | } | 1440 | } |
1417 | impl<T2> A<T2> { | 1441 | impl<T2> A<T2> { |
1418 | fn x(self) -> T2 { | 1442 | fn x(self) -> T2 { |
1419 | self.x | 1443 | self.x |
1420 | } | 1444 | } |
1421 | } | 1445 | } |
1422 | fn id<T>(t: T) -> T { t } | 1446 | fn id<T>(t: T) -> T { t } |
1423 | 1447 | ||
1424 | fn test() -> i128 { | 1448 | fn test() -> i128 { |
1425 | let x = 1; | 1449 | let x = 1; |
1426 | let y = id(x); | 1450 | let y = id(x); |
1427 | let a = A { x: id(y) }; | 1451 | let a = A { x: id(y) }; |
1428 | let z = id(a.x); | 1452 | let z = id(a.x); |
1429 | let b = A { x: z }; | 1453 | let b = A { x: z }; |
1430 | b.x() | 1454 | b.x() |
1431 | } | 1455 | } |
1432 | "#), | 1456 | "#, |
1433 | @r###" | 1457 | expect![[r#" |
1434 | 52..56 'self': A<T2> | 1458 | 52..56 'self': A<T2> |
1435 | 64..86 '{ ... }': T2 | 1459 | 64..86 '{ ... }': T2 |
1436 | 74..78 'self': A<T2> | 1460 | 74..78 'self': A<T2> |
1437 | 74..80 'self.x': T2 | 1461 | 74..80 'self.x': T2 |
1438 | 98..99 't': T | 1462 | 98..99 't': T |
1439 | 109..114 '{ t }': T | 1463 | 109..114 '{ t }': T |
1440 | 111..112 't': T | 1464 | 111..112 't': T |
1441 | 134..260 '{ ....x() }': i128 | 1465 | 134..254 '{ ....x() }': i128 |
1442 | 145..146 'x': i128 | 1466 | 144..145 'x': i128 |
1443 | 149..150 '1': i128 | 1467 | 148..149 '1': i128 |
1444 | 161..162 'y': i128 | 1468 | 159..160 'y': i128 |
1445 | 165..167 'id': fn id<i128>(i128) -> i128 | 1469 | 163..165 'id': fn id<i128>(i128) -> i128 |
1446 | 165..170 'id(x)': i128 | 1470 | 163..168 'id(x)': i128 |
1447 | 168..169 'x': i128 | 1471 | 166..167 'x': i128 |
1448 | 181..182 'a': A<i128> | 1472 | 178..179 'a': A<i128> |
1449 | 185..199 'A { x: id(y) }': A<i128> | 1473 | 182..196 'A { x: id(y) }': A<i128> |
1450 | 192..194 'id': fn id<i128>(i128) -> i128 | 1474 | 189..191 'id': fn id<i128>(i128) -> i128 |
1451 | 192..197 'id(y)': i128 | 1475 | 189..194 'id(y)': i128 |
1452 | 195..196 'y': i128 | 1476 | 192..193 'y': i128 |
1453 | 210..211 'z': i128 | 1477 | 206..207 'z': i128 |
1454 | 214..216 'id': fn id<i128>(i128) -> i128 | 1478 | 210..212 'id': fn id<i128>(i128) -> i128 |
1455 | 214..221 'id(a.x)': i128 | 1479 | 210..217 'id(a.x)': i128 |
1456 | 217..218 'a': A<i128> | 1480 | 213..214 'a': A<i128> |
1457 | 217..220 'a.x': i128 | 1481 | 213..216 'a.x': i128 |
1458 | 232..233 'b': A<i128> | 1482 | 227..228 'b': A<i128> |
1459 | 236..246 'A { x: z }': A<i128> | 1483 | 231..241 'A { x: z }': A<i128> |
1460 | 243..244 'z': i128 | 1484 | 238..239 'z': i128 |
1461 | 253..254 'b': A<i128> | 1485 | 247..248 'b': A<i128> |
1462 | 253..258 'b.x()': i128 | 1486 | 247..252 'b.x()': i128 |
1463 | "### | 1487 | "#]], |
1464 | ); | 1488 | ); |
1465 | } | 1489 | } |
1466 | 1490 | ||
1467 | #[test] | 1491 | #[test] |
1468 | fn infer_associated_const() { | 1492 | fn infer_associated_const() { |
1469 | assert_snapshot!( | 1493 | check_infer( |
1470 | infer(r#" | 1494 | r#" |
1471 | struct Struct; | 1495 | struct Struct; |
1472 | 1496 | ||
1473 | impl Struct { | 1497 | impl Struct { |
1474 | const FOO: u32 = 1; | 1498 | const FOO: u32 = 1; |
1475 | } | 1499 | } |
1476 | 1500 | ||
1477 | enum Enum {} | 1501 | enum Enum {} |
1478 | 1502 | ||
1479 | impl Enum { | 1503 | impl Enum { |
1480 | const BAR: u32 = 2; | 1504 | const BAR: u32 = 2; |
1481 | } | 1505 | } |
1482 | 1506 | ||
1483 | trait Trait { | 1507 | trait Trait { |
1484 | const ID: u32; | 1508 | const ID: u32; |
1485 | } | 1509 | } |
1486 | 1510 | ||
1487 | struct TraitTest; | 1511 | struct TraitTest; |
1488 | 1512 | ||
1489 | impl Trait for TraitTest { | 1513 | impl Trait for TraitTest { |
1490 | const ID: u32 = 5; | 1514 | const ID: u32 = 5; |
1491 | } | 1515 | } |
1492 | 1516 | ||
1493 | fn test() { | 1517 | fn test() { |
1494 | let x = Struct::FOO; | 1518 | let x = Struct::FOO; |
1495 | let y = Enum::BAR; | 1519 | let y = Enum::BAR; |
1496 | let z = TraitTest::ID; | 1520 | let z = TraitTest::ID; |
1497 | } | 1521 | } |
1498 | "#), | 1522 | "#, |
1499 | @r###" | 1523 | expect![[r#" |
1500 | 51..52 '1': u32 | 1524 | 51..52 '1': u32 |
1501 | 104..105 '2': u32 | 1525 | 104..105 '2': u32 |
1502 | 212..213 '5': u32 | 1526 | 212..213 '5': u32 |
1503 | 228..306 '{ ...:ID; }': () | 1527 | 228..306 '{ ...:ID; }': () |
1504 | 238..239 'x': u32 | 1528 | 238..239 'x': u32 |
1505 | 242..253 'Struct::FOO': u32 | 1529 | 242..253 'Struct::FOO': u32 |
1506 | 263..264 'y': u32 | 1530 | 263..264 'y': u32 |
1507 | 267..276 'Enum::BAR': u32 | 1531 | 267..276 'Enum::BAR': u32 |
1508 | 286..287 'z': u32 | 1532 | 286..287 'z': u32 |
1509 | 290..303 'TraitTest::ID': u32 | 1533 | 290..303 'TraitTest::ID': u32 |
1510 | "### | 1534 | "#]], |
1511 | ); | 1535 | ); |
1512 | } | 1536 | } |
1513 | 1537 | ||
1514 | #[test] | 1538 | #[test] |
1515 | fn infer_type_alias() { | 1539 | fn infer_type_alias() { |
1516 | assert_snapshot!( | 1540 | check_infer( |
1517 | infer(r#" | 1541 | r#" |
1518 | struct A<X, Y> { x: X, y: Y } | 1542 | struct A<X, Y> { x: X, y: Y } |
1519 | type Foo = A<u32, i128>; | 1543 | type Foo = A<u32, i128>; |
1520 | type Bar<T> = A<T, u128>; | 1544 | type Bar<T> = A<T, u128>; |
1521 | type Baz<U, V> = A<V, U>; | 1545 | type Baz<U, V> = A<V, U>; |
1522 | fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) { | 1546 | fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) { |
1523 | x.x; | 1547 | x.x; |
1524 | x.y; | 1548 | x.y; |
1525 | y.x; | 1549 | y.x; |
1526 | y.y; | 1550 | y.y; |
1527 | z.x; | 1551 | z.x; |
1528 | z.y; | 1552 | z.y; |
1529 | } | 1553 | } |
1530 | "#), | 1554 | "#, |
1531 | @r###" | 1555 | expect![[r#" |
1532 | 115..116 'x': A<u32, i128> | 1556 | 115..116 'x': A<u32, i128> |
1533 | 123..124 'y': A<&str, u128> | 1557 | 123..124 'y': A<&str, u128> |
1534 | 137..138 'z': A<u8, i8> | 1558 | 137..138 'z': A<u8, i8> |
1535 | 153..210 '{ ...z.y; }': () | 1559 | 153..210 '{ ...z.y; }': () |
1536 | 159..160 'x': A<u32, i128> | 1560 | 159..160 'x': A<u32, i128> |
1537 | 159..162 'x.x': u32 | 1561 | 159..162 'x.x': u32 |
1538 | 168..169 'x': A<u32, i128> | 1562 | 168..169 'x': A<u32, i128> |
1539 | 168..171 'x.y': i128 | 1563 | 168..171 'x.y': i128 |
1540 | 177..178 'y': A<&str, u128> | 1564 | 177..178 'y': A<&str, u128> |
1541 | 177..180 'y.x': &str | 1565 | 177..180 'y.x': &str |
1542 | 186..187 'y': A<&str, u128> | 1566 | 186..187 'y': A<&str, u128> |
1543 | 186..189 'y.y': u128 | 1567 | 186..189 'y.y': u128 |
1544 | 195..196 'z': A<u8, i8> | 1568 | 195..196 'z': A<u8, i8> |
1545 | 195..198 'z.x': u8 | 1569 | 195..198 'z.x': u8 |
1546 | 204..205 'z': A<u8, i8> | 1570 | 204..205 'z': A<u8, i8> |
1547 | 204..207 'z.y': i8 | 1571 | 204..207 'z.y': i8 |
1548 | "### | 1572 | "#]], |
1549 | ) | 1573 | ) |
1550 | } | 1574 | } |
1551 | 1575 | ||
1552 | #[test] | 1576 | #[test] |
1553 | fn recursive_type_alias() { | 1577 | fn recursive_type_alias() { |
1554 | assert_snapshot!( | 1578 | check_infer( |
1555 | infer(r#" | 1579 | r#" |
1556 | struct A<X> {} | 1580 | struct A<X> {} |
1557 | type Foo = Foo; | 1581 | type Foo = Foo; |
1558 | type Bar = A<Bar>; | 1582 | type Bar = A<Bar>; |
1559 | fn test(x: Foo) {} | 1583 | fn test(x: Foo) {} |
1560 | "#), | 1584 | "#, |
1561 | @r###" | 1585 | expect![[r#" |
1562 | 58..59 'x': {unknown} | 1586 | 58..59 'x': {unknown} |
1563 | 66..68 '{}': () | 1587 | 66..68 '{}': () |
1564 | "### | 1588 | "#]], |
1565 | ) | 1589 | ) |
1566 | } | 1590 | } |
1567 | 1591 | ||
1568 | #[test] | 1592 | #[test] |
1569 | fn infer_type_param() { | 1593 | fn infer_type_param() { |
1570 | assert_snapshot!( | 1594 | check_infer( |
1571 | infer(r#" | 1595 | r#" |
1572 | fn id<T>(x: T) -> T { | 1596 | fn id<T>(x: T) -> T { |
1573 | x | 1597 | x |
1574 | } | 1598 | } |
1575 | 1599 | ||
1576 | fn clone<T>(x: &T) -> T { | 1600 | fn clone<T>(x: &T) -> T { |
1577 | *x | 1601 | *x |
1578 | } | 1602 | } |
1579 | 1603 | ||
1580 | fn test() { | 1604 | fn test() { |
1581 | let y = 10u32; | 1605 | let y = 10u32; |
1582 | id(y); | 1606 | id(y); |
1583 | let x: bool = clone(z); | 1607 | let x: bool = clone(z); |
1584 | id::<i128>(1); | 1608 | id::<i128>(1); |
1585 | } | 1609 | } |
1586 | "#), | 1610 | "#, |
1587 | @r###" | 1611 | expect![[r#" |
1588 | 9..10 'x': T | 1612 | 9..10 'x': T |
1589 | 20..29 '{ x }': T | 1613 | 20..29 '{ x }': T |
1590 | 26..27 'x': T | 1614 | 26..27 'x': T |
1591 | 43..44 'x': &T | 1615 | 43..44 'x': &T |
1592 | 55..65 '{ *x }': T | 1616 | 55..65 '{ *x }': T |
1593 | 61..63 '*x': T | 1617 | 61..63 '*x': T |
1594 | 62..63 'x': &T | 1618 | 62..63 'x': &T |
1595 | 77..157 '{ ...(1); }': () | 1619 | 77..157 '{ ...(1); }': () |
1596 | 87..88 'y': u32 | 1620 | 87..88 'y': u32 |
1597 | 91..96 '10u32': u32 | 1621 | 91..96 '10u32': u32 |
1598 | 102..104 'id': fn id<u32>(u32) -> u32 | 1622 | 102..104 'id': fn id<u32>(u32) -> u32 |
1599 | 102..107 'id(y)': u32 | 1623 | 102..107 'id(y)': u32 |
1600 | 105..106 'y': u32 | 1624 | 105..106 'y': u32 |
1601 | 117..118 'x': bool | 1625 | 117..118 'x': bool |
1602 | 127..132 'clone': fn clone<bool>(&bool) -> bool | 1626 | 127..132 'clone': fn clone<bool>(&bool) -> bool |
1603 | 127..135 'clone(z)': bool | 1627 | 127..135 'clone(z)': bool |
1604 | 133..134 'z': &bool | 1628 | 133..134 'z': &bool |
1605 | 141..151 'id::<i128>': fn id<i128>(i128) -> i128 | 1629 | 141..151 'id::<i128>': fn id<i128>(i128) -> i128 |
1606 | 141..154 'id::<i128>(1)': i128 | 1630 | 141..154 'id::<i128>(1)': i128 |
1607 | 152..153 '1': i128 | 1631 | 152..153 '1': i128 |
1608 | "### | 1632 | "#]], |
1609 | ); | 1633 | ); |
1610 | } | 1634 | } |
1611 | 1635 | ||
1612 | #[test] | 1636 | #[test] |
1613 | fn infer_const() { | 1637 | fn infer_const() { |
1614 | assert_snapshot!( | 1638 | check_infer( |
1615 | infer(r#" | 1639 | r#" |
1616 | struct Foo; | 1640 | struct Foo; |
1617 | impl Foo { const ASSOC_CONST: u32 = 0; } | 1641 | impl Foo { const ASSOC_CONST: u32 = 0; } |
1618 | const GLOBAL_CONST: u32 = 101; | 1642 | const GLOBAL_CONST: u32 = 101; |
1619 | fn test() { | 1643 | fn test() { |
1620 | const LOCAL_CONST: u32 = 99; | 1644 | const LOCAL_CONST: u32 = 99; |
1621 | let x = LOCAL_CONST; | 1645 | let x = LOCAL_CONST; |
1622 | let z = GLOBAL_CONST; | 1646 | let z = GLOBAL_CONST; |
1623 | let id = Foo::ASSOC_CONST; | 1647 | let id = Foo::ASSOC_CONST; |
1624 | } | 1648 | } |
1625 | "#), | 1649 | "#, |
1626 | @r###" | 1650 | expect![[r#" |
1627 | 48..49 '0': u32 | 1651 | 48..49 '0': u32 |
1628 | 79..82 '101': u32 | 1652 | 79..82 '101': u32 |
1629 | 94..212 '{ ...NST; }': () | 1653 | 94..212 '{ ...NST; }': () |
1630 | 137..138 'x': u32 | 1654 | 137..138 'x': u32 |
1631 | 141..152 'LOCAL_CONST': u32 | 1655 | 141..152 'LOCAL_CONST': u32 |
1632 | 162..163 'z': u32 | 1656 | 162..163 'z': u32 |
1633 | 166..178 'GLOBAL_CONST': u32 | 1657 | 166..178 'GLOBAL_CONST': u32 |
1634 | 188..190 'id': u32 | 1658 | 188..190 'id': u32 |
1635 | 193..209 'Foo::A..._CONST': u32 | 1659 | 193..209 'Foo::A..._CONST': u32 |
1636 | 125..127 '99': u32 | 1660 | 125..127 '99': u32 |
1637 | "### | 1661 | "#]], |
1638 | ); | 1662 | ); |
1639 | } | 1663 | } |
1640 | 1664 | ||
1641 | #[test] | 1665 | #[test] |
1642 | fn infer_static() { | 1666 | fn infer_static() { |
1643 | assert_snapshot!( | 1667 | check_infer( |
1644 | infer(r#" | 1668 | r#" |
1645 | static GLOBAL_STATIC: u32 = 101; | 1669 | static GLOBAL_STATIC: u32 = 101; |
1646 | static mut GLOBAL_STATIC_MUT: u32 = 101; | 1670 | static mut GLOBAL_STATIC_MUT: u32 = 101; |
1647 | fn test() { | 1671 | fn test() { |
1648 | static LOCAL_STATIC: u32 = 99; | 1672 | static LOCAL_STATIC: u32 = 99; |
1649 | static mut LOCAL_STATIC_MUT: u32 = 99; | 1673 | static mut LOCAL_STATIC_MUT: u32 = 99; |
1650 | let x = LOCAL_STATIC; | 1674 | let x = LOCAL_STATIC; |
1651 | let y = LOCAL_STATIC_MUT; | 1675 | let y = LOCAL_STATIC_MUT; |
1652 | let z = GLOBAL_STATIC; | 1676 | let z = GLOBAL_STATIC; |
1653 | let w = GLOBAL_STATIC_MUT; | 1677 | let w = GLOBAL_STATIC_MUT; |
1654 | } | 1678 | } |
1655 | "#), | 1679 | "#, |
1656 | @r###" | 1680 | expect![[r#" |
1657 | 28..31 '101': u32 | 1681 | 28..31 '101': u32 |
1658 | 69..72 '101': u32 | 1682 | 69..72 '101': u32 |
1659 | 84..279 '{ ...MUT; }': () | 1683 | 84..279 '{ ...MUT; }': () |
1660 | 172..173 'x': u32 | 1684 | 172..173 'x': u32 |
1661 | 176..188 'LOCAL_STATIC': u32 | 1685 | 176..188 'LOCAL_STATIC': u32 |
1662 | 198..199 'y': u32 | 1686 | 198..199 'y': u32 |
1663 | 202..218 'LOCAL_...IC_MUT': u32 | 1687 | 202..218 'LOCAL_...IC_MUT': u32 |
1664 | 228..229 'z': u32 | 1688 | 228..229 'z': u32 |
1665 | 232..245 'GLOBAL_STATIC': u32 | 1689 | 232..245 'GLOBAL_STATIC': u32 |
1666 | 255..256 'w': u32 | 1690 | 255..256 'w': u32 |
1667 | 259..276 'GLOBAL...IC_MUT': u32 | 1691 | 259..276 'GLOBAL...IC_MUT': u32 |
1668 | 117..119 '99': u32 | 1692 | 117..119 '99': u32 |
1669 | 160..162 '99': u32 | 1693 | 160..162 '99': u32 |
1670 | "### | 1694 | "#]], |
1671 | ); | 1695 | ); |
1672 | } | 1696 | } |
1673 | 1697 | ||
@@ -1754,413 +1778,413 @@ fn main() { | |||
1754 | 1778 | ||
1755 | #[test] | 1779 | #[test] |
1756 | fn closure_return() { | 1780 | fn closure_return() { |
1757 | assert_snapshot!( | 1781 | check_infer( |
1758 | infer(r#" | 1782 | r#" |
1759 | fn foo() -> u32 { | 1783 | fn foo() -> u32 { |
1760 | let x = || -> usize { return 1; }; | 1784 | let x = || -> usize { return 1; }; |
1761 | } | 1785 | } |
1762 | "#), | 1786 | "#, |
1763 | @r###" | 1787 | expect![[r#" |
1764 | 16..58 '{ ...; }; }': () | 1788 | 16..58 '{ ...; }; }': () |
1765 | 26..27 'x': || -> usize | 1789 | 26..27 'x': || -> usize |
1766 | 30..55 '|| -> ...n 1; }': || -> usize | 1790 | 30..55 '|| -> ...n 1; }': || -> usize |
1767 | 42..55 '{ return 1; }': usize | 1791 | 42..55 '{ return 1; }': usize |
1768 | 44..52 'return 1': ! | 1792 | 44..52 'return 1': ! |
1769 | 51..52 '1': usize | 1793 | 51..52 '1': usize |
1770 | "### | 1794 | "#]], |
1771 | ); | 1795 | ); |
1772 | } | 1796 | } |
1773 | 1797 | ||
1774 | #[test] | 1798 | #[test] |
1775 | fn closure_return_unit() { | 1799 | fn closure_return_unit() { |
1776 | assert_snapshot!( | 1800 | check_infer( |
1777 | infer(r#" | 1801 | r#" |
1778 | fn foo() -> u32 { | 1802 | fn foo() -> u32 { |
1779 | let x = || { return; }; | 1803 | let x = || { return; }; |
1780 | } | 1804 | } |
1781 | "#), | 1805 | "#, |
1782 | @r###" | 1806 | expect![[r#" |
1783 | 16..47 '{ ...; }; }': () | 1807 | 16..47 '{ ...; }; }': () |
1784 | 26..27 'x': || -> () | 1808 | 26..27 'x': || -> () |
1785 | 30..44 '|| { return; }': || -> () | 1809 | 30..44 '|| { return; }': || -> () |
1786 | 33..44 '{ return; }': () | 1810 | 33..44 '{ return; }': () |
1787 | 35..41 'return': ! | 1811 | 35..41 'return': ! |
1788 | "### | 1812 | "#]], |
1789 | ); | 1813 | ); |
1790 | } | 1814 | } |
1791 | 1815 | ||
1792 | #[test] | 1816 | #[test] |
1793 | fn closure_return_inferred() { | 1817 | fn closure_return_inferred() { |
1794 | assert_snapshot!( | 1818 | check_infer( |
1795 | infer(r#" | 1819 | r#" |
1796 | fn foo() -> u32 { | 1820 | fn foo() -> u32 { |
1797 | let x = || { "test" }; | 1821 | let x = || { "test" }; |
1798 | } | 1822 | } |
1799 | "#), | 1823 | "#, |
1800 | @r###" | 1824 | expect![[r#" |
1801 | 16..46 '{ ..." }; }': () | 1825 | 16..46 '{ ..." }; }': () |
1802 | 26..27 'x': || -> &str | 1826 | 26..27 'x': || -> &str |
1803 | 30..43 '|| { "test" }': || -> &str | 1827 | 30..43 '|| { "test" }': || -> &str |
1804 | 33..43 '{ "test" }': &str | 1828 | 33..43 '{ "test" }': &str |
1805 | 35..41 '"test"': &str | 1829 | 35..41 '"test"': &str |
1806 | "### | 1830 | "#]], |
1807 | ); | 1831 | ); |
1808 | } | 1832 | } |
1809 | 1833 | ||
1810 | #[test] | 1834 | #[test] |
1811 | fn fn_pointer_return() { | 1835 | fn fn_pointer_return() { |
1812 | assert_snapshot!( | 1836 | check_infer( |
1813 | infer(r#" | 1837 | r#" |
1814 | struct Vtable { | 1838 | struct Vtable { |
1815 | method: fn(), | 1839 | method: fn(), |
1816 | } | 1840 | } |
1817 | 1841 | ||
1818 | fn main() { | 1842 | fn main() { |
1819 | let vtable = Vtable { method: || {} }; | 1843 | let vtable = Vtable { method: || {} }; |
1820 | let m = vtable.method; | 1844 | let m = vtable.method; |
1821 | } | 1845 | } |
1822 | "#), | 1846 | "#, |
1823 | @r###" | 1847 | expect![[r#" |
1824 | 47..120 '{ ...hod; }': () | 1848 | 47..120 '{ ...hod; }': () |
1825 | 57..63 'vtable': Vtable | 1849 | 57..63 'vtable': Vtable |
1826 | 66..90 'Vtable...| {} }': Vtable | 1850 | 66..90 'Vtable...| {} }': Vtable |
1827 | 83..88 '|| {}': || -> () | 1851 | 83..88 '|| {}': || -> () |
1828 | 86..88 '{}': () | 1852 | 86..88 '{}': () |
1829 | 100..101 'm': fn() | 1853 | 100..101 'm': fn() |
1830 | 104..110 'vtable': Vtable | 1854 | 104..110 'vtable': Vtable |
1831 | 104..117 'vtable.method': fn() | 1855 | 104..117 'vtable.method': fn() |
1832 | "### | 1856 | "#]], |
1833 | ); | 1857 | ); |
1834 | } | 1858 | } |
1835 | 1859 | ||
1836 | #[test] | 1860 | #[test] |
1837 | fn effects_smoke_test() { | 1861 | fn effects_smoke_test() { |
1838 | assert_snapshot!( | 1862 | check_infer( |
1839 | infer(r#" | 1863 | r#" |
1840 | fn main() { | 1864 | fn main() { |
1841 | let x = unsafe { 92 }; | 1865 | let x = unsafe { 92 }; |
1842 | let y = async { async { () }.await }; | 1866 | let y = async { async { () }.await }; |
1843 | let z = try { () }; | 1867 | let z = try { () }; |
1844 | let t = 'a: { 92 }; | 1868 | let t = 'a: { 92 }; |
1845 | } | 1869 | } |
1846 | "#), | 1870 | "#, |
1847 | @r###" | 1871 | expect![[r#" |
1848 | 10..130 '{ ...2 }; }': () | 1872 | 10..130 '{ ...2 }; }': () |
1849 | 20..21 'x': i32 | 1873 | 20..21 'x': i32 |
1850 | 24..37 'unsafe { 92 }': i32 | 1874 | 24..37 'unsafe { 92 }': i32 |
1851 | 31..37 '{ 92 }': i32 | 1875 | 31..37 '{ 92 }': i32 |
1852 | 33..35 '92': i32 | 1876 | 33..35 '92': i32 |
1853 | 47..48 'y': {unknown} | 1877 | 47..48 'y': {unknown} |
1854 | 57..79 '{ asyn...wait }': {unknown} | 1878 | 57..79 '{ asyn...wait }': {unknown} |
1855 | 59..77 'async ....await': {unknown} | 1879 | 59..77 'async ....await': {unknown} |
1856 | 65..71 '{ () }': () | 1880 | 65..71 '{ () }': () |
1857 | 67..69 '()': () | 1881 | 67..69 '()': () |
1858 | 89..90 'z': {unknown} | 1882 | 89..90 'z': {unknown} |
1859 | 93..103 'try { () }': {unknown} | 1883 | 93..103 'try { () }': {unknown} |
1860 | 97..103 '{ () }': () | 1884 | 97..103 '{ () }': () |
1861 | 99..101 '()': () | 1885 | 99..101 '()': () |
1862 | 113..114 't': i32 | 1886 | 113..114 't': i32 |
1863 | 121..127 '{ 92 }': i32 | 1887 | 121..127 '{ 92 }': i32 |
1864 | 123..125 '92': i32 | 1888 | 123..125 '92': i32 |
1865 | "### | 1889 | "#]], |
1866 | ) | 1890 | ) |
1867 | } | 1891 | } |
1868 | 1892 | ||
1869 | #[test] | 1893 | #[test] |
1870 | fn infer_generic_from_later_assignment() { | 1894 | fn infer_generic_from_later_assignment() { |
1871 | assert_snapshot!( | 1895 | check_infer( |
1872 | infer(r#" | 1896 | r#" |
1873 | enum Option<T> { Some(T), None } | 1897 | enum Option<T> { Some(T), None } |
1874 | use Option::*; | 1898 | use Option::*; |
1875 | 1899 | ||
1876 | fn test() { | 1900 | fn test() { |
1877 | let mut end = None; | 1901 | let mut end = None; |
1878 | loop { | 1902 | loop { |
1879 | end = Some(true); | 1903 | end = Some(true); |
1880 | } | 1904 | } |
1881 | } | 1905 | } |
1882 | "#), | 1906 | "#, |
1883 | @r###" | 1907 | expect![[r#" |
1884 | 59..129 '{ ... } }': () | 1908 | 59..129 '{ ... } }': () |
1885 | 69..76 'mut end': Option<bool> | 1909 | 69..76 'mut end': Option<bool> |
1886 | 79..83 'None': Option<bool> | 1910 | 79..83 'None': Option<bool> |
1887 | 89..127 'loop {... }': ! | 1911 | 89..127 'loop {... }': ! |
1888 | 94..127 '{ ... }': () | 1912 | 94..127 '{ ... }': () |
1889 | 104..107 'end': Option<bool> | 1913 | 104..107 'end': Option<bool> |
1890 | 104..120 'end = ...(true)': () | 1914 | 104..120 'end = ...(true)': () |
1891 | 110..114 'Some': Some<bool>(bool) -> Option<bool> | 1915 | 110..114 'Some': Some<bool>(bool) -> Option<bool> |
1892 | 110..120 'Some(true)': Option<bool> | 1916 | 110..120 'Some(true)': Option<bool> |
1893 | 115..119 'true': bool | 1917 | 115..119 'true': bool |
1894 | "### | 1918 | "#]], |
1895 | ); | 1919 | ); |
1896 | } | 1920 | } |
1897 | 1921 | ||
1898 | #[test] | 1922 | #[test] |
1899 | fn infer_loop_break_with_val() { | 1923 | fn infer_loop_break_with_val() { |
1900 | assert_snapshot!( | 1924 | check_infer( |
1901 | infer(r#" | 1925 | r#" |
1902 | enum Option<T> { Some(T), None } | 1926 | enum Option<T> { Some(T), None } |
1903 | use Option::*; | 1927 | use Option::*; |
1904 | 1928 | ||
1905 | fn test() { | 1929 | fn test() { |
1906 | let x = loop { | 1930 | let x = loop { |
1907 | if false { | 1931 | if false { |
1908 | break None; | 1932 | break None; |
1909 | } | 1933 | } |
1910 | 1934 | ||
1911 | break Some(true); | 1935 | break Some(true); |
1912 | }; | 1936 | }; |
1913 | } | 1937 | } |
1914 | "#), | 1938 | "#, |
1915 | @r###" | 1939 | expect![[r#" |
1916 | 59..168 '{ ... }; }': () | 1940 | 59..168 '{ ... }; }': () |
1917 | 69..70 'x': Option<bool> | 1941 | 69..70 'x': Option<bool> |
1918 | 73..165 'loop {... }': Option<bool> | 1942 | 73..165 'loop {... }': Option<bool> |
1919 | 78..165 '{ ... }': () | 1943 | 78..165 '{ ... }': () |
1920 | 88..132 'if fal... }': () | 1944 | 88..132 'if fal... }': () |
1921 | 91..96 'false': bool | 1945 | 91..96 'false': bool |
1922 | 97..132 '{ ... }': () | 1946 | 97..132 '{ ... }': () |
1923 | 111..121 'break None': ! | 1947 | 111..121 'break None': ! |
1924 | 117..121 'None': Option<bool> | 1948 | 117..121 'None': Option<bool> |
1925 | 142..158 'break ...(true)': ! | 1949 | 142..158 'break ...(true)': ! |
1926 | 148..152 'Some': Some<bool>(bool) -> Option<bool> | 1950 | 148..152 'Some': Some<bool>(bool) -> Option<bool> |
1927 | 148..158 'Some(true)': Option<bool> | 1951 | 148..158 'Some(true)': Option<bool> |
1928 | 153..157 'true': bool | 1952 | 153..157 'true': bool |
1929 | "### | 1953 | "#]], |
1930 | ); | 1954 | ); |
1931 | } | 1955 | } |
1932 | 1956 | ||
1933 | #[test] | 1957 | #[test] |
1934 | fn infer_loop_break_without_val() { | 1958 | fn infer_loop_break_without_val() { |
1935 | assert_snapshot!( | 1959 | check_infer( |
1936 | infer(r#" | 1960 | r#" |
1937 | enum Option<T> { Some(T), None } | 1961 | enum Option<T> { Some(T), None } |
1938 | use Option::*; | 1962 | use Option::*; |
1939 | 1963 | ||
1940 | fn test() { | 1964 | fn test() { |
1941 | let x = loop { | 1965 | let x = loop { |
1942 | if false { | 1966 | if false { |
1943 | break; | 1967 | break; |
1944 | } | 1968 | } |
1945 | }; | 1969 | }; |
1946 | } | 1970 | } |
1947 | "#), | 1971 | "#, |
1948 | @r###" | 1972 | expect![[r#" |
1949 | 59..136 '{ ... }; }': () | 1973 | 59..136 '{ ... }; }': () |
1950 | 69..70 'x': () | 1974 | 69..70 'x': () |
1951 | 73..133 'loop {... }': () | 1975 | 73..133 'loop {... }': () |
1952 | 78..133 '{ ... }': () | 1976 | 78..133 '{ ... }': () |
1953 | 88..127 'if fal... }': () | 1977 | 88..127 'if fal... }': () |
1954 | 91..96 'false': bool | 1978 | 91..96 'false': bool |
1955 | 97..127 '{ ... }': () | 1979 | 97..127 '{ ... }': () |
1956 | 111..116 'break': ! | 1980 | 111..116 'break': ! |
1957 | "### | 1981 | "#]], |
1958 | ); | 1982 | ); |
1959 | } | 1983 | } |
1960 | 1984 | ||
1961 | #[test] | 1985 | #[test] |
1962 | fn infer_labelled_break_with_val() { | 1986 | fn infer_labelled_break_with_val() { |
1963 | assert_snapshot!( | 1987 | check_infer( |
1964 | infer(r#" | 1988 | r#" |
1965 | fn foo() { | 1989 | fn foo() { |
1966 | let _x = || 'outer: loop { | 1990 | let _x = || 'outer: loop { |
1967 | let inner = 'inner: loop { | 1991 | let inner = 'inner: loop { |
1968 | let i = Default::default(); | 1992 | let i = Default::default(); |
1969 | if (break 'outer i) { | 1993 | if (break 'outer i) { |
1970 | loop { break 'inner 5i8; }; | 1994 | loop { break 'inner 5i8; }; |
1971 | } else if true { | 1995 | } else if true { |
1972 | break 'inner 6; | 1996 | break 'inner 6; |
1973 | } | 1997 | } |
1974 | break 7; | 1998 | break 7; |
1975 | }; | 1999 | }; |
1976 | break inner < 8; | 2000 | break inner < 8; |
1977 | }; | 2001 | }; |
1978 | } | 2002 | } |
1979 | "#), | 2003 | "#, |
1980 | @r###" | 2004 | expect![[r#" |
1981 | 9..335 '{ ... }; }': () | 2005 | 9..335 '{ ... }; }': () |
1982 | 19..21 '_x': || -> bool | 2006 | 19..21 '_x': || -> bool |
1983 | 24..332 '|| 'ou... }': || -> bool | 2007 | 24..332 '|| 'ou... }': || -> bool |
1984 | 27..332 ''outer... }': bool | 2008 | 27..332 ''outer... }': bool |
1985 | 40..332 '{ ... }': () | 2009 | 40..332 '{ ... }': () |
1986 | 54..59 'inner': i8 | 2010 | 54..59 'inner': i8 |
1987 | 62..300 ''inner... }': i8 | 2011 | 62..300 ''inner... }': i8 |
1988 | 75..300 '{ ... }': () | 2012 | 75..300 '{ ... }': () |
1989 | 93..94 'i': bool | 2013 | 93..94 'i': bool |
1990 | 97..113 'Defaul...efault': {unknown} | 2014 | 97..113 'Defaul...efault': {unknown} |
1991 | 97..115 'Defaul...ault()': bool | 2015 | 97..115 'Defaul...ault()': bool |
1992 | 129..269 'if (br... }': () | 2016 | 129..269 'if (br... }': () |
1993 | 133..147 'break 'outer i': ! | 2017 | 133..147 'break 'outer i': ! |
1994 | 146..147 'i': bool | 2018 | 146..147 'i': bool |
1995 | 149..208 '{ ... }': () | 2019 | 149..208 '{ ... }': () |
1996 | 167..193 'loop {...5i8; }': ! | 2020 | 167..193 'loop {...5i8; }': ! |
1997 | 172..193 '{ brea...5i8; }': () | 2021 | 172..193 '{ brea...5i8; }': () |
1998 | 174..190 'break ...er 5i8': ! | 2022 | 174..190 'break ...er 5i8': ! |
1999 | 187..190 '5i8': i8 | 2023 | 187..190 '5i8': i8 |
2000 | 214..269 'if tru... }': () | 2024 | 214..269 'if tru... }': () |
2001 | 217..221 'true': bool | 2025 | 217..221 'true': bool |
2002 | 222..269 '{ ... }': () | 2026 | 222..269 '{ ... }': () |
2003 | 240..254 'break 'inner 6': ! | 2027 | 240..254 'break 'inner 6': ! |
2004 | 253..254 '6': i8 | 2028 | 253..254 '6': i8 |
2005 | 282..289 'break 7': ! | 2029 | 282..289 'break 7': ! |
2006 | 288..289 '7': i8 | 2030 | 288..289 '7': i8 |
2007 | 310..325 'break inner < 8': ! | 2031 | 310..325 'break inner < 8': ! |
2008 | 316..321 'inner': i8 | 2032 | 316..321 'inner': i8 |
2009 | 316..325 'inner < 8': bool | 2033 | 316..325 'inner < 8': bool |
2010 | 324..325 '8': i8 | 2034 | 324..325 '8': i8 |
2011 | "### | 2035 | "#]], |
2012 | ); | 2036 | ); |
2013 | } | 2037 | } |
2014 | 2038 | ||
2015 | #[test] | 2039 | #[test] |
2016 | fn generic_default() { | 2040 | fn generic_default() { |
2017 | assert_snapshot!( | 2041 | check_infer( |
2018 | infer(r#" | 2042 | r#" |
2019 | struct Thing<T = ()> { t: T } | 2043 | struct Thing<T = ()> { t: T } |
2020 | enum OtherThing<T = ()> { | 2044 | enum OtherThing<T = ()> { |
2021 | One { t: T }, | 2045 | One { t: T }, |
2022 | Two(T), | 2046 | Two(T), |
2023 | } | 2047 | } |
2024 | 2048 | ||
2025 | fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) { | 2049 | fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) { |
2026 | t1.t; | 2050 | t1.t; |
2027 | t3.t; | 2051 | t3.t; |
2028 | match t2 { | 2052 | match t2 { |
2029 | OtherThing::One { t } => { t; }, | 2053 | OtherThing::One { t } => { t; }, |
2030 | OtherThing::Two(t) => { t; }, | 2054 | OtherThing::Two(t) => { t; }, |
2031 | } | 2055 | } |
2032 | match t4 { | 2056 | match t4 { |
2033 | OtherThing::One { t } => { t; }, | 2057 | OtherThing::One { t } => { t; }, |
2034 | OtherThing::Two(t) => { t; }, | 2058 | OtherThing::Two(t) => { t; }, |
2035 | } | 2059 | } |
2036 | } | 2060 | } |
2037 | "#), | 2061 | "#, |
2038 | @r###" | 2062 | expect![[r#" |
2039 | 97..99 't1': Thing<()> | 2063 | 97..99 't1': Thing<()> |
2040 | 108..110 't2': OtherThing<()> | 2064 | 108..110 't2': OtherThing<()> |
2041 | 124..126 't3': Thing<i32> | 2065 | 124..126 't3': Thing<i32> |
2042 | 140..142 't4': OtherThing<i32> | 2066 | 140..142 't4': OtherThing<i32> |
2043 | 161..384 '{ ... } }': () | 2067 | 161..384 '{ ... } }': () |
2044 | 167..169 't1': Thing<()> | 2068 | 167..169 't1': Thing<()> |
2045 | 167..171 't1.t': () | 2069 | 167..171 't1.t': () |
2046 | 177..179 't3': Thing<i32> | 2070 | 177..179 't3': Thing<i32> |
2047 | 177..181 't3.t': i32 | 2071 | 177..181 't3.t': i32 |
2048 | 187..282 'match ... }': () | 2072 | 187..282 'match ... }': () |
2049 | 193..195 't2': OtherThing<()> | 2073 | 193..195 't2': OtherThing<()> |
2050 | 206..227 'OtherT... { t }': OtherThing<()> | 2074 | 206..227 'OtherT... { t }': OtherThing<()> |
2051 | 224..225 't': () | 2075 | 224..225 't': () |
2052 | 231..237 '{ t; }': () | 2076 | 231..237 '{ t; }': () |
2053 | 233..234 't': () | 2077 | 233..234 't': () |
2054 | 247..265 'OtherT...Two(t)': OtherThing<()> | 2078 | 247..265 'OtherT...Two(t)': OtherThing<()> |
2055 | 263..264 't': () | 2079 | 263..264 't': () |
2056 | 269..275 '{ t; }': () | 2080 | 269..275 '{ t; }': () |
2057 | 271..272 't': () | 2081 | 271..272 't': () |
2058 | 287..382 'match ... }': () | 2082 | 287..382 'match ... }': () |
2059 | 293..295 't4': OtherThing<i32> | 2083 | 293..295 't4': OtherThing<i32> |
2060 | 306..327 'OtherT... { t }': OtherThing<i32> | 2084 | 306..327 'OtherT... { t }': OtherThing<i32> |
2061 | 324..325 't': i32 | 2085 | 324..325 't': i32 |
2062 | 331..337 '{ t; }': () | 2086 | 331..337 '{ t; }': () |
2063 | 333..334 't': i32 | 2087 | 333..334 't': i32 |
2064 | 347..365 'OtherT...Two(t)': OtherThing<i32> | 2088 | 347..365 'OtherT...Two(t)': OtherThing<i32> |
2065 | 363..364 't': i32 | 2089 | 363..364 't': i32 |
2066 | 369..375 '{ t; }': () | 2090 | 369..375 '{ t; }': () |
2067 | 371..372 't': i32 | 2091 | 371..372 't': i32 |
2068 | "### | 2092 | "#]], |
2069 | ); | 2093 | ); |
2070 | } | 2094 | } |
2071 | 2095 | ||
2072 | #[test] | 2096 | #[test] |
2073 | fn generic_default_in_struct_literal() { | 2097 | fn generic_default_in_struct_literal() { |
2074 | assert_snapshot!( | 2098 | check_infer( |
2075 | infer(r#" | 2099 | r#" |
2076 | struct Thing<T = ()> { t: T } | 2100 | struct Thing<T = ()> { t: T } |
2077 | enum OtherThing<T = ()> { | 2101 | enum OtherThing<T = ()> { |
2078 | One { t: T }, | 2102 | One { t: T }, |
2079 | Two(T), | 2103 | Two(T), |
2080 | } | 2104 | } |
2081 | 2105 | ||
2082 | fn test() { | 2106 | fn test() { |
2083 | let x = Thing { t: loop {} }; | 2107 | let x = Thing { t: loop {} }; |
2084 | let y = Thing { t: () }; | 2108 | let y = Thing { t: () }; |
2085 | let z = Thing { t: 1i32 }; | 2109 | let z = Thing { t: 1i32 }; |
2086 | if let Thing { t } = z { | 2110 | if let Thing { t } = z { |
2087 | t; | 2111 | t; |
2088 | } | 2112 | } |
2089 | 2113 | ||
2090 | let a = OtherThing::One { t: 1i32 }; | 2114 | let a = OtherThing::One { t: 1i32 }; |
2091 | let b = OtherThing::Two(1i32); | 2115 | let b = OtherThing::Two(1i32); |
2092 | } | 2116 | } |
2093 | "#), | 2117 | "#, |
2094 | @r###" | 2118 | expect![[r#" |
2095 | 99..319 '{ ...32); }': () | 2119 | 99..319 '{ ...32); }': () |
2096 | 109..110 'x': Thing<!> | 2120 | 109..110 'x': Thing<!> |
2097 | 113..133 'Thing ...p {} }': Thing<!> | 2121 | 113..133 'Thing ...p {} }': Thing<!> |
2098 | 124..131 'loop {}': ! | 2122 | 124..131 'loop {}': ! |
2099 | 129..131 '{}': () | 2123 | 129..131 '{}': () |
2100 | 143..144 'y': Thing<()> | 2124 | 143..144 'y': Thing<()> |
2101 | 147..162 'Thing { t: () }': Thing<()> | 2125 | 147..162 'Thing { t: () }': Thing<()> |
2102 | 158..160 '()': () | 2126 | 158..160 '()': () |
2103 | 172..173 'z': Thing<i32> | 2127 | 172..173 'z': Thing<i32> |
2104 | 176..193 'Thing ...1i32 }': Thing<i32> | 2128 | 176..193 'Thing ...1i32 }': Thing<i32> |
2105 | 187..191 '1i32': i32 | 2129 | 187..191 '1i32': i32 |
2106 | 199..240 'if let... }': () | 2130 | 199..240 'if let... }': () |
2107 | 206..217 'Thing { t }': Thing<i32> | 2131 | 206..217 'Thing { t }': Thing<i32> |
2108 | 214..215 't': i32 | 2132 | 214..215 't': i32 |
2109 | 220..221 'z': Thing<i32> | 2133 | 220..221 'z': Thing<i32> |
2110 | 222..240 '{ ... }': () | 2134 | 222..240 '{ ... }': () |
2111 | 232..233 't': i32 | 2135 | 232..233 't': i32 |
2112 | 250..251 'a': OtherThing<i32> | 2136 | 250..251 'a': OtherThing<i32> |
2113 | 254..281 'OtherT...1i32 }': OtherThing<i32> | 2137 | 254..281 'OtherT...1i32 }': OtherThing<i32> |
2114 | 275..279 '1i32': i32 | 2138 | 275..279 '1i32': i32 |
2115 | 291..292 'b': OtherThing<i32> | 2139 | 291..292 'b': OtherThing<i32> |
2116 | 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32> | 2140 | 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32> |
2117 | 295..316 'OtherT...(1i32)': OtherThing<i32> | 2141 | 295..316 'OtherT...(1i32)': OtherThing<i32> |
2118 | 311..315 '1i32': i32 | 2142 | 311..315 '1i32': i32 |
2119 | "### | 2143 | "#]], |
2120 | ); | 2144 | ); |
2121 | } | 2145 | } |
2122 | 2146 | ||
2123 | #[test] | 2147 | #[test] |
2124 | fn generic_default_depending_on_other_type_arg() { | 2148 | fn generic_default_depending_on_other_type_arg() { |
2125 | assert_snapshot!( | 2149 | // FIXME: the {unknown} is a bug |
2126 | infer(r#" | 2150 | check_infer( |
2127 | struct Thing<T = u128, F = fn() -> T> { t: T } | 2151 | r#" |
2128 | 2152 | struct Thing<T = u128, F = fn() -> T> { t: T } | |
2129 | fn test(t1: Thing<u32>, t2: Thing) { | 2153 | |
2130 | t1; | 2154 | fn test(t1: Thing<u32>, t2: Thing) { |
2131 | t2; | 2155 | t1; |
2132 | Thing::<_> { t: 1u32 }; | 2156 | t2; |
2133 | } | 2157 | Thing::<_> { t: 1u32 }; |
2134 | "#), | 2158 | } |
2135 | // FIXME: the {unknown} is a bug | 2159 | "#, |
2136 | @r###" | 2160 | expect![[r#" |
2137 | 56..58 't1': Thing<u32, fn() -> u32> | 2161 | 56..58 't1': Thing<u32, fn() -> u32> |
2138 | 72..74 't2': Thing<u128, fn() -> u128> | 2162 | 72..74 't2': Thing<u128, fn() -> u128> |
2139 | 83..130 '{ ...2 }; }': () | 2163 | 83..130 '{ ...2 }; }': () |
2140 | 89..91 't1': Thing<u32, fn() -> u32> | 2164 | 89..91 't1': Thing<u32, fn() -> u32> |
2141 | 97..99 't2': Thing<u128, fn() -> u128> | 2165 | 97..99 't2': Thing<u128, fn() -> u128> |
2142 | 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}> | 2166 | 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}> |
2143 | 121..125 '1u32': u32 | 2167 | 121..125 '1u32': u32 |
2144 | "### | 2168 | "#]], |
2145 | ); | 2169 | ); |
2146 | } | 2170 | } |
2147 | 2171 | ||
2148 | #[test] | 2172 | #[test] |
2149 | fn generic_default_depending_on_other_type_arg_forward() { | 2173 | fn generic_default_depending_on_other_type_arg_forward() { |
2150 | assert_snapshot!( | 2174 | // the {unknown} here is intentional, as defaults are not allowed to |
2151 | infer(r#" | 2175 | // refer to type parameters coming later |
2152 | struct Thing<F = fn() -> T, T = u128> { t: T } | 2176 | check_infer( |
2153 | 2177 | r#" | |
2154 | fn test(t1: Thing) { | 2178 | struct Thing<F = fn() -> T, T = u128> { t: T } |
2155 | t1; | 2179 | |
2156 | } | 2180 | fn test(t1: Thing) { |
2157 | "#), | 2181 | t1; |
2158 | // the {unknown} here is intentional, as defaults are not allowed to | 2182 | } |
2159 | // refer to type parameters coming later | 2183 | "#, |
2160 | @r###" | 2184 | expect![[r#" |
2161 | 56..58 't1': Thing<fn() -> {unknown}, u128> | 2185 | 56..58 't1': Thing<fn() -> {unknown}, u128> |
2162 | 67..78 '{ t1; }': () | 2186 | 67..78 '{ t1; }': () |
2163 | 73..75 't1': Thing<fn() -> {unknown}, u128> | 2187 | 73..75 't1': Thing<fn() -> {unknown}, u128> |
2164 | "### | 2188 | "#]], |
2165 | ); | 2189 | ); |
2166 | } | 2190 | } |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 01c919a7e..526e61caf 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{check_types, infer, infer_with_mismatches}; | 4 | use super::{check_infer, check_infer_with_mismatches, check_types}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn infer_await() { | 7 | fn infer_await() { |
@@ -38,7 +38,7 @@ fn infer_async() { | |||
38 | r#" | 38 | r#" |
39 | //- /main.rs crate:main deps:core | 39 | //- /main.rs crate:main deps:core |
40 | async fn foo() -> u64 { | 40 | async fn foo() -> u64 { |
41 | 128 | 41 | 128 |
42 | } | 42 | } |
43 | 43 | ||
44 | fn test() { | 44 | fn test() { |
@@ -65,7 +65,7 @@ fn infer_desugar_async() { | |||
65 | r#" | 65 | r#" |
66 | //- /main.rs crate:main deps:core | 66 | //- /main.rs crate:main deps:core |
67 | async fn foo() -> u64 { | 67 | async fn foo() -> u64 { |
68 | 128 | 68 | 128 |
69 | } | 69 | } |
70 | 70 | ||
71 | fn test() { | 71 | fn test() { |
@@ -222,291 +222,291 @@ mod ops { | |||
222 | 222 | ||
223 | #[test] | 223 | #[test] |
224 | fn infer_from_bound_1() { | 224 | fn infer_from_bound_1() { |
225 | assert_snapshot!( | 225 | check_infer( |
226 | infer(r#" | 226 | r#" |
227 | trait Trait<T> {} | 227 | trait Trait<T> {} |
228 | struct S<T>(T); | 228 | struct S<T>(T); |
229 | impl<U> Trait<U> for S<U> {} | 229 | impl<U> Trait<U> for S<U> {} |
230 | fn foo<T: Trait<u32>>(t: T) {} | 230 | fn foo<T: Trait<u32>>(t: T) {} |
231 | fn test() { | 231 | fn test() { |
232 | let s = S(unknown); | 232 | let s = S(unknown); |
233 | foo(s); | 233 | foo(s); |
234 | } | 234 | } |
235 | "#), | 235 | "#, |
236 | @r###" | 236 | expect![[r#" |
237 | 85..86 't': T | 237 | 85..86 't': T |
238 | 91..93 '{}': () | 238 | 91..93 '{}': () |
239 | 104..143 '{ ...(s); }': () | 239 | 104..143 '{ ...(s); }': () |
240 | 114..115 's': S<u32> | 240 | 114..115 's': S<u32> |
241 | 118..119 'S': S<u32>(u32) -> S<u32> | 241 | 118..119 'S': S<u32>(u32) -> S<u32> |
242 | 118..128 'S(unknown)': S<u32> | 242 | 118..128 'S(unknown)': S<u32> |
243 | 120..127 'unknown': u32 | 243 | 120..127 'unknown': u32 |
244 | 134..137 'foo': fn foo<S<u32>>(S<u32>) | 244 | 134..137 'foo': fn foo<S<u32>>(S<u32>) |
245 | 134..140 'foo(s)': () | 245 | 134..140 'foo(s)': () |
246 | 138..139 's': S<u32> | 246 | 138..139 's': S<u32> |
247 | "### | 247 | "#]], |
248 | ); | 248 | ); |
249 | } | 249 | } |
250 | 250 | ||
251 | #[test] | 251 | #[test] |
252 | fn infer_from_bound_2() { | 252 | fn infer_from_bound_2() { |
253 | assert_snapshot!( | 253 | check_infer( |
254 | infer(r#" | 254 | r#" |
255 | trait Trait<T> {} | 255 | trait Trait<T> {} |
256 | struct S<T>(T); | 256 | struct S<T>(T); |
257 | impl<U> Trait<U> for S<U> {} | 257 | impl<U> Trait<U> for S<U> {} |
258 | fn foo<U, T: Trait<U>>(t: T) -> U {} | 258 | fn foo<U, T: Trait<U>>(t: T) -> U {} |
259 | fn test() { | 259 | fn test() { |
260 | let s = S(unknown); | 260 | let s = S(unknown); |
261 | let x: u32 = foo(s); | 261 | let x: u32 = foo(s); |
262 | } | 262 | } |
263 | "#), | 263 | "#, |
264 | @r###" | 264 | expect![[r#" |
265 | 86..87 't': T | 265 | 86..87 't': T |
266 | 97..99 '{}': () | 266 | 97..99 '{}': () |
267 | 110..162 '{ ...(s); }': () | 267 | 110..162 '{ ...(s); }': () |
268 | 120..121 's': S<u32> | 268 | 120..121 's': S<u32> |
269 | 124..125 'S': S<u32>(u32) -> S<u32> | 269 | 124..125 'S': S<u32>(u32) -> S<u32> |
270 | 124..134 'S(unknown)': S<u32> | 270 | 124..134 'S(unknown)': S<u32> |
271 | 126..133 'unknown': u32 | 271 | 126..133 'unknown': u32 |
272 | 144..145 'x': u32 | 272 | 144..145 'x': u32 |
273 | 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 | 273 | 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 |
274 | 153..159 'foo(s)': u32 | 274 | 153..159 'foo(s)': u32 |
275 | 157..158 's': S<u32> | 275 | 157..158 's': S<u32> |
276 | "### | 276 | "#]], |
277 | ); | 277 | ); |
278 | } | 278 | } |
279 | 279 | ||
280 | #[test] | 280 | #[test] |
281 | fn trait_default_method_self_bound_implements_trait() { | 281 | fn trait_default_method_self_bound_implements_trait() { |
282 | mark::check!(trait_self_implements_self); | 282 | mark::check!(trait_self_implements_self); |
283 | assert_snapshot!( | 283 | check_infer( |
284 | infer(r#" | 284 | r#" |
285 | trait Trait { | 285 | trait Trait { |
286 | fn foo(&self) -> i64; | 286 | fn foo(&self) -> i64; |
287 | fn bar(&self) -> { | 287 | fn bar(&self) -> { |
288 | let x = self.foo(); | 288 | let x = self.foo(); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | "#), | 291 | "#, |
292 | @r###" | 292 | expect![[r#" |
293 | 26..30 'self': &Self | 293 | 26..30 'self': &Self |
294 | 52..56 'self': &Self | 294 | 52..56 'self': &Self |
295 | 61..96 '{ ... }': () | 295 | 61..96 '{ ... }': () |
296 | 75..76 'x': i64 | 296 | 75..76 'x': i64 |
297 | 79..83 'self': &Self | 297 | 79..83 'self': &Self |
298 | 79..89 'self.foo()': i64 | 298 | 79..89 'self.foo()': i64 |
299 | "### | 299 | "#]], |
300 | ); | 300 | ); |
301 | } | 301 | } |
302 | 302 | ||
303 | #[test] | 303 | #[test] |
304 | fn trait_default_method_self_bound_implements_super_trait() { | 304 | fn trait_default_method_self_bound_implements_super_trait() { |
305 | assert_snapshot!( | 305 | check_infer( |
306 | infer(r#" | 306 | r#" |
307 | trait SuperTrait { | 307 | trait SuperTrait { |
308 | fn foo(&self) -> i64; | 308 | fn foo(&self) -> i64; |
309 | } | 309 | } |
310 | trait Trait: SuperTrait { | 310 | trait Trait: SuperTrait { |
311 | fn bar(&self) -> { | 311 | fn bar(&self) -> { |
312 | let x = self.foo(); | 312 | let x = self.foo(); |
313 | } | 313 | } |
314 | } | 314 | } |
315 | "#), | 315 | "#, |
316 | @r###" | 316 | expect![[r#" |
317 | 31..35 'self': &Self | 317 | 31..35 'self': &Self |
318 | 85..89 'self': &Self | 318 | 85..89 'self': &Self |
319 | 94..129 '{ ... }': () | 319 | 94..129 '{ ... }': () |
320 | 108..109 'x': i64 | 320 | 108..109 'x': i64 |
321 | 112..116 'self': &Self | 321 | 112..116 'self': &Self |
322 | 112..122 'self.foo()': i64 | 322 | 112..122 'self.foo()': i64 |
323 | "### | 323 | "#]], |
324 | ); | 324 | ); |
325 | } | 325 | } |
326 | 326 | ||
327 | #[test] | 327 | #[test] |
328 | fn infer_project_associated_type() { | 328 | fn infer_project_associated_type() { |
329 | assert_snapshot!( | 329 | check_infer( |
330 | infer(r#" | 330 | r#" |
331 | trait Iterable { | 331 | trait Iterable { |
332 | type Item; | 332 | type Item; |
333 | } | 333 | } |
334 | struct S; | 334 | struct S; |
335 | impl Iterable for S { type Item = u32; } | 335 | impl Iterable for S { type Item = u32; } |
336 | fn test<T: Iterable>() { | 336 | fn test<T: Iterable>() { |
337 | let x: <S as Iterable>::Item = 1; | 337 | let x: <S as Iterable>::Item = 1; |
338 | let y: <T as Iterable>::Item = no_matter; | 338 | let y: <T as Iterable>::Item = no_matter; |
339 | let z: T::Item = no_matter; | 339 | let z: T::Item = no_matter; |
340 | let a: <T>::Item = no_matter; | 340 | let a: <T>::Item = no_matter; |
341 | } | 341 | } |
342 | "#), | 342 | "#, |
343 | @r###" | 343 | expect![[r#" |
344 | 107..260 '{ ...ter; }': () | 344 | 108..261 '{ ...ter; }': () |
345 | 117..118 'x': u32 | 345 | 118..119 'x': u32 |
346 | 144..145 '1': u32 | 346 | 145..146 '1': u32 |
347 | 155..156 'y': Iterable::Item<T> | 347 | 156..157 'y': Iterable::Item<T> |
348 | 182..191 'no_matter': Iterable::Item<T> | 348 | 183..192 'no_matter': Iterable::Item<T> |
349 | 201..202 'z': Iterable::Item<T> | 349 | 202..203 'z': Iterable::Item<T> |
350 | 214..223 'no_matter': Iterable::Item<T> | 350 | 215..224 'no_matter': Iterable::Item<T> |
351 | 233..234 'a': Iterable::Item<T> | 351 | 234..235 'a': Iterable::Item<T> |
352 | 248..257 'no_matter': Iterable::Item<T> | 352 | 249..258 'no_matter': Iterable::Item<T> |
353 | "### | 353 | "#]], |
354 | ); | 354 | ); |
355 | } | 355 | } |
356 | 356 | ||
357 | #[test] | 357 | #[test] |
358 | fn infer_return_associated_type() { | 358 | fn infer_return_associated_type() { |
359 | assert_snapshot!( | 359 | check_infer( |
360 | infer(r#" | 360 | r#" |
361 | trait Iterable { | 361 | trait Iterable { |
362 | type Item; | 362 | type Item; |
363 | } | 363 | } |
364 | struct S; | 364 | struct S; |
365 | impl Iterable for S { type Item = u32; } | 365 | impl Iterable for S { type Item = u32; } |
366 | fn foo1<T: Iterable>(t: T) -> T::Item {} | 366 | fn foo1<T: Iterable>(t: T) -> T::Item {} |
367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} | 367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} |
368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} | 368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} |
369 | fn test() { | 369 | fn test() { |
370 | let x = foo1(S); | 370 | let x = foo1(S); |
371 | let y = foo2(S); | 371 | let y = foo2(S); |
372 | let z = foo3(S); | 372 | let z = foo3(S); |
373 | } | 373 | } |
374 | "#), | 374 | "#, |
375 | @r###" | 375 | expect![[r#" |
376 | 105..106 't': T | 376 | 106..107 't': T |
377 | 122..124 '{}': () | 377 | 123..125 '{}': () |
378 | 146..147 't': T | 378 | 147..148 't': T |
379 | 177..179 '{}': () | 379 | 178..180 '{}': () |
380 | 201..202 't': T | 380 | 202..203 't': T |
381 | 220..222 '{}': () | 381 | 221..223 '{}': () |
382 | 233..299 '{ ...(S); }': () | 382 | 234..300 '{ ...(S); }': () |
383 | 243..244 'x': u32 | 383 | 244..245 'x': u32 |
384 | 247..251 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item | 384 | 248..252 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item |
385 | 247..254 'foo1(S)': u32 | 385 | 248..255 'foo1(S)': u32 |
386 | 252..253 'S': S | 386 | 253..254 'S': S |
387 | 264..265 'y': u32 | 387 | 265..266 'y': u32 |
388 | 268..272 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item | 388 | 269..273 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item |
389 | 268..275 'foo2(S)': u32 | 389 | 269..276 'foo2(S)': u32 |
390 | 273..274 'S': S | 390 | 274..275 'S': S |
391 | 285..286 'z': u32 | 391 | 286..287 'z': u32 |
392 | 289..293 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item | 392 | 290..294 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item |
393 | 289..296 'foo3(S)': u32 | 393 | 290..297 'foo3(S)': u32 |
394 | 294..295 'S': S | 394 | 295..296 'S': S |
395 | "### | 395 | "#]], |
396 | ); | 396 | ); |
397 | } | 397 | } |
398 | 398 | ||
399 | #[test] | 399 | #[test] |
400 | fn infer_associated_type_bound() { | 400 | fn infer_associated_type_bound() { |
401 | assert_snapshot!( | 401 | check_infer( |
402 | infer(r#" | 402 | r#" |
403 | trait Iterable { | 403 | trait Iterable { |
404 | type Item; | 404 | type Item; |
405 | } | 405 | } |
406 | fn test<T: Iterable<Item=u32>>() { | 406 | fn test<T: Iterable<Item=u32>>() { |
407 | let y: T::Item = unknown; | 407 | let y: T::Item = unknown; |
408 | } | 408 | } |
409 | "#), | 409 | "#, |
410 | @r###" | 410 | expect![[r#" |
411 | 66..99 '{ ...own; }': () | 411 | 67..100 '{ ...own; }': () |
412 | 76..77 'y': u32 | 412 | 77..78 'y': u32 |
413 | 89..96 'unknown': u32 | 413 | 90..97 'unknown': u32 |
414 | "### | 414 | "#]], |
415 | ); | 415 | ); |
416 | } | 416 | } |
417 | 417 | ||
418 | #[test] | 418 | #[test] |
419 | fn infer_const_body() { | 419 | fn infer_const_body() { |
420 | assert_snapshot!( | 420 | check_infer( |
421 | infer(r#" | 421 | r#" |
422 | const A: u32 = 1 + 1; | 422 | const A: u32 = 1 + 1; |
423 | static B: u64 = { let x = 1; x }; | 423 | static B: u64 = { let x = 1; x }; |
424 | "#), | 424 | "#, |
425 | @r###" | 425 | expect![[r#" |
426 | 15..16 '1': u32 | 426 | 15..16 '1': u32 |
427 | 15..20 '1 + 1': u32 | 427 | 15..20 '1 + 1': u32 |
428 | 19..20 '1': u32 | 428 | 19..20 '1': u32 |
429 | 38..54 '{ let ...1; x }': u64 | 429 | 38..54 '{ let ...1; x }': u64 |
430 | 44..45 'x': u64 | 430 | 44..45 'x': u64 |
431 | 48..49 '1': u64 | 431 | 48..49 '1': u64 |
432 | 51..52 'x': u64 | 432 | 51..52 'x': u64 |
433 | "### | 433 | "#]], |
434 | ); | 434 | ); |
435 | } | 435 | } |
436 | 436 | ||
437 | #[test] | 437 | #[test] |
438 | fn tuple_struct_fields() { | 438 | fn tuple_struct_fields() { |
439 | assert_snapshot!( | 439 | check_infer( |
440 | infer(r#" | 440 | r#" |
441 | struct S(i32, u64); | 441 | struct S(i32, u64); |
442 | fn test() -> u64 { | 442 | fn test() -> u64 { |
443 | let a = S(4, 6); | 443 | let a = S(4, 6); |
444 | let b = a.0; | 444 | let b = a.0; |
445 | a.1 | 445 | a.1 |
446 | } | 446 | } |
447 | "#), | 447 | "#, |
448 | @r###" | 448 | expect![[r#" |
449 | 37..86 '{ ... a.1 }': u64 | 449 | 37..86 '{ ... a.1 }': u64 |
450 | 47..48 'a': S | 450 | 47..48 'a': S |
451 | 51..52 'S': S(i32, u64) -> S | 451 | 51..52 'S': S(i32, u64) -> S |
452 | 51..58 'S(4, 6)': S | 452 | 51..58 'S(4, 6)': S |
453 | 53..54 '4': i32 | 453 | 53..54 '4': i32 |
454 | 56..57 '6': u64 | 454 | 56..57 '6': u64 |
455 | 68..69 'b': i32 | 455 | 68..69 'b': i32 |
456 | 72..73 'a': S | 456 | 72..73 'a': S |
457 | 72..75 'a.0': i32 | 457 | 72..75 'a.0': i32 |
458 | 81..82 'a': S | 458 | 81..82 'a': S |
459 | 81..84 'a.1': u64 | 459 | 81..84 'a.1': u64 |
460 | "### | 460 | "#]], |
461 | ); | 461 | ); |
462 | } | 462 | } |
463 | 463 | ||
464 | #[test] | 464 | #[test] |
465 | fn tuple_struct_with_fn() { | 465 | fn tuple_struct_with_fn() { |
466 | assert_snapshot!( | 466 | check_infer( |
467 | infer(r#" | 467 | r#" |
468 | struct S(fn(u32) -> u64); | 468 | struct S(fn(u32) -> u64); |
469 | fn test() -> u64 { | 469 | fn test() -> u64 { |
470 | let a = S(|i| 2*i); | 470 | let a = S(|i| 2*i); |
471 | let b = a.0(4); | 471 | let b = a.0(4); |
472 | a.0(2) | 472 | a.0(2) |
473 | } | 473 | } |
474 | "#), | 474 | "#, |
475 | @r###" | 475 | expect![[r#" |
476 | 43..101 '{ ...0(2) }': u64 | 476 | 43..101 '{ ...0(2) }': u64 |
477 | 53..54 'a': S | 477 | 53..54 'a': S |
478 | 57..58 'S': S(fn(u32) -> u64) -> S | 478 | 57..58 'S': S(fn(u32) -> u64) -> S |
479 | 57..67 'S(|i| 2*i)': S | 479 | 57..67 'S(|i| 2*i)': S |
480 | 59..66 '|i| 2*i': |u32| -> u64 | 480 | 59..66 '|i| 2*i': |u32| -> u64 |
481 | 60..61 'i': u32 | 481 | 60..61 'i': u32 |
482 | 63..64 '2': u32 | 482 | 63..64 '2': u32 |
483 | 63..66 '2*i': u32 | 483 | 63..66 '2*i': u32 |
484 | 65..66 'i': u32 | 484 | 65..66 'i': u32 |
485 | 77..78 'b': u64 | 485 | 77..78 'b': u64 |
486 | 81..82 'a': S | 486 | 81..82 'a': S |
487 | 81..84 'a.0': fn(u32) -> u64 | 487 | 81..84 'a.0': fn(u32) -> u64 |
488 | 81..87 'a.0(4)': u64 | 488 | 81..87 'a.0(4)': u64 |
489 | 85..86 '4': u32 | 489 | 85..86 '4': u32 |
490 | 93..94 'a': S | 490 | 93..94 'a': S |
491 | 93..96 'a.0': fn(u32) -> u64 | 491 | 93..96 'a.0': fn(u32) -> u64 |
492 | 93..99 'a.0(2)': u64 | 492 | 93..99 'a.0(2)': u64 |
493 | 97..98 '2': u32 | 493 | 97..98 '2': u32 |
494 | "### | 494 | "#]], |
495 | ); | 495 | ); |
496 | } | 496 | } |
497 | 497 | ||
498 | #[test] | 498 | #[test] |
499 | fn indexing_arrays() { | 499 | fn indexing_arrays() { |
500 | assert_snapshot!( | 500 | check_infer( |
501 | infer("fn main() { &mut [9][2]; }"), | 501 | "fn main() { &mut [9][2]; }", |
502 | @r###" | 502 | expect![[r#" |
503 | 10..26 '{ &mut...[2]; }': () | 503 | 10..26 '{ &mut...[2]; }': () |
504 | 12..23 '&mut [9][2]': &mut {unknown} | 504 | 12..23 '&mut [9][2]': &mut {unknown} |
505 | 17..20 '[9]': [i32; _] | 505 | 17..20 '[9]': [i32; _] |
506 | 17..23 '[9][2]': {unknown} | 506 | 17..23 '[9][2]': {unknown} |
507 | 18..19 '9': i32 | 507 | 18..19 '9': i32 |
508 | 21..22 '2': i32 | 508 | 21..22 '2': i32 |
509 | "### | 509 | "#]], |
510 | ) | 510 | ) |
511 | } | 511 | } |
512 | 512 | ||
@@ -541,6 +541,42 @@ mod ops { | |||
541 | } | 541 | } |
542 | 542 | ||
543 | #[test] | 543 | #[test] |
544 | fn infer_ops_index_int() { | ||
545 | check_types( | ||
546 | r#" | ||
547 | //- /main.rs crate:main deps:std | ||
548 | struct Bar; | ||
549 | struct Foo; | ||
550 | |||
551 | impl std::ops::Index<u32> for Bar { | ||
552 | type Output = Foo; | ||
553 | } | ||
554 | |||
555 | struct Range; | ||
556 | impl std::ops::Index<Range> for Bar { | ||
557 | type Output = Bar; | ||
558 | } | ||
559 | |||
560 | fn test() { | ||
561 | let a = Bar; | ||
562 | let b = a[1]; | ||
563 | b; | ||
564 | //^ Foo | ||
565 | } | ||
566 | |||
567 | //- /std.rs crate:std | ||
568 | #[prelude_import] use ops::*; | ||
569 | mod ops { | ||
570 | #[lang = "index"] | ||
571 | pub trait Index<Idx> { | ||
572 | type Output; | ||
573 | } | ||
574 | } | ||
575 | "#, | ||
576 | ); | ||
577 | } | ||
578 | |||
579 | #[test] | ||
544 | fn infer_ops_index_autoderef() { | 580 | fn infer_ops_index_autoderef() { |
545 | check_types( | 581 | check_types( |
546 | r#" | 582 | r#" |
@@ -872,476 +908,475 @@ fn test<T: ApplyL>(t: T) { | |||
872 | 908 | ||
873 | #[test] | 909 | #[test] |
874 | fn argument_impl_trait() { | 910 | fn argument_impl_trait() { |
875 | assert_snapshot!( | 911 | check_infer_with_mismatches( |
876 | infer_with_mismatches(r#" | 912 | r#" |
877 | trait Trait<T> { | 913 | trait Trait<T> { |
878 | fn foo(&self) -> T; | 914 | fn foo(&self) -> T; |
879 | fn foo2(&self) -> i64; | 915 | fn foo2(&self) -> i64; |
880 | } | 916 | } |
881 | fn bar(x: impl Trait<u16>) {} | 917 | fn bar(x: impl Trait<u16>) {} |
882 | struct S<T>(T); | 918 | struct S<T>(T); |
883 | impl<T> Trait<T> for S<T> {} | 919 | impl<T> Trait<T> for S<T> {} |
884 | 920 | ||
885 | fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { | 921 | fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { |
886 | x; | 922 | x; |
887 | y; | 923 | y; |
888 | let z = S(1); | 924 | let z = S(1); |
889 | bar(z); | 925 | bar(z); |
890 | x.foo(); | 926 | x.foo(); |
891 | y.foo(); | 927 | y.foo(); |
892 | z.foo(); | 928 | z.foo(); |
893 | x.foo2(); | 929 | x.foo2(); |
894 | y.foo2(); | 930 | y.foo2(); |
895 | z.foo2(); | 931 | z.foo2(); |
896 | } | 932 | } |
897 | "#, true), | 933 | "#, |
898 | @r###" | 934 | expect![[r#" |
899 | 29..33 'self': &Self | 935 | 29..33 'self': &Self |
900 | 54..58 'self': &Self | 936 | 54..58 'self': &Self |
901 | 77..78 'x': impl Trait<u16> | 937 | 77..78 'x': impl Trait<u16> |
902 | 97..99 '{}': () | 938 | 97..99 '{}': () |
903 | 154..155 'x': impl Trait<u64> | 939 | 154..155 'x': impl Trait<u64> |
904 | 174..175 'y': &impl Trait<u32> | 940 | 174..175 'y': &impl Trait<u32> |
905 | 195..323 '{ ...2(); }': () | 941 | 195..323 '{ ...2(); }': () |
906 | 201..202 'x': impl Trait<u64> | 942 | 201..202 'x': impl Trait<u64> |
907 | 208..209 'y': &impl Trait<u32> | 943 | 208..209 'y': &impl Trait<u32> |
908 | 219..220 'z': S<u16> | 944 | 219..220 'z': S<u16> |
909 | 223..224 'S': S<u16>(u16) -> S<u16> | 945 | 223..224 'S': S<u16>(u16) -> S<u16> |
910 | 223..227 'S(1)': S<u16> | 946 | 223..227 'S(1)': S<u16> |
911 | 225..226 '1': u16 | 947 | 225..226 '1': u16 |
912 | 233..236 'bar': fn bar(S<u16>) | 948 | 233..236 'bar': fn bar(S<u16>) |
913 | 233..239 'bar(z)': () | 949 | 233..239 'bar(z)': () |
914 | 237..238 'z': S<u16> | 950 | 237..238 'z': S<u16> |
915 | 245..246 'x': impl Trait<u64> | 951 | 245..246 'x': impl Trait<u64> |
916 | 245..252 'x.foo()': u64 | 952 | 245..252 'x.foo()': u64 |
917 | 258..259 'y': &impl Trait<u32> | 953 | 258..259 'y': &impl Trait<u32> |
918 | 258..265 'y.foo()': u32 | 954 | 258..265 'y.foo()': u32 |
919 | 271..272 'z': S<u16> | 955 | 271..272 'z': S<u16> |
920 | 271..278 'z.foo()': u16 | 956 | 271..278 'z.foo()': u16 |
921 | 284..285 'x': impl Trait<u64> | 957 | 284..285 'x': impl Trait<u64> |
922 | 284..292 'x.foo2()': i64 | 958 | 284..292 'x.foo2()': i64 |
923 | 298..299 'y': &impl Trait<u32> | 959 | 298..299 'y': &impl Trait<u32> |
924 | 298..306 'y.foo2()': i64 | 960 | 298..306 'y.foo2()': i64 |
925 | 312..313 'z': S<u16> | 961 | 312..313 'z': S<u16> |
926 | 312..320 'z.foo2()': i64 | 962 | 312..320 'z.foo2()': i64 |
927 | "### | 963 | "#]], |
928 | ); | 964 | ); |
929 | } | 965 | } |
930 | 966 | ||
931 | #[test] | 967 | #[test] |
932 | fn argument_impl_trait_type_args_1() { | 968 | fn argument_impl_trait_type_args_1() { |
933 | assert_snapshot!( | 969 | check_infer_with_mismatches( |
934 | infer_with_mismatches(r#" | 970 | r#" |
935 | trait Trait {} | 971 | trait Trait {} |
936 | trait Foo { | 972 | trait Foo { |
937 | // this function has an implicit Self param, an explicit type param, | 973 | // this function has an implicit Self param, an explicit type param, |
938 | // and an implicit impl Trait param! | 974 | // and an implicit impl Trait param! |
939 | fn bar<T>(x: impl Trait) -> T { loop {} } | 975 | fn bar<T>(x: impl Trait) -> T { loop {} } |
940 | } | 976 | } |
941 | fn foo<T>(x: impl Trait) -> T { loop {} } | 977 | fn foo<T>(x: impl Trait) -> T { loop {} } |
942 | struct S; | 978 | struct S; |
943 | impl Trait for S {} | 979 | impl Trait for S {} |
944 | struct F; | 980 | struct F; |
945 | impl Foo for F {} | 981 | impl Foo for F {} |
946 | 982 | ||
947 | fn test() { | 983 | fn test() { |
948 | Foo::bar(S); | 984 | Foo::bar(S); |
949 | <F as Foo>::bar(S); | 985 | <F as Foo>::bar(S); |
950 | F::bar(S); | 986 | F::bar(S); |
951 | Foo::bar::<u32>(S); | 987 | Foo::bar::<u32>(S); |
952 | <F as Foo>::bar::<u32>(S); | 988 | <F as Foo>::bar::<u32>(S); |
953 | 989 | ||
954 | foo(S); | 990 | foo(S); |
955 | foo::<u32>(S); | 991 | foo::<u32>(S); |
956 | foo::<u32, i32>(S); // we should ignore the extraneous i32 | 992 | foo::<u32, i32>(S); // we should ignore the extraneous i32 |
957 | } | 993 | } |
958 | "#, true), | 994 | "#, |
959 | @r###" | 995 | expect![[r#" |
960 | 155..156 'x': impl Trait | 996 | 155..156 'x': impl Trait |
961 | 175..186 '{ loop {} }': T | 997 | 175..186 '{ loop {} }': T |
962 | 177..184 'loop {}': ! | 998 | 177..184 'loop {}': ! |
963 | 182..184 '{}': () | 999 | 182..184 '{}': () |
964 | 199..200 'x': impl Trait | 1000 | 199..200 'x': impl Trait |
965 | 219..230 '{ loop {} }': T | 1001 | 219..230 '{ loop {} }': T |
966 | 221..228 'loop {}': ! | 1002 | 221..228 'loop {}': ! |
967 | 226..228 '{}': () | 1003 | 226..228 '{}': () |
968 | 300..509 '{ ... i32 }': () | 1004 | 300..509 '{ ... i32 }': () |
969 | 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} | 1005 | 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} |
970 | 306..317 'Foo::bar(S)': {unknown} | 1006 | 306..317 'Foo::bar(S)': {unknown} |
971 | 315..316 'S': S | 1007 | 315..316 'S': S |
972 | 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} | 1008 | 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} |
973 | 323..341 '<F as ...bar(S)': {unknown} | 1009 | 323..341 '<F as ...bar(S)': {unknown} |
974 | 339..340 'S': S | 1010 | 339..340 'S': S |
975 | 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} | 1011 | 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} |
976 | 347..356 'F::bar(S)': {unknown} | 1012 | 347..356 'F::bar(S)': {unknown} |
977 | 354..355 'S': S | 1013 | 354..355 'S': S |
978 | 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 | 1014 | 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 |
979 | 362..380 'Foo::b...32>(S)': u32 | 1015 | 362..380 'Foo::b...32>(S)': u32 |
980 | 378..379 'S': S | 1016 | 378..379 'S': S |
981 | 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 | 1017 | 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 |
982 | 386..411 '<F as ...32>(S)': u32 | 1018 | 386..411 '<F as ...32>(S)': u32 |
983 | 409..410 'S': S | 1019 | 409..410 'S': S |
984 | 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} | 1020 | 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} |
985 | 418..424 'foo(S)': {unknown} | 1021 | 418..424 'foo(S)': {unknown} |
986 | 422..423 'S': S | 1022 | 422..423 'S': S |
987 | 430..440 'foo::<u32>': fn foo<u32>(S) -> u32 | 1023 | 430..440 'foo::<u32>': fn foo<u32>(S) -> u32 |
988 | 430..443 'foo::<u32>(S)': u32 | 1024 | 430..443 'foo::<u32>(S)': u32 |
989 | 441..442 'S': S | 1025 | 441..442 'S': S |
990 | 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32 | 1026 | 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32 |
991 | 449..467 'foo::<...32>(S)': u32 | 1027 | 449..467 'foo::<...32>(S)': u32 |
992 | 465..466 'S': S | 1028 | 465..466 'S': S |
993 | "### | 1029 | "#]], |
994 | ); | 1030 | ); |
995 | } | 1031 | } |
996 | 1032 | ||
997 | #[test] | 1033 | #[test] |
998 | fn argument_impl_trait_type_args_2() { | 1034 | fn argument_impl_trait_type_args_2() { |
999 | assert_snapshot!( | 1035 | check_infer_with_mismatches( |
1000 | infer_with_mismatches(r#" | 1036 | r#" |
1001 | trait Trait {} | 1037 | trait Trait {} |
1002 | struct S; | 1038 | struct S; |
1003 | impl Trait for S {} | 1039 | impl Trait for S {} |
1004 | struct F<T>; | 1040 | struct F<T>; |
1005 | impl<T> F<T> { | 1041 | impl<T> F<T> { |
1006 | fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } | 1042 | fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } |
1007 | } | 1043 | } |
1008 | 1044 | ||
1009 | fn test() { | 1045 | fn test() { |
1010 | F.foo(S); | 1046 | F.foo(S); |
1011 | F::<u32>.foo(S); | 1047 | F::<u32>.foo(S); |
1012 | F::<u32>.foo::<i32>(S); | 1048 | F::<u32>.foo::<i32>(S); |
1013 | F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored | 1049 | F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored |
1014 | } | 1050 | } |
1015 | "#, true), | 1051 | "#, |
1016 | @r###" | 1052 | expect![[r#" |
1017 | 87..91 'self': F<T> | 1053 | 87..91 'self': F<T> |
1018 | 93..94 'x': impl Trait | 1054 | 93..94 'x': impl Trait |
1019 | 118..129 '{ loop {} }': (T, U) | 1055 | 118..129 '{ loop {} }': (T, U) |
1020 | 120..127 'loop {}': ! | 1056 | 120..127 'loop {}': ! |
1021 | 125..127 '{}': () | 1057 | 125..127 '{}': () |
1022 | 143..283 '{ ...ored }': () | 1058 | 143..283 '{ ...ored }': () |
1023 | 149..150 'F': F<{unknown}> | 1059 | 149..150 'F': F<{unknown}> |
1024 | 149..157 'F.foo(S)': ({unknown}, {unknown}) | 1060 | 149..157 'F.foo(S)': ({unknown}, {unknown}) |
1025 | 155..156 'S': S | 1061 | 155..156 'S': S |
1026 | 163..171 'F::<u32>': F<u32> | 1062 | 163..171 'F::<u32>': F<u32> |
1027 | 163..178 'F::<u32>.foo(S)': (u32, {unknown}) | 1063 | 163..178 'F::<u32>.foo(S)': (u32, {unknown}) |
1028 | 176..177 'S': S | 1064 | 176..177 'S': S |
1029 | 184..192 'F::<u32>': F<u32> | 1065 | 184..192 'F::<u32>': F<u32> |
1030 | 184..206 'F::<u3...32>(S)': (u32, i32) | 1066 | 184..206 'F::<u3...32>(S)': (u32, i32) |
1031 | 204..205 'S': S | 1067 | 204..205 'S': S |
1032 | 212..220 'F::<u32>': F<u32> | 1068 | 212..220 'F::<u32>': F<u32> |
1033 | 212..239 'F::<u3...32>(S)': (u32, i32) | 1069 | 212..239 'F::<u3...32>(S)': (u32, i32) |
1034 | 237..238 'S': S | 1070 | 237..238 'S': S |
1035 | "### | 1071 | "#]], |
1036 | ); | 1072 | ); |
1037 | } | 1073 | } |
1038 | 1074 | ||
1039 | #[test] | 1075 | #[test] |
1040 | fn argument_impl_trait_to_fn_pointer() { | 1076 | fn argument_impl_trait_to_fn_pointer() { |
1041 | assert_snapshot!( | 1077 | check_infer_with_mismatches( |
1042 | infer_with_mismatches(r#" | 1078 | r#" |
1043 | trait Trait {} | 1079 | trait Trait {} |
1044 | fn foo(x: impl Trait) { loop {} } | 1080 | fn foo(x: impl Trait) { loop {} } |
1045 | struct S; | 1081 | struct S; |
1046 | impl Trait for S {} | 1082 | impl Trait for S {} |
1047 | 1083 | ||
1048 | fn test() { | 1084 | fn test() { |
1049 | let f: fn(S) -> () = foo; | 1085 | let f: fn(S) -> () = foo; |
1050 | } | 1086 | } |
1051 | "#, true), | 1087 | "#, |
1052 | @r###" | 1088 | expect![[r#" |
1053 | 22..23 'x': impl Trait | 1089 | 22..23 'x': impl Trait |
1054 | 37..48 '{ loop {} }': () | 1090 | 37..48 '{ loop {} }': () |
1055 | 39..46 'loop {}': ! | 1091 | 39..46 'loop {}': ! |
1056 | 44..46 '{}': () | 1092 | 44..46 '{}': () |
1057 | 90..123 '{ ...foo; }': () | 1093 | 90..123 '{ ...foo; }': () |
1058 | 100..101 'f': fn(S) | 1094 | 100..101 'f': fn(S) |
1059 | 117..120 'foo': fn foo(S) | 1095 | 117..120 'foo': fn foo(S) |
1060 | "### | 1096 | "#]], |
1061 | ); | 1097 | ); |
1062 | } | 1098 | } |
1063 | 1099 | ||
1064 | #[test] | 1100 | #[test] |
1065 | fn impl_trait() { | 1101 | fn impl_trait() { |
1066 | assert_snapshot!( | 1102 | check_infer( |
1067 | infer(r#" | 1103 | r#" |
1068 | trait Trait<T> { | 1104 | trait Trait<T> { |
1069 | fn foo(&self) -> T; | 1105 | fn foo(&self) -> T; |
1070 | fn foo2(&self) -> i64; | 1106 | fn foo2(&self) -> i64; |
1071 | } | 1107 | } |
1072 | fn bar() -> impl Trait<u64> {} | 1108 | fn bar() -> impl Trait<u64> {} |
1073 | 1109 | ||
1074 | fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { | 1110 | fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { |
1075 | x; | 1111 | x; |
1076 | y; | 1112 | y; |
1077 | let z = bar(); | 1113 | let z = bar(); |
1078 | x.foo(); | 1114 | x.foo(); |
1079 | y.foo(); | 1115 | y.foo(); |
1080 | z.foo(); | 1116 | z.foo(); |
1081 | x.foo2(); | 1117 | x.foo2(); |
1082 | y.foo2(); | 1118 | y.foo2(); |
1083 | z.foo2(); | 1119 | z.foo2(); |
1084 | } | 1120 | } |
1085 | "#), | 1121 | "#, |
1086 | @r###" | 1122 | expect![[r#" |
1087 | 29..33 'self': &Self | 1123 | 29..33 'self': &Self |
1088 | 54..58 'self': &Self | 1124 | 54..58 'self': &Self |
1089 | 98..100 '{}': () | 1125 | 98..100 '{}': () |
1090 | 110..111 'x': impl Trait<u64> | 1126 | 110..111 'x': impl Trait<u64> |
1091 | 130..131 'y': &impl Trait<u64> | 1127 | 130..131 'y': &impl Trait<u64> |
1092 | 151..268 '{ ...2(); }': () | 1128 | 151..268 '{ ...2(); }': () |
1093 | 157..158 'x': impl Trait<u64> | 1129 | 157..158 'x': impl Trait<u64> |
1094 | 164..165 'y': &impl Trait<u64> | 1130 | 164..165 'y': &impl Trait<u64> |
1095 | 175..176 'z': impl Trait<u64> | 1131 | 175..176 'z': impl Trait<u64> |
1096 | 179..182 'bar': fn bar() -> impl Trait<u64> | 1132 | 179..182 'bar': fn bar() -> impl Trait<u64> |
1097 | 179..184 'bar()': impl Trait<u64> | 1133 | 179..184 'bar()': impl Trait<u64> |
1098 | 190..191 'x': impl Trait<u64> | 1134 | 190..191 'x': impl Trait<u64> |
1099 | 190..197 'x.foo()': u64 | 1135 | 190..197 'x.foo()': u64 |
1100 | 203..204 'y': &impl Trait<u64> | 1136 | 203..204 'y': &impl Trait<u64> |
1101 | 203..210 'y.foo()': u64 | 1137 | 203..210 'y.foo()': u64 |
1102 | 216..217 'z': impl Trait<u64> | 1138 | 216..217 'z': impl Trait<u64> |
1103 | 216..223 'z.foo()': u64 | 1139 | 216..223 'z.foo()': u64 |
1104 | 229..230 'x': impl Trait<u64> | 1140 | 229..230 'x': impl Trait<u64> |
1105 | 229..237 'x.foo2()': i64 | 1141 | 229..237 'x.foo2()': i64 |
1106 | 243..244 'y': &impl Trait<u64> | 1142 | 243..244 'y': &impl Trait<u64> |
1107 | 243..251 'y.foo2()': i64 | 1143 | 243..251 'y.foo2()': i64 |
1108 | 257..258 'z': impl Trait<u64> | 1144 | 257..258 'z': impl Trait<u64> |
1109 | 257..265 'z.foo2()': i64 | 1145 | 257..265 'z.foo2()': i64 |
1110 | "### | 1146 | "#]], |
1111 | ); | 1147 | ); |
1112 | } | 1148 | } |
1113 | 1149 | ||
1114 | #[test] | 1150 | #[test] |
1115 | fn simple_return_pos_impl_trait() { | 1151 | fn simple_return_pos_impl_trait() { |
1116 | mark::check!(lower_rpit); | 1152 | mark::check!(lower_rpit); |
1117 | assert_snapshot!( | 1153 | check_infer( |
1118 | infer(r#" | 1154 | r#" |
1119 | trait Trait<T> { | 1155 | trait Trait<T> { |
1120 | fn foo(&self) -> T; | 1156 | fn foo(&self) -> T; |
1121 | } | 1157 | } |
1122 | fn bar() -> impl Trait<u64> { loop {} } | 1158 | fn bar() -> impl Trait<u64> { loop {} } |
1123 | 1159 | ||
1124 | fn test() { | 1160 | fn test() { |
1125 | let a = bar(); | 1161 | let a = bar(); |
1126 | a.foo(); | 1162 | a.foo(); |
1127 | } | 1163 | } |
1128 | "#), | 1164 | "#, |
1129 | @r###" | 1165 | expect![[r#" |
1130 | 29..33 'self': &Self | 1166 | 29..33 'self': &Self |
1131 | 71..82 '{ loop {} }': ! | 1167 | 71..82 '{ loop {} }': ! |
1132 | 73..80 'loop {}': ! | 1168 | 73..80 'loop {}': ! |
1133 | 78..80 '{}': () | 1169 | 78..80 '{}': () |
1134 | 94..129 '{ ...o(); }': () | 1170 | 94..129 '{ ...o(); }': () |
1135 | 104..105 'a': impl Trait<u64> | 1171 | 104..105 'a': impl Trait<u64> |
1136 | 108..111 'bar': fn bar() -> impl Trait<u64> | 1172 | 108..111 'bar': fn bar() -> impl Trait<u64> |
1137 | 108..113 'bar()': impl Trait<u64> | 1173 | 108..113 'bar()': impl Trait<u64> |
1138 | 119..120 'a': impl Trait<u64> | 1174 | 119..120 'a': impl Trait<u64> |
1139 | 119..126 'a.foo()': u64 | 1175 | 119..126 'a.foo()': u64 |
1140 | "### | 1176 | "#]], |
1141 | ); | 1177 | ); |
1142 | } | 1178 | } |
1143 | 1179 | ||
1144 | #[test] | 1180 | #[test] |
1145 | fn more_return_pos_impl_trait() { | 1181 | fn more_return_pos_impl_trait() { |
1146 | assert_snapshot!( | 1182 | check_infer( |
1147 | infer(r#" | 1183 | r#" |
1148 | trait Iterator { | 1184 | trait Iterator { |
1149 | type Item; | 1185 | type Item; |
1150 | fn next(&mut self) -> Self::Item; | 1186 | fn next(&mut self) -> Self::Item; |
1151 | } | 1187 | } |
1152 | trait Trait<T> { | 1188 | trait Trait<T> { |
1153 | fn foo(&self) -> T; | 1189 | fn foo(&self) -> T; |
1154 | } | 1190 | } |
1155 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | 1191 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } |
1156 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } | 1192 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } |
1157 | 1193 | ||
1158 | fn test() { | 1194 | fn test() { |
1159 | let (a, b) = bar(); | 1195 | let (a, b) = bar(); |
1160 | a.next().foo(); | 1196 | a.next().foo(); |
1161 | b.foo(); | 1197 | b.foo(); |
1162 | let (c, d) = baz(1u128); | 1198 | let (c, d) = baz(1u128); |
1163 | c.next().foo(); | 1199 | c.next().foo(); |
1164 | d.foo(); | 1200 | d.foo(); |
1165 | } | 1201 | } |
1166 | "#), | 1202 | "#, |
1167 | @r###" | 1203 | expect![[r#" |
1168 | 49..53 'self': &mut Self | 1204 | 49..53 'self': &mut Self |
1169 | 101..105 'self': &Self | 1205 | 101..105 'self': &Self |
1170 | 184..195 '{ loop {} }': ({unknown}, {unknown}) | 1206 | 184..195 '{ loop {} }': ({unknown}, {unknown}) |
1171 | 186..193 'loop {}': ! | 1207 | 186..193 'loop {}': ! |
1172 | 191..193 '{}': () | 1208 | 191..193 '{}': () |
1173 | 206..207 't': T | 1209 | 206..207 't': T |
1174 | 268..279 '{ loop {} }': ({unknown}, {unknown}) | 1210 | 268..279 '{ loop {} }': ({unknown}, {unknown}) |
1175 | 270..277 'loop {}': ! | 1211 | 270..277 'loop {}': ! |
1176 | 275..277 '{}': () | 1212 | 275..277 '{}': () |
1177 | 291..413 '{ ...o(); }': () | 1213 | 291..413 '{ ...o(); }': () |
1178 | 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1214 | 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1179 | 302..303 'a': impl Iterator<Item = impl Trait<u32>> | 1215 | 302..303 'a': impl Iterator<Item = impl Trait<u32>> |
1180 | 305..306 'b': impl Trait<u64> | 1216 | 305..306 'b': impl Trait<u64> |
1181 | 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1217 | 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1182 | 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1218 | 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1183 | 321..322 'a': impl Iterator<Item = impl Trait<u32>> | 1219 | 321..322 'a': impl Iterator<Item = impl Trait<u32>> |
1184 | 321..329 'a.next()': impl Trait<u32> | 1220 | 321..329 'a.next()': impl Trait<u32> |
1185 | 321..335 'a.next().foo()': u32 | 1221 | 321..335 'a.next().foo()': u32 |
1186 | 341..342 'b': impl Trait<u64> | 1222 | 341..342 'b': impl Trait<u64> |
1187 | 341..348 'b.foo()': u64 | 1223 | 341..348 'b.foo()': u64 |
1188 | 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1224 | 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1189 | 359..360 'c': impl Iterator<Item = impl Trait<u128>> | 1225 | 359..360 'c': impl Iterator<Item = impl Trait<u128>> |
1190 | 362..363 'd': impl Trait<u128> | 1226 | 362..363 'd': impl Trait<u128> |
1191 | 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1227 | 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1192 | 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1228 | 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1193 | 371..376 '1u128': u128 | 1229 | 371..376 '1u128': u128 |
1194 | 383..384 'c': impl Iterator<Item = impl Trait<u128>> | 1230 | 383..384 'c': impl Iterator<Item = impl Trait<u128>> |
1195 | 383..391 'c.next()': impl Trait<u128> | 1231 | 383..391 'c.next()': impl Trait<u128> |
1196 | 383..397 'c.next().foo()': u128 | 1232 | 383..397 'c.next().foo()': u128 |
1197 | 403..404 'd': impl Trait<u128> | 1233 | 403..404 'd': impl Trait<u128> |
1198 | 403..410 'd.foo()': u128 | 1234 | 403..410 'd.foo()': u128 |
1199 | "### | 1235 | "#]], |
1200 | ); | 1236 | ); |
1201 | } | 1237 | } |
1202 | 1238 | ||
1203 | #[test] | 1239 | #[test] |
1204 | fn dyn_trait() { | 1240 | fn dyn_trait() { |
1205 | assert_snapshot!( | 1241 | check_infer( |
1206 | infer(r#" | 1242 | r#" |
1207 | trait Trait<T> { | 1243 | trait Trait<T> { |
1208 | fn foo(&self) -> T; | 1244 | fn foo(&self) -> T; |
1209 | fn foo2(&self) -> i64; | 1245 | fn foo2(&self) -> i64; |
1210 | } | 1246 | } |
1211 | fn bar() -> dyn Trait<u64> {} | 1247 | fn bar() -> dyn Trait<u64> {} |
1212 | 1248 | ||
1213 | fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { | 1249 | fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { |
1214 | x; | 1250 | x; |
1215 | y; | 1251 | y; |
1216 | let z = bar(); | 1252 | let z = bar(); |
1217 | x.foo(); | 1253 | x.foo(); |
1218 | y.foo(); | 1254 | y.foo(); |
1219 | z.foo(); | 1255 | z.foo(); |
1220 | x.foo2(); | 1256 | x.foo2(); |
1221 | y.foo2(); | 1257 | y.foo2(); |
1222 | z.foo2(); | 1258 | z.foo2(); |
1223 | } | 1259 | } |
1224 | "#), | 1260 | "#, |
1225 | @r###" | 1261 | expect![[r#" |
1226 | 29..33 'self': &Self | 1262 | 29..33 'self': &Self |
1227 | 54..58 'self': &Self | 1263 | 54..58 'self': &Self |
1228 | 97..99 '{}': () | 1264 | 97..99 '{}': () |
1229 | 109..110 'x': dyn Trait<u64> | 1265 | 109..110 'x': dyn Trait<u64> |
1230 | 128..129 'y': &dyn Trait<u64> | 1266 | 128..129 'y': &dyn Trait<u64> |
1231 | 148..265 '{ ...2(); }': () | 1267 | 148..265 '{ ...2(); }': () |
1232 | 154..155 'x': dyn Trait<u64> | 1268 | 154..155 'x': dyn Trait<u64> |
1233 | 161..162 'y': &dyn Trait<u64> | 1269 | 161..162 'y': &dyn Trait<u64> |
1234 | 172..173 'z': dyn Trait<u64> | 1270 | 172..173 'z': dyn Trait<u64> |
1235 | 176..179 'bar': fn bar() -> dyn Trait<u64> | 1271 | 176..179 'bar': fn bar() -> dyn Trait<u64> |
1236 | 176..181 'bar()': dyn Trait<u64> | 1272 | 176..181 'bar()': dyn Trait<u64> |
1237 | 187..188 'x': dyn Trait<u64> | 1273 | 187..188 'x': dyn Trait<u64> |
1238 | 187..194 'x.foo()': u64 | 1274 | 187..194 'x.foo()': u64 |
1239 | 200..201 'y': &dyn Trait<u64> | 1275 | 200..201 'y': &dyn Trait<u64> |
1240 | 200..207 'y.foo()': u64 | 1276 | 200..207 'y.foo()': u64 |
1241 | 213..214 'z': dyn Trait<u64> | 1277 | 213..214 'z': dyn Trait<u64> |
1242 | 213..220 'z.foo()': u64 | 1278 | 213..220 'z.foo()': u64 |
1243 | 226..227 'x': dyn Trait<u64> | 1279 | 226..227 'x': dyn Trait<u64> |
1244 | 226..234 'x.foo2()': i64 | 1280 | 226..234 'x.foo2()': i64 |
1245 | 240..241 'y': &dyn Trait<u64> | 1281 | 240..241 'y': &dyn Trait<u64> |
1246 | 240..248 'y.foo2()': i64 | 1282 | 240..248 'y.foo2()': i64 |
1247 | 254..255 'z': dyn Trait<u64> | 1283 | 254..255 'z': dyn Trait<u64> |
1248 | 254..262 'z.foo2()': i64 | 1284 | 254..262 'z.foo2()': i64 |
1249 | "### | 1285 | "#]], |
1250 | ); | 1286 | ); |
1251 | } | 1287 | } |
1252 | 1288 | ||
1253 | #[test] | 1289 | #[test] |
1254 | fn dyn_trait_in_impl() { | 1290 | fn dyn_trait_in_impl() { |
1255 | assert_snapshot!( | 1291 | check_infer( |
1256 | infer(r#" | 1292 | r#" |
1257 | trait Trait<T, U> { | 1293 | trait Trait<T, U> { |
1258 | fn foo(&self) -> (T, U); | 1294 | fn foo(&self) -> (T, U); |
1259 | } | 1295 | } |
1260 | struct S<T, U> {} | 1296 | struct S<T, U> {} |
1261 | impl<T, U> S<T, U> { | 1297 | impl<T, U> S<T, U> { |
1262 | fn bar(&self) -> &dyn Trait<T, U> { loop {} } | 1298 | fn bar(&self) -> &dyn Trait<T, U> { loop {} } |
1263 | } | 1299 | } |
1264 | trait Trait2<T, U> { | 1300 | trait Trait2<T, U> { |
1265 | fn baz(&self) -> (T, U); | 1301 | fn baz(&self) -> (T, U); |
1266 | } | 1302 | } |
1267 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } | 1303 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } |
1268 | 1304 | ||
1269 | fn test(s: S<u32, i32>) { | 1305 | fn test(s: S<u32, i32>) { |
1270 | s.bar().baz(); | 1306 | s.bar().baz(); |
1271 | } | 1307 | } |
1272 | "#), | 1308 | "#, |
1273 | @r###" | 1309 | expect![[r#" |
1274 | 32..36 'self': &Self | 1310 | 32..36 'self': &Self |
1275 | 102..106 'self': &S<T, U> | 1311 | 102..106 'self': &S<T, U> |
1276 | 128..139 '{ loop {} }': &dyn Trait<T, U> | 1312 | 128..139 '{ loop {} }': &dyn Trait<T, U> |
1277 | 130..137 'loop {}': ! | 1313 | 130..137 'loop {}': ! |
1278 | 135..137 '{}': () | 1314 | 135..137 '{}': () |
1279 | 175..179 'self': &Self | 1315 | 175..179 'self': &Self |
1280 | 251..252 's': S<u32, i32> | 1316 | 251..252 's': S<u32, i32> |
1281 | 267..289 '{ ...z(); }': () | 1317 | 267..289 '{ ...z(); }': () |
1282 | 273..274 's': S<u32, i32> | 1318 | 273..274 's': S<u32, i32> |
1283 | 273..280 's.bar()': &dyn Trait<u32, i32> | 1319 | 273..280 's.bar()': &dyn Trait<u32, i32> |
1284 | 273..286 's.bar().baz()': (u32, i32) | 1320 | 273..286 's.bar().baz()': (u32, i32) |
1285 | "### | 1321 | "#]], |
1286 | ); | 1322 | ); |
1287 | } | 1323 | } |
1288 | 1324 | ||
1289 | #[test] | 1325 | #[test] |
1290 | fn dyn_trait_bare() { | 1326 | fn dyn_trait_bare() { |
1291 | assert_snapshot!( | 1327 | check_infer( |
1292 | infer(r#" | 1328 | r#" |
1293 | trait Trait { | 1329 | trait Trait { |
1294 | fn foo(&self) -> u64; | 1330 | fn foo(&self) -> u64; |
1295 | } | 1331 | } |
1296 | fn bar() -> Trait {} | 1332 | fn bar() -> Trait {} |
1297 | 1333 | ||
1298 | fn test(x: Trait, y: &Trait) -> u64 { | 1334 | fn test(x: Trait, y: &Trait) -> u64 { |
1299 | x; | 1335 | x; |
1300 | y; | 1336 | y; |
1301 | let z = bar(); | 1337 | let z = bar(); |
1302 | x.foo(); | 1338 | x.foo(); |
1303 | y.foo(); | 1339 | y.foo(); |
1304 | z.foo(); | 1340 | z.foo(); |
1305 | } | 1341 | } |
1306 | "#), | 1342 | "#, |
1307 | @r###" | 1343 | expect![[r#" |
1308 | 26..30 'self': &Self | 1344 | 26..30 'self': &Self |
1309 | 60..62 '{}': () | 1345 | 60..62 '{}': () |
1310 | 72..73 'x': dyn Trait | 1346 | 72..73 'x': dyn Trait |
1311 | 82..83 'y': &dyn Trait | 1347 | 82..83 'y': &dyn Trait |
1312 | 100..175 '{ ...o(); }': () | 1348 | 100..175 '{ ...o(); }': () |
1313 | 106..107 'x': dyn Trait | 1349 | 106..107 'x': dyn Trait |
1314 | 113..114 'y': &dyn Trait | 1350 | 113..114 'y': &dyn Trait |
1315 | 124..125 'z': dyn Trait | 1351 | 124..125 'z': dyn Trait |
1316 | 128..131 'bar': fn bar() -> dyn Trait | 1352 | 128..131 'bar': fn bar() -> dyn Trait |
1317 | 128..133 'bar()': dyn Trait | 1353 | 128..133 'bar()': dyn Trait |
1318 | 139..140 'x': dyn Trait | 1354 | 139..140 'x': dyn Trait |
1319 | 139..146 'x.foo()': u64 | 1355 | 139..146 'x.foo()': u64 |
1320 | 152..153 'y': &dyn Trait | 1356 | 152..153 'y': &dyn Trait |
1321 | 152..159 'y.foo()': u64 | 1357 | 152..159 'y.foo()': u64 |
1322 | 165..166 'z': dyn Trait | 1358 | 165..166 'z': dyn Trait |
1323 | 165..172 'z.foo()': u64 | 1359 | 165..172 'z.foo()': u64 |
1324 | "### | 1360 | "#]], |
1325 | ); | 1361 | ); |
1326 | } | 1362 | } |
1327 | 1363 | ||
1328 | #[test] | 1364 | #[test] |
1329 | fn weird_bounds() { | 1365 | fn weird_bounds() { |
1330 | assert_snapshot!( | 1366 | check_infer( |
1331 | infer(r#" | 1367 | r#" |
1332 | trait Trait {} | 1368 | trait Trait {} |
1333 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { | 1369 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} |
1334 | } | 1370 | "#, |
1335 | "#), | 1371 | expect![[r#" |
1336 | @r###" | 1372 | 23..24 'a': impl Trait + {error} |
1337 | 23..24 'a': impl Trait + {error} | 1373 | 50..51 'b': impl {error} |
1338 | 50..51 'b': impl {error} | 1374 | 69..70 'c': impl Trait |
1339 | 69..70 'c': impl Trait | 1375 | 86..87 'd': impl {error} |
1340 | 86..87 'd': impl {error} | 1376 | 107..108 'e': impl {error} |
1341 | 107..108 'e': impl {error} | 1377 | 123..124 'f': impl Trait + {error} |
1342 | 123..124 'f': impl Trait + {error} | 1378 | 147..149 '{}': () |
1343 | 147..150 '{ }': () | 1379 | "#]], |
1344 | "### | ||
1345 | ); | 1380 | ); |
1346 | } | 1381 | } |
1347 | 1382 | ||
@@ -1363,66 +1398,66 @@ fn test(x: (impl Trait + UnknownTrait)) { | |||
1363 | 1398 | ||
1364 | #[test] | 1399 | #[test] |
1365 | fn assoc_type_bindings() { | 1400 | fn assoc_type_bindings() { |
1366 | assert_snapshot!( | 1401 | check_infer( |
1367 | infer(r#" | 1402 | r#" |
1368 | trait Trait { | 1403 | trait Trait { |
1369 | type Type; | 1404 | type Type; |
1370 | } | 1405 | } |
1371 | |||
1372 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} | ||
1373 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | ||
1374 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | ||
1375 | 1406 | ||
1376 | struct S<T>; | 1407 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} |
1377 | impl<T> Trait for S<T> { type Type = T; } | 1408 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} |
1378 | 1409 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | |
1379 | fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { | 1410 | |
1380 | get(x); | 1411 | struct S<T>; |
1381 | get2(x); | 1412 | impl<T> Trait for S<T> { type Type = T; } |
1382 | get(y); | 1413 | |
1383 | get2(y); | 1414 | fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { |
1384 | get(set(S)); | 1415 | get(x); |
1385 | get2(set(S)); | 1416 | get2(x); |
1386 | get2(S::<str>); | 1417 | get(y); |
1387 | } | 1418 | get2(y); |
1388 | "#), | 1419 | get(set(S)); |
1389 | @r###" | 1420 | get2(set(S)); |
1390 | 49..50 't': T | 1421 | get2(S::<str>); |
1391 | 77..79 '{}': () | 1422 | } |
1392 | 111..112 't': T | 1423 | "#, |
1393 | 122..124 '{}': () | 1424 | expect![[r#" |
1394 | 154..155 't': T | 1425 | 49..50 't': T |
1395 | 165..168 '{t}': T | 1426 | 77..79 '{}': () |
1396 | 166..167 't': T | 1427 | 111..112 't': T |
1397 | 256..257 'x': T | 1428 | 122..124 '{}': () |
1398 | 262..263 'y': impl Trait<Type = i64> | 1429 | 154..155 't': T |
1399 | 289..397 '{ ...r>); }': () | 1430 | 165..168 '{t}': T |
1400 | 295..298 'get': fn get<T>(T) -> <T as Trait>::Type | 1431 | 166..167 't': T |
1401 | 295..301 'get(x)': u32 | 1432 | 256..257 'x': T |
1402 | 299..300 'x': T | 1433 | 262..263 'y': impl Trait<Type = i64> |
1403 | 307..311 'get2': fn get2<u32, T>(T) -> u32 | 1434 | 289..397 '{ ...r>); }': () |
1404 | 307..314 'get2(x)': u32 | 1435 | 295..298 'get': fn get<T>(T) -> <T as Trait>::Type |
1405 | 312..313 'x': T | 1436 | 295..301 'get(x)': u32 |
1406 | 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type | 1437 | 299..300 'x': T |
1407 | 320..326 'get(y)': i64 | 1438 | 307..311 'get2': fn get2<u32, T>(T) -> u32 |
1408 | 324..325 'y': impl Trait<Type = i64> | 1439 | 307..314 'get2(x)': u32 |
1409 | 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 | 1440 | 312..313 'x': T |
1410 | 332..339 'get2(y)': i64 | 1441 | 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type |
1411 | 337..338 'y': impl Trait<Type = i64> | 1442 | 320..326 'get(y)': i64 |
1412 | 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type | 1443 | 324..325 'y': impl Trait<Type = i64> |
1413 | 345..356 'get(set(S))': u64 | 1444 | 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 |
1414 | 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1445 | 332..339 'get2(y)': i64 |
1415 | 349..355 'set(S)': S<u64> | 1446 | 337..338 'y': impl Trait<Type = i64> |
1416 | 353..354 'S': S<u64> | 1447 | 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type |
1417 | 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 | 1448 | 345..356 'get(set(S))': u64 |
1418 | 362..374 'get2(set(S))': u64 | 1449 | 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1419 | 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1450 | 349..355 'set(S)': S<u64> |
1420 | 367..373 'set(S)': S<u64> | 1451 | 353..354 'S': S<u64> |
1421 | 371..372 'S': S<u64> | 1452 | 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 |
1422 | 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str | 1453 | 362..374 'get2(set(S))': u64 |
1423 | 380..394 'get2(S::<str>)': str | 1454 | 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1424 | 385..393 'S::<str>': S<str> | 1455 | 367..373 'set(S)': S<u64> |
1425 | "### | 1456 | 371..372 'S': S<u64> |
1457 | 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str | ||
1458 | 380..394 'get2(S::<str>)': str | ||
1459 | 385..393 'S::<str>': S<str> | ||
1460 | "#]], | ||
1426 | ); | 1461 | ); |
1427 | } | 1462 | } |
1428 | 1463 | ||
@@ -1470,27 +1505,27 @@ mod iter { | |||
1470 | 1505 | ||
1471 | #[test] | 1506 | #[test] |
1472 | fn projection_eq_within_chalk() { | 1507 | fn projection_eq_within_chalk() { |
1473 | assert_snapshot!( | 1508 | check_infer( |
1474 | infer(r#" | 1509 | r#" |
1475 | trait Trait1 { | 1510 | trait Trait1 { |
1476 | type Type; | 1511 | type Type; |
1477 | } | 1512 | } |
1478 | trait Trait2<T> { | 1513 | trait Trait2<T> { |
1479 | fn foo(self) -> T; | 1514 | fn foo(self) -> T; |
1480 | } | 1515 | } |
1481 | impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} | 1516 | impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} |
1482 | 1517 | ||
1483 | fn test<T: Trait1<Type = u32>>(x: T) { | 1518 | fn test<T: Trait1<Type = u32>>(x: T) { |
1484 | x.foo(); | 1519 | x.foo(); |
1485 | } | 1520 | } |
1486 | "#), | 1521 | "#, |
1487 | @r###" | 1522 | expect![[r#" |
1488 | 61..65 'self': Self | 1523 | 61..65 'self': Self |
1489 | 163..164 'x': T | 1524 | 163..164 'x': T |
1490 | 169..185 '{ ...o(); }': () | 1525 | 169..185 '{ ...o(); }': () |
1491 | 175..176 'x': T | 1526 | 175..176 'x': T |
1492 | 175..182 'x.foo()': u32 | 1527 | 175..182 'x.foo()': u32 |
1493 | "### | 1528 | "#]], |
1494 | ); | 1529 | ); |
1495 | } | 1530 | } |
1496 | 1531 | ||
@@ -1513,445 +1548,467 @@ fn test<T: foo::Trait>(x: T) { | |||
1513 | 1548 | ||
1514 | #[test] | 1549 | #[test] |
1515 | fn super_trait_method_resolution() { | 1550 | fn super_trait_method_resolution() { |
1516 | assert_snapshot!( | 1551 | check_infer( |
1517 | infer(r#" | 1552 | r#" |
1518 | mod foo { | 1553 | mod foo { |
1519 | trait SuperTrait { | 1554 | trait SuperTrait { |
1520 | fn foo(&self) -> u32 {} | 1555 | fn foo(&self) -> u32 {} |
1521 | } | 1556 | } |
1522 | } | 1557 | } |
1523 | trait Trait1: foo::SuperTrait {} | 1558 | trait Trait1: foo::SuperTrait {} |
1524 | trait Trait2 where Self: foo::SuperTrait {} | 1559 | trait Trait2 where Self: foo::SuperTrait {} |
1525 | 1560 | ||
1526 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { | 1561 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { |
1527 | x.foo(); | 1562 | x.foo(); |
1528 | y.foo(); | 1563 | y.foo(); |
1529 | } | 1564 | } |
1530 | "#), | 1565 | "#, |
1531 | @r###" | 1566 | expect![[r#" |
1532 | 49..53 'self': &Self | 1567 | 49..53 'self': &Self |
1533 | 62..64 '{}': () | 1568 | 62..64 '{}': () |
1534 | 181..182 'x': T | 1569 | 181..182 'x': T |
1535 | 187..188 'y': U | 1570 | 187..188 'y': U |
1536 | 193..222 '{ ...o(); }': () | 1571 | 193..222 '{ ...o(); }': () |
1537 | 199..200 'x': T | 1572 | 199..200 'x': T |
1538 | 199..206 'x.foo()': u32 | 1573 | 199..206 'x.foo()': u32 |
1539 | 212..213 'y': U | 1574 | 212..213 'y': U |
1540 | 212..219 'y.foo()': u32 | 1575 | 212..219 'y.foo()': u32 |
1541 | "### | 1576 | "#]], |
1542 | ); | 1577 | ); |
1543 | } | 1578 | } |
1544 | 1579 | ||
1545 | #[test] | 1580 | #[test] |
1546 | fn super_trait_impl_trait_method_resolution() { | 1581 | fn super_trait_impl_trait_method_resolution() { |
1547 | assert_snapshot!( | 1582 | check_infer( |
1548 | infer(r#" | 1583 | r#" |
1549 | mod foo { | 1584 | mod foo { |
1550 | trait SuperTrait { | 1585 | trait SuperTrait { |
1551 | fn foo(&self) -> u32 {} | 1586 | fn foo(&self) -> u32 {} |
1552 | } | 1587 | } |
1553 | } | 1588 | } |
1554 | trait Trait1: foo::SuperTrait {} | 1589 | trait Trait1: foo::SuperTrait {} |
1555 | 1590 | ||
1556 | fn test(x: &impl Trait1) { | 1591 | fn test(x: &impl Trait1) { |
1557 | x.foo(); | 1592 | x.foo(); |
1558 | } | 1593 | } |
1559 | "#), | 1594 | "#, |
1560 | @r###" | 1595 | expect![[r#" |
1561 | 49..53 'self': &Self | 1596 | 49..53 'self': &Self |
1562 | 62..64 '{}': () | 1597 | 62..64 '{}': () |
1563 | 115..116 'x': &impl Trait1 | 1598 | 115..116 'x': &impl Trait1 |
1564 | 132..148 '{ ...o(); }': () | 1599 | 132..148 '{ ...o(); }': () |
1565 | 138..139 'x': &impl Trait1 | 1600 | 138..139 'x': &impl Trait1 |
1566 | 138..145 'x.foo()': u32 | 1601 | 138..145 'x.foo()': u32 |
1567 | "### | 1602 | "#]], |
1568 | ); | 1603 | ); |
1569 | } | 1604 | } |
1570 | 1605 | ||
1571 | #[test] | 1606 | #[test] |
1572 | fn super_trait_cycle() { | 1607 | fn super_trait_cycle() { |
1573 | // This just needs to not crash | 1608 | // This just needs to not crash |
1574 | assert_snapshot!( | 1609 | check_infer( |
1575 | infer(r#" | 1610 | r#" |
1576 | trait A: B {} | 1611 | trait A: B {} |
1577 | trait B: A {} | 1612 | trait B: A {} |
1578 | 1613 | ||
1579 | fn test<T: A>(x: T) { | 1614 | fn test<T: A>(x: T) { |
1580 | x.foo(); | 1615 | x.foo(); |
1581 | } | 1616 | } |
1582 | "#), | 1617 | "#, |
1583 | @r###" | 1618 | expect![[r#" |
1584 | 43..44 'x': T | 1619 | 43..44 'x': T |
1585 | 49..65 '{ ...o(); }': () | 1620 | 49..65 '{ ...o(); }': () |
1586 | 55..56 'x': T | 1621 | 55..56 'x': T |
1587 | 55..62 'x.foo()': {unknown} | 1622 | 55..62 'x.foo()': {unknown} |
1588 | "### | 1623 | "#]], |
1589 | ); | 1624 | ); |
1590 | } | 1625 | } |
1591 | 1626 | ||
1592 | #[test] | 1627 | #[test] |
1593 | fn super_trait_assoc_type_bounds() { | 1628 | fn super_trait_assoc_type_bounds() { |
1594 | assert_snapshot!( | 1629 | check_infer( |
1595 | infer(r#" | 1630 | r#" |
1596 | trait SuperTrait { type Type; } | 1631 | trait SuperTrait { type Type; } |
1597 | trait Trait where Self: SuperTrait {} | 1632 | trait Trait where Self: SuperTrait {} |
1598 | 1633 | ||
1599 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | 1634 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} |
1600 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | 1635 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} |
1601 | 1636 | ||
1602 | struct S<T>; | 1637 | struct S<T>; |
1603 | impl<T> SuperTrait for S<T> { type Type = T; } | 1638 | impl<T> SuperTrait for S<T> { type Type = T; } |
1604 | impl<T> Trait for S<T> {} | 1639 | impl<T> Trait for S<T> {} |
1605 | 1640 | ||
1606 | fn test() { | 1641 | fn test() { |
1607 | get2(set(S)); | 1642 | get2(set(S)); |
1608 | } | 1643 | } |
1609 | "#), | 1644 | "#, |
1610 | @r###" | 1645 | expect![[r#" |
1611 | 102..103 't': T | 1646 | 102..103 't': T |
1612 | 113..115 '{}': () | 1647 | 113..115 '{}': () |
1613 | 145..146 't': T | 1648 | 145..146 't': T |
1614 | 156..159 '{t}': T | 1649 | 156..159 '{t}': T |
1615 | 157..158 't': T | 1650 | 157..158 't': T |
1616 | 258..279 '{ ...S)); }': () | 1651 | 258..279 '{ ...S)); }': () |
1617 | 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 | 1652 | 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 |
1618 | 264..276 'get2(set(S))': u64 | 1653 | 264..276 'get2(set(S))': u64 |
1619 | 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1654 | 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1620 | 269..275 'set(S)': S<u64> | 1655 | 269..275 'set(S)': S<u64> |
1621 | 273..274 'S': S<u64> | 1656 | 273..274 'S': S<u64> |
1622 | "### | 1657 | "#]], |
1623 | ); | 1658 | ); |
1624 | } | 1659 | } |
1625 | 1660 | ||
1626 | #[test] | 1661 | #[test] |
1627 | fn fn_trait() { | 1662 | fn fn_trait() { |
1628 | assert_snapshot!( | 1663 | check_infer( |
1629 | infer(r#" | 1664 | r#" |
1630 | trait FnOnce<Args> { | 1665 | trait FnOnce<Args> { |
1631 | type Output; | 1666 | type Output; |
1632 | 1667 | ||
1633 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; | 1668 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; |
1634 | } | 1669 | } |
1635 | 1670 | ||
1636 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | 1671 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { |
1637 | f.call_once((1, 2)); | 1672 | f.call_once((1, 2)); |
1638 | } | 1673 | } |
1639 | "#), | 1674 | "#, |
1640 | @r###" | 1675 | expect![[r#" |
1641 | 56..60 'self': Self | 1676 | 56..60 'self': Self |
1642 | 62..66 'args': Args | 1677 | 62..66 'args': Args |
1643 | 149..150 'f': F | 1678 | 149..150 'f': F |
1644 | 155..183 '{ ...2)); }': () | 1679 | 155..183 '{ ...2)); }': () |
1645 | 161..162 'f': F | 1680 | 161..162 'f': F |
1646 | 161..180 'f.call...1, 2))': u128 | 1681 | 161..180 'f.call...1, 2))': u128 |
1647 | 173..179 '(1, 2)': (u32, u64) | 1682 | 173..179 '(1, 2)': (u32, u64) |
1648 | 174..175 '1': u32 | 1683 | 174..175 '1': u32 |
1649 | 177..178 '2': u64 | 1684 | 177..178 '2': u64 |
1650 | "### | 1685 | "#]], |
1651 | ); | 1686 | ); |
1652 | } | 1687 | } |
1653 | 1688 | ||
1654 | #[test] | 1689 | #[test] |
1655 | fn fn_ptr_and_item() { | 1690 | fn fn_ptr_and_item() { |
1656 | assert_snapshot!( | 1691 | check_infer( |
1657 | infer(r#" | 1692 | r#" |
1658 | #[lang="fn_once"] | 1693 | #[lang="fn_once"] |
1659 | trait FnOnce<Args> { | 1694 | trait FnOnce<Args> { |
1660 | type Output; | 1695 | type Output; |
1661 | 1696 | ||
1662 | fn call_once(self, args: Args) -> Self::Output; | 1697 | fn call_once(self, args: Args) -> Self::Output; |
1663 | } | 1698 | } |
1664 | 1699 | ||
1665 | trait Foo<T> { | 1700 | trait Foo<T> { |
1666 | fn foo(&self) -> T; | 1701 | fn foo(&self) -> T; |
1667 | } | 1702 | } |
1668 | 1703 | ||
1669 | struct Bar<T>(T); | 1704 | struct Bar<T>(T); |
1670 | 1705 | ||
1671 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { | 1706 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { |
1672 | fn foo(&self) -> (A1, R) {} | 1707 | fn foo(&self) -> (A1, R) {} |
1673 | } | 1708 | } |
1674 | 1709 | ||
1675 | enum Opt<T> { None, Some(T) } | 1710 | enum Opt<T> { None, Some(T) } |
1676 | impl<T> Opt<T> { | 1711 | impl<T> Opt<T> { |
1677 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} | 1712 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} |
1678 | } | 1713 | } |
1679 | 1714 | ||
1680 | fn test() { | 1715 | fn test() { |
1681 | let bar: Bar<fn(u8) -> u32>; | 1716 | let bar: Bar<fn(u8) -> u32>; |
1682 | bar.foo(); | 1717 | bar.foo(); |
1683 | 1718 | ||
1684 | let opt: Opt<u8>; | 1719 | let opt: Opt<u8>; |
1685 | let f: fn(u8) -> u32; | 1720 | let f: fn(u8) -> u32; |
1686 | opt.map(f); | 1721 | opt.map(f); |
1687 | } | 1722 | } |
1688 | "#), | 1723 | "#, |
1689 | @r###" | 1724 | expect![[r#" |
1690 | 74..78 'self': Self | 1725 | 74..78 'self': Self |
1691 | 80..84 'args': Args | 1726 | 80..84 'args': Args |
1692 | 139..143 'self': &Self | 1727 | 139..143 'self': &Self |
1693 | 243..247 'self': &Bar<F> | 1728 | 243..247 'self': &Bar<F> |
1694 | 260..262 '{}': () | 1729 | 260..262 '{}': () |
1695 | 346..350 'self': Opt<T> | 1730 | 346..350 'self': Opt<T> |
1696 | 352..353 'f': F | 1731 | 352..353 'f': F |
1697 | 368..370 '{}': () | 1732 | 368..370 '{}': () |
1698 | 384..500 '{ ...(f); }': () | 1733 | 384..500 '{ ...(f); }': () |
1699 | 394..397 'bar': Bar<fn(u8) -> u32> | 1734 | 394..397 'bar': Bar<fn(u8) -> u32> |
1700 | 423..426 'bar': Bar<fn(u8) -> u32> | 1735 | 423..426 'bar': Bar<fn(u8) -> u32> |
1701 | 423..432 'bar.foo()': (u8, u32) | 1736 | 423..432 'bar.foo()': (u8, u32) |
1702 | 443..446 'opt': Opt<u8> | 1737 | 443..446 'opt': Opt<u8> |
1703 | 465..466 'f': fn(u8) -> u32 | 1738 | 465..466 'f': fn(u8) -> u32 |
1704 | 487..490 'opt': Opt<u8> | 1739 | 487..490 'opt': Opt<u8> |
1705 | 487..497 'opt.map(f)': Opt<u32> | 1740 | 487..497 'opt.map(f)': Opt<u32> |
1706 | 495..496 'f': fn(u8) -> u32 | 1741 | 495..496 'f': fn(u8) -> u32 |
1707 | "### | 1742 | "#]], |
1708 | ); | 1743 | ); |
1709 | } | 1744 | } |
1710 | 1745 | ||
1711 | #[test] | 1746 | #[test] |
1712 | fn fn_trait_deref_with_ty_default() { | 1747 | fn fn_trait_deref_with_ty_default() { |
1713 | assert_snapshot!( | 1748 | check_infer( |
1714 | infer(r#" | 1749 | r#" |
1715 | #[lang = "deref"] | 1750 | #[lang = "deref"] |
1716 | trait Deref { | 1751 | trait Deref { |
1717 | type Target; | 1752 | type Target; |
1718 | 1753 | ||
1719 | fn deref(&self) -> &Self::Target; | 1754 | fn deref(&self) -> &Self::Target; |
1720 | } | 1755 | } |
1721 | 1756 | ||
1722 | #[lang="fn_once"] | 1757 | #[lang="fn_once"] |
1723 | trait FnOnce<Args> { | 1758 | trait FnOnce<Args> { |
1724 | type Output; | 1759 | type Output; |
1725 | 1760 | ||
1726 | fn call_once(self, args: Args) -> Self::Output; | 1761 | fn call_once(self, args: Args) -> Self::Output; |
1727 | } | 1762 | } |
1728 | 1763 | ||
1729 | struct Foo; | 1764 | struct Foo; |
1730 | 1765 | ||
1731 | impl Foo { | 1766 | impl Foo { |
1732 | fn foo(&self) -> usize {} | 1767 | fn foo(&self) -> usize {} |
1733 | } | 1768 | } |
1734 | 1769 | ||
1735 | struct Lazy<T, F = fn() -> T>(F); | 1770 | struct Lazy<T, F = fn() -> T>(F); |
1736 | 1771 | ||
1737 | impl<T, F> Lazy<T, F> { | 1772 | impl<T, F> Lazy<T, F> { |
1738 | pub fn new(f: F) -> Lazy<T, F> {} | 1773 | pub fn new(f: F) -> Lazy<T, F> {} |
1739 | } | 1774 | } |
1740 | 1775 | ||
1741 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { | 1776 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { |
1742 | type Target = T; | 1777 | type Target = T; |
1743 | } | 1778 | } |
1744 | 1779 | ||
1745 | fn test() { | 1780 | fn test() { |
1746 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); | 1781 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); |
1747 | let r1 = lazy1.foo(); | 1782 | let r1 = lazy1.foo(); |
1748 | 1783 | ||
1749 | fn make_foo_fn() -> Foo {} | 1784 | fn make_foo_fn() -> Foo {} |
1750 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; | 1785 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; |
1751 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); | 1786 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); |
1752 | let r2 = lazy2.foo(); | 1787 | let r2 = lazy2.foo(); |
1753 | } | 1788 | } |
1754 | "#), | 1789 | "#, |
1755 | @r###" | 1790 | expect![[r#" |
1756 | 64..68 'self': &Self | 1791 | 64..68 'self': &Self |
1757 | 165..169 'self': Self | 1792 | 165..169 'self': Self |
1758 | 171..175 'args': Args | 1793 | 171..175 'args': Args |
1759 | 239..243 'self': &Foo | 1794 | 239..243 'self': &Foo |
1760 | 254..256 '{}': () | 1795 | 254..256 '{}': () |
1761 | 334..335 'f': F | 1796 | 334..335 'f': F |
1762 | 354..356 '{}': () | 1797 | 354..356 '{}': () |
1763 | 443..689 '{ ...o(); }': () | 1798 | 443..689 '{ ...o(); }': () |
1764 | 453..458 'lazy1': Lazy<Foo, || -> Foo> | 1799 | 453..458 'lazy1': Lazy<Foo, || -> Foo> |
1765 | 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> | 1800 | 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> |
1766 | 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> | 1801 | 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> |
1767 | 485..491 '|| Foo': || -> Foo | 1802 | 485..491 '|| Foo': || -> Foo |
1768 | 488..491 'Foo': Foo | 1803 | 488..491 'Foo': Foo |
1769 | 502..504 'r1': usize | 1804 | 502..504 'r1': usize |
1770 | 507..512 'lazy1': Lazy<Foo, || -> Foo> | 1805 | 507..512 'lazy1': Lazy<Foo, || -> Foo> |
1771 | 507..518 'lazy1.foo()': usize | 1806 | 507..518 'lazy1.foo()': usize |
1772 | 560..575 'make_foo_fn_ptr': fn() -> Foo | 1807 | 560..575 'make_foo_fn_ptr': fn() -> Foo |
1773 | 591..602 'make_foo_fn': fn make_foo_fn() -> Foo | 1808 | 591..602 'make_foo_fn': fn make_foo_fn() -> Foo |
1774 | 612..617 'lazy2': Lazy<Foo, fn() -> Foo> | 1809 | 612..617 'lazy2': Lazy<Foo, fn() -> Foo> |
1775 | 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> | 1810 | 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> |
1776 | 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> | 1811 | 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> |
1777 | 644..659 'make_foo_fn_ptr': fn() -> Foo | 1812 | 644..659 'make_foo_fn_ptr': fn() -> Foo |
1778 | 670..672 'r2': usize | 1813 | 670..672 'r2': usize |
1779 | 675..680 'lazy2': Lazy<Foo, fn() -> Foo> | 1814 | 675..680 'lazy2': Lazy<Foo, fn() -> Foo> |
1780 | 675..686 'lazy2.foo()': usize | 1815 | 675..686 'lazy2.foo()': usize |
1781 | 549..551 '{}': () | 1816 | 549..551 '{}': () |
1782 | "### | 1817 | "#]], |
1783 | ); | 1818 | ); |
1784 | } | 1819 | } |
1785 | 1820 | ||
1786 | #[test] | 1821 | #[test] |
1787 | fn closure_1() { | 1822 | fn closure_1() { |
1788 | assert_snapshot!( | 1823 | check_infer( |
1789 | infer(r#" | 1824 | r#" |
1790 | #[lang = "fn_once"] | 1825 | #[lang = "fn_once"] |
1791 | trait FnOnce<Args> { | 1826 | trait FnOnce<Args> { |
1792 | type Output; | 1827 | type Output; |
1793 | } | 1828 | } |
1794 | 1829 | ||
1795 | enum Option<T> { Some(T), None } | 1830 | enum Option<T> { Some(T), None } |
1796 | impl<T> Option<T> { | 1831 | impl<T> Option<T> { |
1797 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} | 1832 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} |
1798 | } | 1833 | } |
1799 | 1834 | ||
1800 | fn test() { | 1835 | fn test() { |
1801 | let x = Option::Some(1u32); | 1836 | let x = Option::Some(1u32); |
1802 | x.map(|v| v + 1); | 1837 | x.map(|v| v + 1); |
1803 | x.map(|_v| 1u64); | 1838 | x.map(|_v| 1u64); |
1804 | let y: Option<i64> = x.map(|_v| 1); | 1839 | let y: Option<i64> = x.map(|_v| 1); |
1805 | } | 1840 | } |
1806 | "#), | 1841 | "#, |
1807 | @r###" | 1842 | expect![[r#" |
1808 | 147..151 'self': Option<T> | 1843 | 147..151 'self': Option<T> |
1809 | 153..154 'f': F | 1844 | 153..154 'f': F |
1810 | 172..174 '{}': () | 1845 | 172..174 '{}': () |
1811 | 188..307 '{ ... 1); }': () | 1846 | 188..307 '{ ... 1); }': () |
1812 | 198..199 'x': Option<u32> | 1847 | 198..199 'x': Option<u32> |
1813 | 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> | 1848 | 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> |
1814 | 202..220 'Option...(1u32)': Option<u32> | 1849 | 202..220 'Option...(1u32)': Option<u32> |
1815 | 215..219 '1u32': u32 | 1850 | 215..219 '1u32': u32 |
1816 | 226..227 'x': Option<u32> | 1851 | 226..227 'x': Option<u32> |
1817 | 226..242 'x.map(...v + 1)': Option<u32> | 1852 | 226..242 'x.map(...v + 1)': Option<u32> |
1818 | 232..241 '|v| v + 1': |u32| -> u32 | 1853 | 232..241 '|v| v + 1': |u32| -> u32 |
1819 | 233..234 'v': u32 | 1854 | 233..234 'v': u32 |
1820 | 236..237 'v': u32 | 1855 | 236..237 'v': u32 |
1821 | 236..241 'v + 1': u32 | 1856 | 236..241 'v + 1': u32 |
1822 | 240..241 '1': u32 | 1857 | 240..241 '1': u32 |
1823 | 248..249 'x': Option<u32> | 1858 | 248..249 'x': Option<u32> |
1824 | 248..264 'x.map(... 1u64)': Option<u64> | 1859 | 248..264 'x.map(... 1u64)': Option<u64> |
1825 | 254..263 '|_v| 1u64': |u32| -> u64 | 1860 | 254..263 '|_v| 1u64': |u32| -> u64 |
1826 | 255..257 '_v': u32 | 1861 | 255..257 '_v': u32 |
1827 | 259..263 '1u64': u64 | 1862 | 259..263 '1u64': u64 |
1828 | 274..275 'y': Option<i64> | 1863 | 274..275 'y': Option<i64> |
1829 | 291..292 'x': Option<u32> | 1864 | 291..292 'x': Option<u32> |
1830 | 291..304 'x.map(|_v| 1)': Option<i64> | 1865 | 291..304 'x.map(|_v| 1)': Option<i64> |
1831 | 297..303 '|_v| 1': |u32| -> i64 | 1866 | 297..303 '|_v| 1': |u32| -> i64 |
1832 | 298..300 '_v': u32 | 1867 | 298..300 '_v': u32 |
1833 | 302..303 '1': i64 | 1868 | 302..303 '1': i64 |
1834 | "### | 1869 | "#]], |
1835 | ); | 1870 | ); |
1836 | } | 1871 | } |
1837 | 1872 | ||
1838 | #[test] | 1873 | #[test] |
1839 | fn closure_2() { | 1874 | fn closure_2() { |
1840 | assert_snapshot!( | 1875 | check_infer( |
1841 | infer(r#" | 1876 | r#" |
1842 | trait FnOnce<Args> { | 1877 | trait FnOnce<Args> { |
1843 | type Output; | 1878 | type Output; |
1844 | } | 1879 | } |
1845 | 1880 | ||
1846 | fn test<F: FnOnce(u32) -> u64>(f: F) { | 1881 | fn test<F: FnOnce(u32) -> u64>(f: F) { |
1847 | f(1); | 1882 | f(1); |
1848 | let g = |v| v + 1; | 1883 | let g = |v| v + 1; |
1849 | g(1u64); | 1884 | g(1u64); |
1850 | let h = |v| 1u128 + v; | 1885 | let h = |v| 1u128 + v; |
1851 | } | 1886 | } |
1852 | "#), | 1887 | "#, |
1853 | @r###" | 1888 | expect![[r#" |
1854 | 72..73 'f': F | 1889 | 72..73 'f': F |
1855 | 78..154 '{ ...+ v; }': () | 1890 | 78..154 '{ ...+ v; }': () |
1856 | 84..85 'f': F | 1891 | 84..85 'f': F |
1857 | 84..88 'f(1)': {unknown} | 1892 | 84..88 'f(1)': {unknown} |
1858 | 86..87 '1': i32 | 1893 | 86..87 '1': i32 |
1859 | 98..99 'g': |u64| -> i32 | 1894 | 98..99 'g': |u64| -> i32 |
1860 | 102..111 '|v| v + 1': |u64| -> i32 | 1895 | 102..111 '|v| v + 1': |u64| -> i32 |
1861 | 103..104 'v': u64 | 1896 | 103..104 'v': u64 |
1862 | 106..107 'v': u64 | 1897 | 106..107 'v': u64 |
1863 | 106..111 'v + 1': i32 | 1898 | 106..111 'v + 1': i32 |
1864 | 110..111 '1': i32 | 1899 | 110..111 '1': i32 |
1865 | 117..118 'g': |u64| -> i32 | 1900 | 117..118 'g': |u64| -> i32 |
1866 | 117..124 'g(1u64)': i32 | 1901 | 117..124 'g(1u64)': i32 |
1867 | 119..123 '1u64': u64 | 1902 | 119..123 '1u64': u64 |
1868 | 134..135 'h': |u128| -> u128 | 1903 | 134..135 'h': |u128| -> u128 |
1869 | 138..151 '|v| 1u128 + v': |u128| -> u128 | 1904 | 138..151 '|v| 1u128 + v': |u128| -> u128 |
1870 | 139..140 'v': u128 | 1905 | 139..140 'v': u128 |
1871 | 142..147 '1u128': u128 | 1906 | 142..147 '1u128': u128 |
1872 | 142..151 '1u128 + v': u128 | 1907 | 142..151 '1u128 + v': u128 |
1873 | 150..151 'v': u128 | 1908 | 150..151 'v': u128 |
1874 | "### | 1909 | "#]], |
1875 | ); | 1910 | ); |
1876 | } | 1911 | } |
1877 | 1912 | ||
1878 | #[test] | 1913 | #[test] |
1879 | fn closure_as_argument_inference_order() { | 1914 | fn closure_as_argument_inference_order() { |
1880 | assert_snapshot!( | 1915 | check_infer( |
1881 | infer(r#" | 1916 | r#" |
1917 | #[lang = "fn_once"] | ||
1918 | trait FnOnce<Args> { | ||
1919 | type Output; | ||
1920 | } | ||
1921 | |||
1922 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} | ||
1923 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} | ||
1924 | |||
1925 | struct S; | ||
1926 | impl S { | ||
1927 | fn method(self) -> u64; | ||
1928 | |||
1929 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} | ||
1930 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} | ||
1931 | } | ||
1932 | |||
1933 | fn test() { | ||
1934 | let x1 = foo1(S, |s| s.method()); | ||
1935 | let x2 = foo2(|s| s.method(), S); | ||
1936 | let x3 = S.foo1(S, |s| s.method()); | ||
1937 | let x4 = S.foo2(|s| s.method(), S); | ||
1938 | } | ||
1939 | "#, | ||
1940 | expect![[r#" | ||
1941 | 94..95 'x': T | ||
1942 | 100..101 'f': F | ||
1943 | 111..113 '{}': () | ||
1944 | 147..148 'f': F | ||
1945 | 153..154 'x': T | ||
1946 | 164..166 '{}': () | ||
1947 | 201..205 'self': S | ||
1948 | 253..257 'self': S | ||
1949 | 259..260 'x': T | ||
1950 | 265..266 'f': F | ||
1951 | 276..278 '{}': () | ||
1952 | 316..320 'self': S | ||
1953 | 322..323 'f': F | ||
1954 | 328..329 'x': T | ||
1955 | 339..341 '{}': () | ||
1956 | 355..514 '{ ... S); }': () | ||
1957 | 365..367 'x1': u64 | ||
1958 | 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 | ||
1959 | 370..393 'foo1(S...hod())': u64 | ||
1960 | 375..376 'S': S | ||
1961 | 378..392 '|s| s.method()': |S| -> u64 | ||
1962 | 379..380 's': S | ||
1963 | 382..383 's': S | ||
1964 | 382..392 's.method()': u64 | ||
1965 | 403..405 'x2': u64 | ||
1966 | 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 | ||
1967 | 408..431 'foo2(|...(), S)': u64 | ||
1968 | 413..427 '|s| s.method()': |S| -> u64 | ||
1969 | 414..415 's': S | ||
1970 | 417..418 's': S | ||
1971 | 417..427 's.method()': u64 | ||
1972 | 429..430 'S': S | ||
1973 | 441..443 'x3': u64 | ||
1974 | 446..447 'S': S | ||
1975 | 446..471 'S.foo1...hod())': u64 | ||
1976 | 453..454 'S': S | ||
1977 | 456..470 '|s| s.method()': |S| -> u64 | ||
1978 | 457..458 's': S | ||
1979 | 460..461 's': S | ||
1980 | 460..470 's.method()': u64 | ||
1981 | 481..483 'x4': u64 | ||
1982 | 486..487 'S': S | ||
1983 | 486..511 'S.foo2...(), S)': u64 | ||
1984 | 493..507 '|s| s.method()': |S| -> u64 | ||
1985 | 494..495 's': S | ||
1986 | 497..498 's': S | ||
1987 | 497..507 's.method()': u64 | ||
1988 | 509..510 'S': S | ||
1989 | "#]], | ||
1990 | ); | ||
1991 | } | ||
1992 | |||
1993 | #[test] | ||
1994 | fn fn_item_fn_trait() { | ||
1995 | check_types( | ||
1996 | r#" | ||
1882 | #[lang = "fn_once"] | 1997 | #[lang = "fn_once"] |
1883 | trait FnOnce<Args> { | 1998 | trait FnOnce<Args> { |
1884 | type Output; | 1999 | type Output; |
1885 | } | 2000 | } |
1886 | 2001 | ||
1887 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} | ||
1888 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} | ||
1889 | |||
1890 | struct S; | 2002 | struct S; |
1891 | impl S { | ||
1892 | fn method(self) -> u64; | ||
1893 | 2003 | ||
1894 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} | 2004 | fn foo() -> S {} |
1895 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} | 2005 | |
1896 | } | 2006 | fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() } |
1897 | 2007 | ||
1898 | fn test() { | 2008 | fn test() { |
1899 | let x1 = foo1(S, |s| s.method()); | 2009 | takes_closure(foo); |
1900 | let x2 = foo2(|s| s.method(), S); | 2010 | } //^^^^^^^^^^^^^^^^^^ S |
1901 | let x3 = S.foo1(S, |s| s.method()); | 2011 | "#, |
1902 | let x4 = S.foo2(|s| s.method(), S); | ||
1903 | } | ||
1904 | "#), | ||
1905 | @r###" | ||
1906 | 94..95 'x': T | ||
1907 | 100..101 'f': F | ||
1908 | 111..113 '{}': () | ||
1909 | 147..148 'f': F | ||
1910 | 153..154 'x': T | ||
1911 | 164..166 '{}': () | ||
1912 | 201..205 'self': S | ||
1913 | 253..257 'self': S | ||
1914 | 259..260 'x': T | ||
1915 | 265..266 'f': F | ||
1916 | 276..278 '{}': () | ||
1917 | 316..320 'self': S | ||
1918 | 322..323 'f': F | ||
1919 | 328..329 'x': T | ||
1920 | 339..341 '{}': () | ||
1921 | 355..514 '{ ... S); }': () | ||
1922 | 365..367 'x1': u64 | ||
1923 | 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 | ||
1924 | 370..393 'foo1(S...hod())': u64 | ||
1925 | 375..376 'S': S | ||
1926 | 378..392 '|s| s.method()': |S| -> u64 | ||
1927 | 379..380 's': S | ||
1928 | 382..383 's': S | ||
1929 | 382..392 's.method()': u64 | ||
1930 | 403..405 'x2': u64 | ||
1931 | 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 | ||
1932 | 408..431 'foo2(|...(), S)': u64 | ||
1933 | 413..427 '|s| s.method()': |S| -> u64 | ||
1934 | 414..415 's': S | ||
1935 | 417..418 's': S | ||
1936 | 417..427 's.method()': u64 | ||
1937 | 429..430 'S': S | ||
1938 | 441..443 'x3': u64 | ||
1939 | 446..447 'S': S | ||
1940 | 446..471 'S.foo1...hod())': u64 | ||
1941 | 453..454 'S': S | ||
1942 | 456..470 '|s| s.method()': |S| -> u64 | ||
1943 | 457..458 's': S | ||
1944 | 460..461 's': S | ||
1945 | 460..470 's.method()': u64 | ||
1946 | 481..483 'x4': u64 | ||
1947 | 486..487 'S': S | ||
1948 | 486..511 'S.foo2...(), S)': u64 | ||
1949 | 493..507 '|s| s.method()': |S| -> u64 | ||
1950 | 494..495 's': S | ||
1951 | 497..498 's': S | ||
1952 | 497..507 's.method()': u64 | ||
1953 | 509..510 'S': S | ||
1954 | "### | ||
1955 | ); | 2012 | ); |
1956 | } | 2013 | } |
1957 | 2014 | ||
@@ -1998,43 +2055,44 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { | |||
1998 | 2055 | ||
1999 | #[test] | 2056 | #[test] |
2000 | fn unselected_projection_on_impl_self() { | 2057 | fn unselected_projection_on_impl_self() { |
2001 | assert_snapshot!(infer( | 2058 | check_infer( |
2002 | r#" | 2059 | r#" |
2003 | //- /main.rs | 2060 | //- /main.rs |
2004 | trait Trait { | 2061 | trait Trait { |
2005 | type Item; | 2062 | type Item; |
2006 | 2063 | ||
2007 | fn f(&self, x: Self::Item); | 2064 | fn f(&self, x: Self::Item); |
2008 | } | 2065 | } |
2009 | 2066 | ||
2010 | struct S; | 2067 | struct S; |
2011 | 2068 | ||
2012 | impl Trait for S { | 2069 | impl Trait for S { |
2013 | type Item = u32; | 2070 | type Item = u32; |
2014 | fn f(&self, x: Self::Item) { let y = x; } | 2071 | fn f(&self, x: Self::Item) { let y = x; } |
2015 | } | 2072 | } |
2016 | 2073 | ||
2017 | struct S2; | 2074 | struct S2; |
2018 | 2075 | ||
2019 | impl Trait for S2 { | 2076 | impl Trait for S2 { |
2020 | type Item = i32; | 2077 | type Item = i32; |
2021 | fn f(&self, x: <Self>::Item) { let y = x; } | 2078 | fn f(&self, x: <Self>::Item) { let y = x; } |
2022 | } | 2079 | } |
2023 | "#, | 2080 | "#, |
2024 | ), @r###" | 2081 | expect![[r#" |
2025 | 40..44 'self': &Self | 2082 | 40..44 'self': &Self |
2026 | 46..47 'x': Trait::Item<Self> | 2083 | 46..47 'x': Trait::Item<Self> |
2027 | 126..130 'self': &S | 2084 | 126..130 'self': &S |
2028 | 132..133 'x': u32 | 2085 | 132..133 'x': u32 |
2029 | 147..161 '{ let y = x; }': () | 2086 | 147..161 '{ let y = x; }': () |
2030 | 153..154 'y': u32 | 2087 | 153..154 'y': u32 |
2031 | 157..158 'x': u32 | 2088 | 157..158 'x': u32 |
2032 | 228..232 'self': &S2 | 2089 | 228..232 'self': &S2 |
2033 | 234..235 'x': i32 | 2090 | 234..235 'x': i32 |
2034 | 251..265 '{ let y = x; }': () | 2091 | 251..265 '{ let y = x; }': () |
2035 | 257..258 'y': i32 | 2092 | 257..258 'y': i32 |
2036 | 261..262 'x': i32 | 2093 | 261..262 'x': i32 |
2037 | "###); | 2094 | "#]], |
2095 | ); | ||
2038 | } | 2096 | } |
2039 | 2097 | ||
2040 | #[test] | 2098 | #[test] |
@@ -2203,170 +2261,170 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() { | |||
2203 | 2261 | ||
2204 | #[test] | 2262 | #[test] |
2205 | fn proc_macro_server_types() { | 2263 | fn proc_macro_server_types() { |
2206 | assert_snapshot!( | 2264 | check_infer( |
2207 | infer(r#" | 2265 | r#" |
2208 | macro_rules! with_api { | 2266 | macro_rules! with_api { |
2209 | ($S:ident, $self:ident, $m:ident) => { | 2267 | ($S:ident, $self:ident, $m:ident) => { |
2210 | $m! { | 2268 | $m! { |
2211 | TokenStream { | 2269 | TokenStream { |
2212 | fn new() -> $S::TokenStream; | 2270 | fn new() -> $S::TokenStream; |
2213 | }, | 2271 | }, |
2214 | Group { | 2272 | Group { |
2215 | }, | 2273 | }, |
2216 | } | 2274 | } |
2217 | }; | 2275 | }; |
2218 | } | 2276 | } |
2219 | macro_rules! associated_item { | 2277 | macro_rules! associated_item { |
2220 | (type TokenStream) => | 2278 | (type TokenStream) => |
2221 | (type TokenStream: 'static;); | 2279 | (type TokenStream: 'static;); |
2222 | (type Group) => | 2280 | (type Group) => |
2223 | (type Group: 'static;); | 2281 | (type Group: 'static;); |
2224 | ($($item:tt)*) => ($($item)*;) | 2282 | ($($item:tt)*) => ($($item)*;) |
2225 | } | 2283 | } |
2226 | macro_rules! declare_server_traits { | 2284 | macro_rules! declare_server_traits { |
2227 | ($($name:ident { | 2285 | ($($name:ident { |
2228 | $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* | 2286 | $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* |
2229 | }),* $(,)?) => { | 2287 | }),* $(,)?) => { |
2230 | pub trait Types { | 2288 | pub trait Types { |
2231 | $(associated_item!(type $name);)* | 2289 | $(associated_item!(type $name);)* |
2232 | } | 2290 | } |
2233 | |||
2234 | $(pub trait $name: Types { | ||
2235 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* | ||
2236 | })* | ||
2237 | |||
2238 | pub trait Server: Types $(+ $name)* {} | ||
2239 | impl<S: Types $(+ $name)*> Server for S {} | ||
2240 | } | ||
2241 | } | ||
2242 | 2291 | ||
2243 | with_api!(Self, self_, declare_server_traits); | 2292 | $(pub trait $name: Types { |
2244 | struct G {} | 2293 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* |
2245 | struct T {} | 2294 | })* |
2246 | struct Rustc; | ||
2247 | impl Types for Rustc { | ||
2248 | type TokenStream = T; | ||
2249 | type Group = G; | ||
2250 | } | ||
2251 | 2295 | ||
2252 | fn make<T>() -> T { loop {} } | 2296 | pub trait Server: Types $(+ $name)* {} |
2253 | impl TokenStream for Rustc { | 2297 | impl<S: Types $(+ $name)*> Server for S {} |
2254 | fn new() -> Self::TokenStream { | 2298 | } |
2255 | let group: Self::Group = make(); | 2299 | } |
2256 | make() | 2300 | |
2257 | } | 2301 | with_api!(Self, self_, declare_server_traits); |
2258 | } | 2302 | struct G {} |
2259 | "#), | 2303 | struct T {} |
2260 | @r###" | 2304 | struct Rustc; |
2261 | 1061..1072 '{ loop {} }': T | 2305 | impl Types for Rustc { |
2262 | 1063..1070 'loop {}': ! | 2306 | type TokenStream = T; |
2263 | 1068..1070 '{}': () | 2307 | type Group = G; |
2264 | 1136..1199 '{ ... }': T | 2308 | } |
2265 | 1150..1155 'group': G | 2309 | |
2266 | 1171..1175 'make': fn make<G>() -> G | 2310 | fn make<T>() -> T { loop {} } |
2267 | 1171..1177 'make()': G | 2311 | impl TokenStream for Rustc { |
2268 | 1187..1191 'make': fn make<T>() -> T | 2312 | fn new() -> Self::TokenStream { |
2269 | 1187..1193 'make()': T | 2313 | let group: Self::Group = make(); |
2270 | "### | 2314 | make() |
2315 | } | ||
2316 | } | ||
2317 | "#, | ||
2318 | expect![[r#" | ||
2319 | 1061..1072 '{ loop {} }': T | ||
2320 | 1063..1070 'loop {}': ! | ||
2321 | 1068..1070 '{}': () | ||
2322 | 1136..1199 '{ ... }': T | ||
2323 | 1150..1155 'group': G | ||
2324 | 1171..1175 'make': fn make<G>() -> G | ||
2325 | 1171..1177 'make()': G | ||
2326 | 1187..1191 'make': fn make<T>() -> T | ||
2327 | 1187..1193 'make()': T | ||
2328 | "#]], | ||
2271 | ); | 2329 | ); |
2272 | } | 2330 | } |
2273 | 2331 | ||
2274 | #[test] | 2332 | #[test] |
2275 | fn unify_impl_trait() { | 2333 | fn unify_impl_trait() { |
2276 | assert_snapshot!( | 2334 | check_infer_with_mismatches( |
2277 | infer_with_mismatches(r#" | 2335 | r#" |
2278 | trait Trait<T> {} | 2336 | trait Trait<T> {} |
2279 | 2337 | ||
2280 | fn foo(x: impl Trait<u32>) { loop {} } | 2338 | fn foo(x: impl Trait<u32>) { loop {} } |
2281 | fn bar<T>(x: impl Trait<T>) -> T { loop {} } | 2339 | fn bar<T>(x: impl Trait<T>) -> T { loop {} } |
2282 | 2340 | ||
2283 | struct S<T>(T); | 2341 | struct S<T>(T); |
2284 | impl<T> Trait<T> for S<T> {} | 2342 | impl<T> Trait<T> for S<T> {} |
2285 | 2343 | ||
2286 | fn default<T>() -> T { loop {} } | 2344 | fn default<T>() -> T { loop {} } |
2287 | 2345 | ||
2288 | fn test() -> impl Trait<i32> { | 2346 | fn test() -> impl Trait<i32> { |
2289 | let s1 = S(default()); | 2347 | let s1 = S(default()); |
2290 | foo(s1); | 2348 | foo(s1); |
2291 | let x: i32 = bar(S(default())); | 2349 | let x: i32 = bar(S(default())); |
2292 | S(default()) | 2350 | S(default()) |
2293 | } | 2351 | } |
2294 | "#, true), | 2352 | "#, |
2295 | @r###" | 2353 | expect![[r#" |
2296 | 26..27 'x': impl Trait<u32> | 2354 | 26..27 'x': impl Trait<u32> |
2297 | 46..57 '{ loop {} }': () | 2355 | 46..57 '{ loop {} }': () |
2298 | 48..55 'loop {}': ! | 2356 | 48..55 'loop {}': ! |
2299 | 53..55 '{}': () | 2357 | 53..55 '{}': () |
2300 | 68..69 'x': impl Trait<T> | 2358 | 68..69 'x': impl Trait<T> |
2301 | 91..102 '{ loop {} }': T | 2359 | 91..102 '{ loop {} }': T |
2302 | 93..100 'loop {}': ! | 2360 | 93..100 'loop {}': ! |
2303 | 98..100 '{}': () | 2361 | 98..100 '{}': () |
2304 | 171..182 '{ loop {} }': T | 2362 | 171..182 '{ loop {} }': T |
2305 | 173..180 'loop {}': ! | 2363 | 173..180 'loop {}': ! |
2306 | 178..180 '{}': () | 2364 | 178..180 '{}': () |
2307 | 213..309 '{ ...t()) }': S<{unknown}> | 2365 | 213..309 '{ ...t()) }': S<{unknown}> |
2308 | 223..225 's1': S<u32> | 2366 | 223..225 's1': S<u32> |
2309 | 228..229 'S': S<u32>(u32) -> S<u32> | 2367 | 228..229 'S': S<u32>(u32) -> S<u32> |
2310 | 228..240 'S(default())': S<u32> | 2368 | 228..240 'S(default())': S<u32> |
2311 | 230..237 'default': fn default<u32>() -> u32 | 2369 | 230..237 'default': fn default<u32>() -> u32 |
2312 | 230..239 'default()': u32 | 2370 | 230..239 'default()': u32 |
2313 | 246..249 'foo': fn foo(S<u32>) | 2371 | 246..249 'foo': fn foo(S<u32>) |
2314 | 246..253 'foo(s1)': () | 2372 | 246..253 'foo(s1)': () |
2315 | 250..252 's1': S<u32> | 2373 | 250..252 's1': S<u32> |
2316 | 263..264 'x': i32 | 2374 | 263..264 'x': i32 |
2317 | 272..275 'bar': fn bar<i32>(S<i32>) -> i32 | 2375 | 272..275 'bar': fn bar<i32>(S<i32>) -> i32 |
2318 | 272..289 'bar(S(...lt()))': i32 | 2376 | 272..289 'bar(S(...lt()))': i32 |
2319 | 276..277 'S': S<i32>(i32) -> S<i32> | 2377 | 276..277 'S': S<i32>(i32) -> S<i32> |
2320 | 276..288 'S(default())': S<i32> | 2378 | 276..288 'S(default())': S<i32> |
2321 | 278..285 'default': fn default<i32>() -> i32 | 2379 | 278..285 'default': fn default<i32>() -> i32 |
2322 | 278..287 'default()': i32 | 2380 | 278..287 'default()': i32 |
2323 | 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> | 2381 | 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> |
2324 | 295..307 'S(default())': S<{unknown}> | 2382 | 295..307 'S(default())': S<{unknown}> |
2325 | 297..304 'default': fn default<{unknown}>() -> {unknown} | 2383 | 297..304 'default': fn default<{unknown}>() -> {unknown} |
2326 | 297..306 'default()': {unknown} | 2384 | 297..306 'default()': {unknown} |
2327 | "### | 2385 | "#]], |
2328 | ); | 2386 | ); |
2329 | } | 2387 | } |
2330 | 2388 | ||
2331 | #[test] | 2389 | #[test] |
2332 | fn assoc_types_from_bounds() { | 2390 | fn assoc_types_from_bounds() { |
2333 | assert_snapshot!( | 2391 | check_infer( |
2334 | infer(r#" | 2392 | r#" |
2335 | //- /main.rs | 2393 | //- /main.rs |
2336 | #[lang = "fn_once"] | 2394 | #[lang = "fn_once"] |
2337 | trait FnOnce<Args> { | 2395 | trait FnOnce<Args> { |
2338 | type Output; | 2396 | type Output; |
2339 | } | 2397 | } |
2340 | 2398 | ||
2341 | trait T { | 2399 | trait T { |
2342 | type O; | 2400 | type O; |
2343 | } | 2401 | } |
2344 | 2402 | ||
2345 | impl T for () { | 2403 | impl T for () { |
2346 | type O = (); | 2404 | type O = (); |
2347 | } | 2405 | } |
2348 | 2406 | ||
2349 | fn f<X, F>(_v: F) | 2407 | fn f<X, F>(_v: F) |
2350 | where | 2408 | where |
2351 | X: T, | 2409 | X: T, |
2352 | F: FnOnce(&X::O), | 2410 | F: FnOnce(&X::O), |
2353 | { } | 2411 | { } |
2354 | 2412 | ||
2355 | fn main() { | 2413 | fn main() { |
2356 | f::<(), _>(|z| { z; }); | 2414 | f::<(), _>(|z| { z; }); |
2357 | } | 2415 | } |
2358 | "#), | 2416 | "#, |
2359 | @r###" | 2417 | expect![[r#" |
2360 | 133..135 '_v': F | 2418 | 133..135 '_v': F |
2361 | 178..181 '{ }': () | 2419 | 178..181 '{ }': () |
2362 | 193..224 '{ ... }); }': () | 2420 | 193..224 '{ ... }); }': () |
2363 | 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) | 2421 | 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) |
2364 | 199..221 'f::<()... z; })': () | 2422 | 199..221 'f::<()... z; })': () |
2365 | 210..220 '|z| { z; }': |&()| -> () | 2423 | 210..220 '|z| { z; }': |&()| -> () |
2366 | 211..212 'z': &() | 2424 | 211..212 'z': &() |
2367 | 214..220 '{ z; }': () | 2425 | 214..220 '{ z; }': () |
2368 | 216..217 'z': &() | 2426 | 216..217 'z': &() |
2369 | "### | 2427 | "#]], |
2370 | ); | 2428 | ); |
2371 | } | 2429 | } |
2372 | 2430 | ||
@@ -2439,120 +2497,120 @@ fn test() { | |||
2439 | 2497 | ||
2440 | #[test] | 2498 | #[test] |
2441 | fn iterator_chain() { | 2499 | fn iterator_chain() { |
2442 | assert_snapshot!( | 2500 | check_infer( |
2443 | infer(r#" | 2501 | r#" |
2444 | //- /main.rs | 2502 | //- /main.rs |
2445 | #[lang = "fn_once"] | 2503 | #[lang = "fn_once"] |
2446 | trait FnOnce<Args> { | 2504 | trait FnOnce<Args> { |
2447 | type Output; | 2505 | type Output; |
2448 | } | 2506 | } |
2449 | #[lang = "fn_mut"] | 2507 | #[lang = "fn_mut"] |
2450 | trait FnMut<Args>: FnOnce<Args> { } | 2508 | trait FnMut<Args>: FnOnce<Args> { } |
2451 | 2509 | ||
2452 | enum Option<T> { Some(T), None } | 2510 | enum Option<T> { Some(T), None } |
2453 | use Option::*; | 2511 | use Option::*; |
2454 | 2512 | ||
2455 | pub trait Iterator { | 2513 | pub trait Iterator { |
2456 | type Item; | 2514 | type Item; |
2457 | 2515 | ||
2458 | fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> | 2516 | fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> |
2459 | where | 2517 | where |
2460 | F: FnMut(Self::Item) -> Option<B>, | 2518 | F: FnMut(Self::Item) -> Option<B>, |
2461 | { loop {} } | 2519 | { loop {} } |
2462 | 2520 | ||
2463 | fn for_each<F>(self, f: F) | 2521 | fn for_each<F>(self, f: F) |
2464 | where | 2522 | where |
2465 | F: FnMut(Self::Item), | 2523 | F: FnMut(Self::Item), |
2466 | { loop {} } | 2524 | { loop {} } |
2467 | } | 2525 | } |
2468 | 2526 | ||
2469 | pub trait IntoIterator { | 2527 | pub trait IntoIterator { |
2470 | type Item; | 2528 | type Item; |
2471 | type IntoIter: Iterator<Item = Self::Item>; | 2529 | type IntoIter: Iterator<Item = Self::Item>; |
2472 | fn into_iter(self) -> Self::IntoIter; | 2530 | fn into_iter(self) -> Self::IntoIter; |
2473 | } | 2531 | } |
2474 | 2532 | ||
2475 | pub struct FilterMap<I, F> { } | 2533 | pub struct FilterMap<I, F> { } |
2476 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> | 2534 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> |
2477 | where | 2535 | where |
2478 | F: FnMut(I::Item) -> Option<B>, | 2536 | F: FnMut(I::Item) -> Option<B>, |
2479 | { | 2537 | { |
2480 | type Item = B; | 2538 | type Item = B; |
2481 | } | 2539 | } |
2482 | 2540 | ||
2483 | #[stable(feature = "rust1", since = "1.0.0")] | 2541 | #[stable(feature = "rust1", since = "1.0.0")] |
2484 | impl<I: Iterator> IntoIterator for I { | 2542 | impl<I: Iterator> IntoIterator for I { |
2485 | type Item = I::Item; | 2543 | type Item = I::Item; |
2486 | type IntoIter = I; | 2544 | type IntoIter = I; |
2487 | 2545 | ||
2488 | fn into_iter(self) -> I { | 2546 | fn into_iter(self) -> I { |
2489 | self | 2547 | self |
2490 | } | 2548 | } |
2491 | } | 2549 | } |
2492 | 2550 | ||
2493 | struct Vec<T> {} | 2551 | struct Vec<T> {} |
2494 | impl<T> Vec<T> { | 2552 | impl<T> Vec<T> { |
2495 | fn new() -> Self { loop {} } | 2553 | fn new() -> Self { loop {} } |
2496 | } | 2554 | } |
2497 | 2555 | ||
2498 | impl<T> IntoIterator for Vec<T> { | 2556 | impl<T> IntoIterator for Vec<T> { |
2499 | type Item = T; | 2557 | type Item = T; |
2500 | type IntoIter = IntoIter<T>; | 2558 | type IntoIter = IntoIter<T>; |
2501 | } | 2559 | } |
2502 | 2560 | ||
2503 | pub struct IntoIter<T> { } | 2561 | pub struct IntoIter<T> { } |
2504 | impl<T> Iterator for IntoIter<T> { | 2562 | impl<T> Iterator for IntoIter<T> { |
2505 | type Item = T; | 2563 | type Item = T; |
2506 | } | 2564 | } |
2507 | 2565 | ||
2508 | fn main() { | 2566 | fn main() { |
2509 | Vec::<i32>::new().into_iter() | 2567 | Vec::<i32>::new().into_iter() |
2510 | .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) | 2568 | .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) |
2511 | .for_each(|y| { y; }); | 2569 | .for_each(|y| { y; }); |
2512 | } | 2570 | } |
2513 | "#), | 2571 | "#, |
2514 | @r###" | 2572 | expect![[r#" |
2515 | 226..230 'self': Self | 2573 | 226..230 'self': Self |
2516 | 232..233 'f': F | 2574 | 232..233 'f': F |
2517 | 317..328 '{ loop {} }': FilterMap<Self, F> | 2575 | 317..328 '{ loop {} }': FilterMap<Self, F> |
2518 | 319..326 'loop {}': ! | 2576 | 319..326 'loop {}': ! |
2519 | 324..326 '{}': () | 2577 | 324..326 '{}': () |
2520 | 349..353 'self': Self | 2578 | 349..353 'self': Self |
2521 | 355..356 'f': F | 2579 | 355..356 'f': F |
2522 | 405..416 '{ loop {} }': () | 2580 | 405..416 '{ loop {} }': () |
2523 | 407..414 'loop {}': ! | 2581 | 407..414 'loop {}': ! |
2524 | 412..414 '{}': () | 2582 | 412..414 '{}': () |
2525 | 525..529 'self': Self | 2583 | 525..529 'self': Self |
2526 | 854..858 'self': I | 2584 | 854..858 'self': I |
2527 | 865..885 '{ ... }': I | 2585 | 865..885 '{ ... }': I |
2528 | 875..879 'self': I | 2586 | 875..879 'self': I |
2529 | 944..955 '{ loop {} }': Vec<T> | 2587 | 944..955 '{ loop {} }': Vec<T> |
2530 | 946..953 'loop {}': ! | 2588 | 946..953 'loop {}': ! |
2531 | 951..953 '{}': () | 2589 | 951..953 '{}': () |
2532 | 1142..1273 '{ ... }); }': () | 2590 | 1142..1269 '{ ... }); }': () |
2533 | 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> | 2591 | 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> |
2534 | 1148..1165 'Vec::<...:new()': Vec<i32> | 2592 | 1148..1165 'Vec::<...:new()': Vec<i32> |
2535 | 1148..1177 'Vec::<...iter()': IntoIter<i32> | 2593 | 1148..1177 'Vec::<...iter()': IntoIter<i32> |
2536 | 1148..1242 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> | 2594 | 1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> |
2537 | 1148..1270 'Vec::<... y; })': () | 2595 | 1148..1266 'Vec::<... y; })': () |
2538 | 1196..1241 '|x| if...None }': |i32| -> Option<u32> | 2596 | 1194..1239 '|x| if...None }': |i32| -> Option<u32> |
2539 | 1197..1198 'x': i32 | 2597 | 1195..1196 'x': i32 |
2540 | 1200..1241 'if x >...None }': Option<u32> | 2598 | 1198..1239 'if x >...None }': Option<u32> |
2541 | 1203..1204 'x': i32 | 2599 | 1201..1202 'x': i32 |
2542 | 1203..1208 'x > 0': bool | 2600 | 1201..1206 'x > 0': bool |
2543 | 1207..1208 '0': i32 | 2601 | 1205..1206 '0': i32 |
2544 | 1209..1227 '{ Some...u32) }': Option<u32> | 2602 | 1207..1225 '{ Some...u32) }': Option<u32> |
2545 | 1211..1215 'Some': Some<u32>(u32) -> Option<u32> | 2603 | 1209..1213 'Some': Some<u32>(u32) -> Option<u32> |
2546 | 1211..1225 'Some(x as u32)': Option<u32> | 2604 | 1209..1223 'Some(x as u32)': Option<u32> |
2547 | 1216..1217 'x': i32 | 2605 | 1214..1215 'x': i32 |
2548 | 1216..1224 'x as u32': u32 | 2606 | 1214..1222 'x as u32': u32 |
2549 | 1233..1241 '{ None }': Option<u32> | 2607 | 1231..1239 '{ None }': Option<u32> |
2550 | 1235..1239 'None': Option<u32> | 2608 | 1233..1237 'None': Option<u32> |
2551 | 1259..1269 '|y| { y; }': |u32| -> () | 2609 | 1255..1265 '|y| { y; }': |u32| -> () |
2552 | 1260..1261 'y': u32 | 2610 | 1256..1257 'y': u32 |
2553 | 1263..1269 '{ y; }': () | 2611 | 1259..1265 '{ y; }': () |
2554 | 1265..1266 'y': u32 | 2612 | 1261..1262 'y': u32 |
2555 | "### | 2613 | "#]], |
2556 | ); | 2614 | ); |
2557 | } | 2615 | } |
2558 | 2616 | ||
@@ -2590,176 +2648,176 @@ fn main() { | |||
2590 | 2648 | ||
2591 | #[test] | 2649 | #[test] |
2592 | fn trait_object_no_coercion() { | 2650 | fn trait_object_no_coercion() { |
2593 | assert_snapshot!( | 2651 | check_infer_with_mismatches( |
2594 | infer_with_mismatches(r#" | 2652 | r#" |
2595 | trait Foo {} | 2653 | trait Foo {} |
2596 | 2654 | ||
2597 | fn foo(x: &dyn Foo) {} | 2655 | fn foo(x: &dyn Foo) {} |
2598 | 2656 | ||
2599 | fn test(x: &dyn Foo) { | 2657 | fn test(x: &dyn Foo) { |
2600 | foo(x); | 2658 | foo(x); |
2601 | } | 2659 | } |
2602 | "#, true), | 2660 | "#, |
2603 | @r###" | 2661 | expect![[r#" |
2604 | 21..22 'x': &dyn Foo | 2662 | 21..22 'x': &dyn Foo |
2605 | 34..36 '{}': () | 2663 | 34..36 '{}': () |
2606 | 46..47 'x': &dyn Foo | 2664 | 46..47 'x': &dyn Foo |
2607 | 59..74 '{ foo(x); }': () | 2665 | 59..74 '{ foo(x); }': () |
2608 | 65..68 'foo': fn foo(&dyn Foo) | 2666 | 65..68 'foo': fn foo(&dyn Foo) |
2609 | 65..71 'foo(x)': () | 2667 | 65..71 'foo(x)': () |
2610 | 69..70 'x': &dyn Foo | 2668 | 69..70 'x': &dyn Foo |
2611 | "### | 2669 | "#]], |
2612 | ); | 2670 | ); |
2613 | } | 2671 | } |
2614 | 2672 | ||
2615 | #[test] | 2673 | #[test] |
2616 | fn builtin_copy() { | 2674 | fn builtin_copy() { |
2617 | assert_snapshot!( | 2675 | check_infer_with_mismatches( |
2618 | infer_with_mismatches(r#" | 2676 | r#" |
2619 | #[lang = "copy"] | 2677 | #[lang = "copy"] |
2620 | trait Copy {} | 2678 | trait Copy {} |
2621 | 2679 | ||
2622 | struct IsCopy; | 2680 | struct IsCopy; |
2623 | impl Copy for IsCopy {} | 2681 | impl Copy for IsCopy {} |
2624 | struct NotCopy; | 2682 | struct NotCopy; |
2625 | 2683 | ||
2626 | trait Test { fn test(&self) -> bool; } | 2684 | trait Test { fn test(&self) -> bool; } |
2627 | impl<T: Copy> Test for T {} | 2685 | impl<T: Copy> Test for T {} |
2628 | 2686 | ||
2629 | fn test() { | 2687 | fn test() { |
2630 | IsCopy.test(); | 2688 | IsCopy.test(); |
2631 | NotCopy.test(); | 2689 | NotCopy.test(); |
2632 | (IsCopy, IsCopy).test(); | 2690 | (IsCopy, IsCopy).test(); |
2633 | (IsCopy, NotCopy).test(); | 2691 | (IsCopy, NotCopy).test(); |
2634 | } | 2692 | } |
2635 | "#, true), | 2693 | "#, |
2636 | @r###" | 2694 | expect![[r#" |
2637 | 110..114 'self': &Self | 2695 | 110..114 'self': &Self |
2638 | 166..267 '{ ...t(); }': () | 2696 | 166..267 '{ ...t(); }': () |
2639 | 172..178 'IsCopy': IsCopy | 2697 | 172..178 'IsCopy': IsCopy |
2640 | 172..185 'IsCopy.test()': bool | 2698 | 172..185 'IsCopy.test()': bool |
2641 | 191..198 'NotCopy': NotCopy | 2699 | 191..198 'NotCopy': NotCopy |
2642 | 191..205 'NotCopy.test()': {unknown} | 2700 | 191..205 'NotCopy.test()': {unknown} |
2643 | 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) | 2701 | 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) |
2644 | 211..234 '(IsCop...test()': bool | 2702 | 211..234 '(IsCop...test()': bool |
2645 | 212..218 'IsCopy': IsCopy | 2703 | 212..218 'IsCopy': IsCopy |
2646 | 220..226 'IsCopy': IsCopy | 2704 | 220..226 'IsCopy': IsCopy |
2647 | 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) | 2705 | 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) |
2648 | 240..264 '(IsCop...test()': {unknown} | 2706 | 240..264 '(IsCop...test()': {unknown} |
2649 | 241..247 'IsCopy': IsCopy | 2707 | 241..247 'IsCopy': IsCopy |
2650 | 249..256 'NotCopy': NotCopy | 2708 | 249..256 'NotCopy': NotCopy |
2651 | "### | 2709 | "#]], |
2652 | ); | 2710 | ); |
2653 | } | 2711 | } |
2654 | 2712 | ||
2655 | #[test] | 2713 | #[test] |
2656 | fn builtin_fn_def_copy() { | 2714 | fn builtin_fn_def_copy() { |
2657 | assert_snapshot!( | 2715 | check_infer_with_mismatches( |
2658 | infer_with_mismatches(r#" | 2716 | r#" |
2659 | #[lang = "copy"] | 2717 | #[lang = "copy"] |
2660 | trait Copy {} | 2718 | trait Copy {} |
2661 | 2719 | ||
2662 | fn foo() {} | 2720 | fn foo() {} |
2663 | fn bar<T: Copy>(T) -> T {} | 2721 | fn bar<T: Copy>(T) -> T {} |
2664 | struct Struct(usize); | 2722 | struct Struct(usize); |
2665 | enum Enum { Variant(usize) } | 2723 | enum Enum { Variant(usize) } |
2666 | 2724 | ||
2667 | trait Test { fn test(&self) -> bool; } | 2725 | trait Test { fn test(&self) -> bool; } |
2668 | impl<T: Copy> Test for T {} | 2726 | impl<T: Copy> Test for T {} |
2669 | 2727 | ||
2670 | fn test() { | 2728 | fn test() { |
2671 | foo.test(); | 2729 | foo.test(); |
2672 | bar.test(); | 2730 | bar.test(); |
2673 | Struct.test(); | 2731 | Struct.test(); |
2674 | Enum::Variant.test(); | 2732 | Enum::Variant.test(); |
2675 | } | 2733 | } |
2676 | "#, true), | 2734 | "#, |
2677 | @r###" | 2735 | expect![[r#" |
2678 | 41..43 '{}': () | 2736 | 41..43 '{}': () |
2679 | 60..61 'T': {unknown} | 2737 | 60..61 'T': {unknown} |
2680 | 68..70 '{}': () | 2738 | 68..70 '{}': () |
2681 | 68..70: expected T, got () | 2739 | 68..70: expected T, got () |
2682 | 145..149 'self': &Self | 2740 | 145..149 'self': &Self |
2683 | 201..281 '{ ...t(); }': () | 2741 | 201..281 '{ ...t(); }': () |
2684 | 207..210 'foo': fn foo() | 2742 | 207..210 'foo': fn foo() |
2685 | 207..217 'foo.test()': bool | 2743 | 207..217 'foo.test()': bool |
2686 | 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} | 2744 | 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} |
2687 | 223..233 'bar.test()': bool | 2745 | 223..233 'bar.test()': bool |
2688 | 239..245 'Struct': Struct(usize) -> Struct | 2746 | 239..245 'Struct': Struct(usize) -> Struct |
2689 | 239..252 'Struct.test()': bool | 2747 | 239..252 'Struct.test()': bool |
2690 | 258..271 'Enum::Variant': Variant(usize) -> Enum | 2748 | 258..271 'Enum::Variant': Variant(usize) -> Enum |
2691 | 258..278 'Enum::...test()': bool | 2749 | 258..278 'Enum::...test()': bool |
2692 | "### | 2750 | "#]], |
2693 | ); | 2751 | ); |
2694 | } | 2752 | } |
2695 | 2753 | ||
2696 | #[test] | 2754 | #[test] |
2697 | fn builtin_fn_ptr_copy() { | 2755 | fn builtin_fn_ptr_copy() { |
2698 | assert_snapshot!( | 2756 | check_infer_with_mismatches( |
2699 | infer_with_mismatches(r#" | 2757 | r#" |
2700 | #[lang = "copy"] | 2758 | #[lang = "copy"] |
2701 | trait Copy {} | 2759 | trait Copy {} |
2702 | 2760 | ||
2703 | trait Test { fn test(&self) -> bool; } | 2761 | trait Test { fn test(&self) -> bool; } |
2704 | impl<T: Copy> Test for T {} | 2762 | impl<T: Copy> Test for T {} |
2705 | 2763 | ||
2706 | fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { | 2764 | fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { |
2707 | f1.test(); | 2765 | f1.test(); |
2708 | f2.test(); | 2766 | f2.test(); |
2709 | f3.test(); | 2767 | f3.test(); |
2710 | } | 2768 | } |
2711 | "#, true), | 2769 | "#, |
2712 | @r###" | 2770 | expect![[r#" |
2713 | 54..58 'self': &Self | 2771 | 54..58 'self': &Self |
2714 | 108..110 'f1': fn() | 2772 | 108..110 'f1': fn() |
2715 | 118..120 'f2': fn(usize) -> u8 | 2773 | 118..120 'f2': fn(usize) -> u8 |
2716 | 139..141 'f3': fn(u8, u8) -> &u8 | 2774 | 139..141 'f3': fn(u8, u8) -> &u8 |
2717 | 162..210 '{ ...t(); }': () | 2775 | 162..210 '{ ...t(); }': () |
2718 | 168..170 'f1': fn() | 2776 | 168..170 'f1': fn() |
2719 | 168..177 'f1.test()': bool | 2777 | 168..177 'f1.test()': bool |
2720 | 183..185 'f2': fn(usize) -> u8 | 2778 | 183..185 'f2': fn(usize) -> u8 |
2721 | 183..192 'f2.test()': bool | 2779 | 183..192 'f2.test()': bool |
2722 | 198..200 'f3': fn(u8, u8) -> &u8 | 2780 | 198..200 'f3': fn(u8, u8) -> &u8 |
2723 | 198..207 'f3.test()': bool | 2781 | 198..207 'f3.test()': bool |
2724 | "### | 2782 | "#]], |
2725 | ); | 2783 | ); |
2726 | } | 2784 | } |
2727 | 2785 | ||
2728 | #[test] | 2786 | #[test] |
2729 | fn builtin_sized() { | 2787 | fn builtin_sized() { |
2730 | assert_snapshot!( | 2788 | check_infer_with_mismatches( |
2731 | infer_with_mismatches(r#" | 2789 | r#" |
2732 | #[lang = "sized"] | 2790 | #[lang = "sized"] |
2733 | trait Sized {} | 2791 | trait Sized {} |
2734 | 2792 | ||
2735 | trait Test { fn test(&self) -> bool; } | 2793 | trait Test { fn test(&self) -> bool; } |
2736 | impl<T: Sized> Test for T {} | 2794 | impl<T: Sized> Test for T {} |
2737 | 2795 | ||
2738 | fn test() { | 2796 | fn test() { |
2739 | 1u8.test(); | 2797 | 1u8.test(); |
2740 | (*"foo").test(); // not Sized | 2798 | (*"foo").test(); // not Sized |
2741 | (1u8, 1u8).test(); | 2799 | (1u8, 1u8).test(); |
2742 | (1u8, *"foo").test(); // not Sized | 2800 | (1u8, *"foo").test(); // not Sized |
2743 | } | 2801 | } |
2744 | "#, true), | 2802 | "#, |
2745 | @r###" | 2803 | expect![[r#" |
2746 | 56..60 'self': &Self | 2804 | 56..60 'self': &Self |
2747 | 113..228 '{ ...ized }': () | 2805 | 113..228 '{ ...ized }': () |
2748 | 119..122 '1u8': u8 | 2806 | 119..122 '1u8': u8 |
2749 | 119..129 '1u8.test()': bool | 2807 | 119..129 '1u8.test()': bool |
2750 | 135..150 '(*"foo").test()': {unknown} | 2808 | 135..150 '(*"foo").test()': {unknown} |
2751 | 136..142 '*"foo"': str | 2809 | 136..142 '*"foo"': str |
2752 | 137..142 '"foo"': &str | 2810 | 137..142 '"foo"': &str |
2753 | 169..179 '(1u8, 1u8)': (u8, u8) | 2811 | 169..179 '(1u8, 1u8)': (u8, u8) |
2754 | 169..186 '(1u8, ...test()': bool | 2812 | 169..186 '(1u8, ...test()': bool |
2755 | 170..173 '1u8': u8 | 2813 | 170..173 '1u8': u8 |
2756 | 175..178 '1u8': u8 | 2814 | 175..178 '1u8': u8 |
2757 | 192..205 '(1u8, *"foo")': (u8, str) | 2815 | 192..205 '(1u8, *"foo")': (u8, str) |
2758 | 192..212 '(1u8, ...test()': {unknown} | 2816 | 192..212 '(1u8, ...test()': {unknown} |
2759 | 193..196 '1u8': u8 | 2817 | 193..196 '1u8': u8 |
2760 | 198..204 '*"foo"': str | 2818 | 198..204 '*"foo"': str |
2761 | 199..204 '"foo"': &str | 2819 | 199..204 '"foo"': &str |
2762 | "### | 2820 | "#]], |
2763 | ); | 2821 | ); |
2764 | } | 2822 | } |
2765 | 2823 | ||
@@ -2809,223 +2867,247 @@ impl<A: Step> iter::Iterator for ops::Range<A> { | |||
2809 | 2867 | ||
2810 | #[test] | 2868 | #[test] |
2811 | fn infer_closure_arg() { | 2869 | fn infer_closure_arg() { |
2812 | assert_snapshot!( | 2870 | check_infer( |
2813 | infer( | 2871 | r#" |
2814 | r#" | 2872 | //- /lib.rs |
2815 | //- /lib.rs | ||
2816 | |||
2817 | enum Option<T> { | ||
2818 | None, | ||
2819 | Some(T) | ||
2820 | } | ||
2821 | 2873 | ||
2822 | fn foo() { | 2874 | enum Option<T> { |
2823 | let s = Option::None; | 2875 | None, |
2824 | let f = |x: Option<i32>| {}; | 2876 | Some(T) |
2825 | (&f)(s) | 2877 | } |
2826 | } | 2878 | |
2827 | "# | 2879 | fn foo() { |
2828 | ), | 2880 | let s = Option::None; |
2829 | @r###" | 2881 | let f = |x: Option<i32>| {}; |
2830 | 52..126 '{ ...)(s) }': () | 2882 | (&f)(s) |
2831 | 62..63 's': Option<i32> | 2883 | } |
2832 | 66..78 'Option::None': Option<i32> | 2884 | "#, |
2833 | 88..89 'f': |Option<i32>| -> () | 2885 | expect![[r#" |
2834 | 92..111 '|x: Op...2>| {}': |Option<i32>| -> () | 2886 | 52..126 '{ ...)(s) }': () |
2835 | 93..94 'x': Option<i32> | 2887 | 62..63 's': Option<i32> |
2836 | 109..111 '{}': () | 2888 | 66..78 'Option::None': Option<i32> |
2837 | 117..124 '(&f)(s)': () | 2889 | 88..89 'f': |Option<i32>| -> () |
2838 | 118..120 '&f': &|Option<i32>| -> () | 2890 | 92..111 '|x: Op...2>| {}': |Option<i32>| -> () |
2839 | 119..120 'f': |Option<i32>| -> () | 2891 | 93..94 'x': Option<i32> |
2840 | 122..123 's': Option<i32> | 2892 | 109..111 '{}': () |
2841 | "### | 2893 | 117..124 '(&f)(s)': () |
2894 | 118..120 '&f': &|Option<i32>| -> () | ||
2895 | 119..120 'f': |Option<i32>| -> () | ||
2896 | 122..123 's': Option<i32> | ||
2897 | "#]], | ||
2842 | ); | 2898 | ); |
2843 | } | 2899 | } |
2844 | 2900 | ||
2845 | #[test] | 2901 | #[test] |
2846 | fn infer_fn_trait_arg() { | 2902 | fn infer_fn_trait_arg() { |
2847 | assert_snapshot!( | 2903 | check_infer( |
2848 | infer( | 2904 | r#" |
2849 | r#" | 2905 | //- /lib.rs deps:std |
2850 | //- /lib.rs deps:std | ||
2851 | 2906 | ||
2852 | #[lang = "fn_once"] | 2907 | #[lang = "fn_once"] |
2853 | pub trait FnOnce<Args> { | 2908 | pub trait FnOnce<Args> { |
2854 | type Output; | 2909 | type Output; |
2855 | 2910 | ||
2856 | extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; | 2911 | extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; |
2857 | } | 2912 | } |
2858 | 2913 | ||
2859 | #[lang = "fn"] | 2914 | #[lang = "fn"] |
2860 | pub trait Fn<Args>:FnOnce<Args> { | 2915 | pub trait Fn<Args>:FnOnce<Args> { |
2861 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; | 2916 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; |
2862 | } | 2917 | } |
2863 | 2918 | ||
2864 | enum Option<T> { | 2919 | enum Option<T> { |
2865 | None, | 2920 | None, |
2866 | Some(T) | 2921 | Some(T) |
2867 | } | 2922 | } |
2868 | 2923 | ||
2869 | fn foo<F, T>(f: F) -> T | 2924 | fn foo<F, T>(f: F) -> T |
2870 | where | 2925 | where |
2871 | F: Fn(Option<i32>) -> T, | 2926 | F: Fn(Option<i32>) -> T, |
2872 | { | 2927 | { |
2873 | let s = None; | 2928 | let s = None; |
2874 | f(s) | 2929 | f(s) |
2875 | } | 2930 | } |
2876 | "# | 2931 | "#, |
2877 | ), | 2932 | expect![[r#" |
2878 | @r###" | 2933 | 101..105 'self': &Self |
2879 | 101..105 'self': &Self | 2934 | 107..111 'args': Args |
2880 | 107..111 'args': Args | 2935 | 220..224 'self': &Self |
2881 | 220..224 'self': &Self | 2936 | 226..230 'args': Args |
2882 | 226..230 'args': Args | 2937 | 313..314 'f': F |
2883 | 313..314 'f': F | 2938 | 359..389 '{ ...f(s) }': T |
2884 | 359..389 '{ ...f(s) }': T | 2939 | 369..370 's': Option<i32> |
2885 | 369..370 's': Option<i32> | 2940 | 373..377 'None': Option<i32> |
2886 | 373..377 'None': Option<i32> | 2941 | 383..384 'f': F |
2887 | 383..384 'f': F | 2942 | 383..387 'f(s)': T |
2888 | 383..387 'f(s)': T | 2943 | 385..386 's': Option<i32> |
2889 | 385..386 's': Option<i32> | 2944 | "#]], |
2890 | "### | ||
2891 | ); | 2945 | ); |
2892 | } | 2946 | } |
2893 | 2947 | ||
2894 | #[test] | 2948 | #[test] |
2895 | fn infer_box_fn_arg() { | 2949 | fn infer_box_fn_arg() { |
2896 | assert_snapshot!( | 2950 | check_infer( |
2897 | infer( | 2951 | r#" |
2898 | r#" | 2952 | //- /lib.rs deps:std |
2899 | //- /lib.rs deps:std | ||
2900 | 2953 | ||
2901 | #[lang = "fn_once"] | 2954 | #[lang = "fn_once"] |
2902 | pub trait FnOnce<Args> { | 2955 | pub trait FnOnce<Args> { |
2903 | type Output; | 2956 | type Output; |
2904 | 2957 | ||
2905 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | 2958 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; |
2906 | } | 2959 | } |
2907 | 2960 | ||
2908 | #[lang = "deref"] | 2961 | #[lang = "deref"] |
2909 | pub trait Deref { | 2962 | pub trait Deref { |
2910 | type Target: ?Sized; | 2963 | type Target: ?Sized; |
2911 | 2964 | ||
2912 | fn deref(&self) -> &Self::Target; | 2965 | fn deref(&self) -> &Self::Target; |
2913 | } | 2966 | } |
2914 | 2967 | ||
2915 | #[lang = "owned_box"] | 2968 | #[lang = "owned_box"] |
2916 | pub struct Box<T: ?Sized> { | 2969 | pub struct Box<T: ?Sized> { |
2917 | inner: *mut T, | 2970 | inner: *mut T, |
2918 | } | 2971 | } |
2919 | 2972 | ||
2920 | impl<T: ?Sized> Deref for Box<T> { | 2973 | impl<T: ?Sized> Deref for Box<T> { |
2921 | type Target = T; | 2974 | type Target = T; |
2922 | 2975 | ||
2923 | fn deref(&self) -> &T { | 2976 | fn deref(&self) -> &T { |
2924 | &self.inner | 2977 | &self.inner |
2925 | } | ||
2926 | } | 2978 | } |
2979 | } | ||
2927 | 2980 | ||
2928 | enum Option<T> { | 2981 | enum Option<T> { |
2929 | None, | 2982 | None, |
2930 | Some(T) | 2983 | Some(T) |
2931 | } | 2984 | } |
2932 | 2985 | ||
2933 | fn foo() { | 2986 | fn foo() { |
2934 | let s = Option::None; | 2987 | let s = Option::None; |
2935 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); | 2988 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); |
2936 | f(&s) | 2989 | f(&s) |
2937 | } | 2990 | } |
2938 | "# | 2991 | "#, |
2939 | ), | 2992 | expect![[r#" |
2940 | @r###" | 2993 | 100..104 'self': Self |
2941 | 100..104 'self': Self | 2994 | 106..110 'args': Args |
2942 | 106..110 'args': Args | 2995 | 214..218 'self': &Self |
2943 | 214..218 'self': &Self | 2996 | 384..388 'self': &Box<T> |
2944 | 384..388 'self': &Box<T> | 2997 | 396..423 '{ ... }': &T |
2945 | 396..423 '{ ... }': &T | 2998 | 406..417 '&self.inner': &*mut T |
2946 | 406..417 '&self.inner': &*mut T | 2999 | 407..411 'self': &Box<T> |
2947 | 407..411 'self': &Box<T> | 3000 | 407..417 'self.inner': *mut T |
2948 | 407..417 'self.inner': *mut T | 3001 | 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> |
2949 | 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> | 3002 | 488..489 's': Option<i32> |
2950 | 488..489 's': Option<i32> | 3003 | 492..504 'Option::None': Option<i32> |
2951 | 492..504 'Option::None': Option<i32> | 3004 | 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>> |
2952 | 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>> | 3005 | 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> |
2953 | 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> | 3006 | 554..561 '|ps| {}': |{unknown}| -> () |
2954 | 554..561 '|ps| {}': |{unknown}| -> () | 3007 | 555..557 'ps': {unknown} |
2955 | 555..557 'ps': {unknown} | 3008 | 559..561 '{}': () |
2956 | 559..561 '{}': () | 3009 | 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>> |
2957 | 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>> | 3010 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> |
2958 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> | 3011 | 570..572 '&s': &Option<i32> |
2959 | 570..572 '&s': &Option<i32> | 3012 | 571..572 's': Option<i32> |
2960 | 571..572 's': Option<i32> | 3013 | "#]], |
2961 | "### | ||
2962 | ); | 3014 | ); |
2963 | } | 3015 | } |
2964 | 3016 | ||
2965 | #[test] | 3017 | #[test] |
2966 | fn infer_dyn_fn_output() { | 3018 | fn infer_dyn_fn_output() { |
2967 | assert_snapshot!( | 3019 | check_types( |
2968 | infer( | 3020 | r#" |
2969 | r#" | 3021 | #[lang = "fn_once"] |
2970 | //- /lib.rs deps:std | 3022 | pub trait FnOnce<Args> { |
3023 | type Output; | ||
3024 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ||
3025 | } | ||
2971 | 3026 | ||
2972 | #[lang = "fn_once"] | 3027 | #[lang = "fn"] |
2973 | pub trait FnOnce<Args> { | 3028 | pub trait Fn<Args>: FnOnce<Args> { |
2974 | type Output; | 3029 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; |
3030 | } | ||
2975 | 3031 | ||
2976 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | 3032 | fn foo() { |
2977 | } | 3033 | let f: &dyn Fn() -> i32; |
3034 | f(); | ||
3035 | //^^^ i32 | ||
3036 | }"#, | ||
3037 | ); | ||
3038 | } | ||
2978 | 3039 | ||
2979 | #[lang = "fn"] | 3040 | #[test] |
2980 | pub trait Fn<Args>:FnOnce<Args> { | 3041 | fn infer_dyn_fn_once_output() { |
2981 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; | 3042 | check_types( |
2982 | } | 3043 | r#" |
3044 | #[lang = "fn_once"] | ||
3045 | pub trait FnOnce<Args> { | ||
3046 | type Output; | ||
3047 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ||
3048 | } | ||
2983 | 3049 | ||
2984 | #[lang = "deref"] | 3050 | fn foo() { |
2985 | pub trait Deref { | 3051 | let f: dyn FnOnce() -> i32; |
2986 | type Target: ?Sized; | 3052 | f(); |
3053 | //^^^ i32 | ||
3054 | }"#, | ||
3055 | ); | ||
3056 | } | ||
2987 | 3057 | ||
2988 | fn deref(&self) -> &Self::Target; | 3058 | #[test] |
2989 | } | 3059 | fn variable_kinds_1() { |
3060 | check_types( | ||
3061 | r#" | ||
3062 | trait Trait<T> { fn get(self, t: T) -> T; } | ||
3063 | struct S; | ||
3064 | impl Trait<u128> for S {} | ||
3065 | impl Trait<f32> for S {} | ||
3066 | fn test() { | ||
3067 | S.get(1); | ||
3068 | //^^^^^^^^ u128 | ||
3069 | S.get(1.); | ||
3070 | //^^^^^^^^ f32 | ||
3071 | } | ||
3072 | "#, | ||
3073 | ); | ||
3074 | } | ||
2990 | 3075 | ||
2991 | #[lang = "owned_box"] | 3076 | #[test] |
2992 | pub struct Box<T: ?Sized> { | 3077 | fn variable_kinds_2() { |
2993 | inner: *mut T, | 3078 | check_types( |
2994 | } | 3079 | r#" |
3080 | trait Trait { fn get(self) -> Self; } | ||
3081 | impl Trait for u128 {} | ||
3082 | impl Trait for f32 {} | ||
3083 | fn test() { | ||
3084 | 1.get(); | ||
3085 | //^^^^^^^ u128 | ||
3086 | (1.).get(); | ||
3087 | //^^^^^^^^^^ f32 | ||
3088 | } | ||
3089 | "#, | ||
3090 | ); | ||
3091 | } | ||
2995 | 3092 | ||
2996 | impl<T: ?Sized> Deref for Box<T> { | 3093 | #[test] |
2997 | type Target = T; | 3094 | fn underscore_import() { |
3095 | check_types( | ||
3096 | r#" | ||
3097 | mod tr { | ||
3098 | pub trait Tr { | ||
3099 | fn method(&self) -> u8 { 0 } | ||
3100 | } | ||
3101 | } | ||
2998 | 3102 | ||
2999 | fn deref(&self) -> &T { | 3103 | struct Tr; |
3000 | &self.inner | 3104 | impl crate::tr::Tr for Tr {} |
3001 | } | ||
3002 | } | ||
3003 | 3105 | ||
3004 | fn foo() { | 3106 | use crate::tr::Tr as _; |
3005 | let f: Box<dyn Fn() -> i32> = box(|| 5); | 3107 | fn test() { |
3006 | let x = f(); | 3108 | Tr.method(); |
3007 | } | 3109 | //^^^^^^^^^^^ u8 |
3008 | "# | 3110 | } |
3009 | ), | 3111 | "#, |
3010 | @r###" | ||
3011 | 100..104 'self': Self | ||
3012 | 106..110 'args': Args | ||
3013 | 219..223 'self': &Self | ||
3014 | 225..229 'args': Args | ||
3015 | 333..337 'self': &Self | ||
3016 | 503..507 'self': &Box<T> | ||
3017 | 515..542 '{ ... }': &T | ||
3018 | 525..536 '&self.inner': &*mut T | ||
3019 | 526..530 'self': &Box<T> | ||
3020 | 526..536 'self.inner': *mut T | ||
3021 | 555..620 '{ ...f(); }': () | ||
3022 | 565..566 'f': Box<dyn Fn<(), Output = i32>> | ||
3023 | 591..600 'box(|| 5)': Box<|| -> i32> | ||
3024 | 595..599 '|| 5': || -> i32 | ||
3025 | 598..599 '5': i32 | ||
3026 | 610..611 'x': FnOnce::Output<dyn Fn<(), Output = i32>, ()> | ||
3027 | 614..615 'f': Box<dyn Fn<(), Output = i32>> | ||
3028 | 614..617 'f()': FnOnce::Output<dyn Fn<(), Output = i32>, ()> | ||
3029 | "### | ||
3030 | ); | 3112 | ); |
3031 | } | 3113 | } |