diff options
| author | Aleksey Kladov <[email protected]> | 2019-11-27 14:46:02 +0000 |
|---|---|---|
| committer | Aleksey Kladov <[email protected]> | 2019-11-27 18:16:00 +0000 |
| commit | a87579500a2c35597071efd0ad6983927f0c1815 (patch) | |
| tree | 9805b3dcbf8d767b2fc0623f42794068f3660d44 /crates/ra_hir_ty/src/tests | |
| parent | 368653081558ab389c6543d6b5027859e26beb3b (diff) | |
Move Ty
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
| -rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 369 | ||||
| -rw-r--r-- | crates/ra_hir_ty/src/tests/never_type.rs | 246 |
2 files changed, 615 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs new file mode 100644 index 000000000..1530fcc63 --- /dev/null +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
| @@ -0,0 +1,369 @@ | |||
| 1 | use insta::assert_snapshot; | ||
| 2 | use test_utils::covers; | ||
| 3 | |||
| 4 | // Infer with some common definitions and impls. | ||
| 5 | fn infer(source: &str) -> String { | ||
| 6 | let defs = r#" | ||
| 7 | #[lang = "sized"] | ||
| 8 | pub trait Sized {} | ||
| 9 | #[lang = "unsize"] | ||
| 10 | pub trait Unsize<T: ?Sized> {} | ||
| 11 | #[lang = "coerce_unsized"] | ||
| 12 | pub trait CoerceUnsized<T> {} | ||
| 13 | |||
| 14 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} | ||
| 15 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} | ||
| 16 | "#; | ||
| 17 | |||
| 18 | // Append to the end to keep positions unchanged. | ||
| 19 | super::infer(&format!("{}{}", source, defs)) | ||
| 20 | } | ||
| 21 | |||
| 22 | #[test] | ||
| 23 | fn infer_block_expr_type_mismatch() { | ||
| 24 | assert_snapshot!( | ||
| 25 | infer(r#" | ||
| 26 | fn test() { | ||
| 27 | let a: i32 = { 1i64 }; | ||
| 28 | } | ||
| 29 | "#), | ||
| 30 | @r###" | ||
| 31 | [11; 41) '{ ...4 }; }': () | ||
| 32 | [21; 22) 'a': i32 | ||
| 33 | [30; 38) '{ 1i64 }': i64 | ||
| 34 | [32; 36) '1i64': i64 | ||
| 35 | "###); | ||
| 36 | } | ||
| 37 | |||
| 38 | #[test] | ||
| 39 | fn coerce_places() { | ||
| 40 | assert_snapshot!( | ||
| 41 | infer(r#" | ||
| 42 | struct S<T> { a: T } | ||
| 43 | |||
| 44 | fn f<T>(_: &[T]) -> T { loop {} } | ||
| 45 | fn g<T>(_: S<&[T]>) -> T { loop {} } | ||
| 46 | |||
| 47 | fn gen<T>() -> *mut [T; 2] { loop {} } | ||
| 48 | fn test1<U>() -> *mut [U] { | ||
| 49 | gen() | ||
| 50 | } | ||
| 51 | |||
| 52 | fn test2() { | ||
| 53 | let arr: &[u8; 1] = &[1]; | ||
| 54 | |||
| 55 | let a: &[_] = arr; | ||
| 56 | let b = f(arr); | ||
| 57 | let c: &[_] = { arr }; | ||
| 58 | let d = g(S { a: arr }); | ||
| 59 | let e: [&[_]; 1] = [arr]; | ||
| 60 | let f: [&[_]; 2] = [arr; 2]; | ||
| 61 | let g: (&[_], &[_]) = (arr, arr); | ||
| 62 | } | ||
| 63 | "#), | ||
| 64 | @r###" | ||
| 65 | [31; 32) '_': &[T] | ||
| 66 | [45; 56) '{ loop {} }': T | ||
| 67 | [47; 54) 'loop {}': ! | ||
| 68 | [52; 54) '{}': () | ||
| 69 | [65; 66) '_': S<&[T]> | ||
| 70 | [82; 93) '{ loop {} }': T | ||
| 71 | [84; 91) 'loop {}': ! | ||
| 72 | [89; 91) '{}': () | ||
| 73 | [122; 133) '{ loop {} }': *mut [T;_] | ||
| 74 | [124; 131) 'loop {}': ! | ||
| 75 | [129; 131) '{}': () | ||
| 76 | [160; 173) '{ gen() }': *mut [U] | ||
| 77 | [166; 169) 'gen': fn gen<U>() -> *mut [T;_] | ||
| 78 | [166; 171) 'gen()': *mut [U;_] | ||
| 79 | [186; 420) '{ ...rr); }': () | ||
| 80 | [196; 199) 'arr': &[u8;_] | ||
| 81 | [212; 216) '&[1]': &[u8;_] | ||
| 82 | [213; 216) '[1]': [u8;_] | ||
| 83 | [214; 215) '1': u8 | ||
| 84 | [227; 228) 'a': &[u8] | ||
| 85 | [237; 240) 'arr': &[u8;_] | ||
| 86 | [250; 251) 'b': u8 | ||
| 87 | [254; 255) 'f': fn f<u8>(&[T]) -> T | ||
| 88 | [254; 260) 'f(arr)': u8 | ||
| 89 | [256; 259) 'arr': &[u8;_] | ||
| 90 | [270; 271) 'c': &[u8] | ||
| 91 | [280; 287) '{ arr }': &[u8] | ||
| 92 | [282; 285) 'arr': &[u8;_] | ||
| 93 | [297; 298) 'd': u8 | ||
| 94 | [301; 302) 'g': fn g<u8>(S<&[T]>) -> T | ||
| 95 | [301; 316) 'g(S { a: arr })': u8 | ||
| 96 | [303; 315) 'S { a: arr }': S<&[u8]> | ||
| 97 | [310; 313) 'arr': &[u8;_] | ||
| 98 | [326; 327) 'e': [&[u8];_] | ||
| 99 | [341; 346) '[arr]': [&[u8];_] | ||
| 100 | [342; 345) 'arr': &[u8;_] | ||
| 101 | [356; 357) 'f': [&[u8];_] | ||
| 102 | [371; 379) '[arr; 2]': [&[u8];_] | ||
| 103 | [372; 375) 'arr': &[u8;_] | ||
| 104 | [377; 378) '2': usize | ||
| 105 | [389; 390) 'g': (&[u8], &[u8]) | ||
| 106 | [407; 417) '(arr, arr)': (&[u8], &[u8]) | ||
| 107 | [408; 411) 'arr': &[u8;_] | ||
| 108 | [413; 416) 'arr': &[u8;_] | ||
| 109 | "### | ||
| 110 | ); | ||
| 111 | } | ||
| 112 | |||
| 113 | #[test] | ||
| 114 | fn infer_let_stmt_coerce() { | ||
| 115 | assert_snapshot!( | ||
| 116 | infer(r#" | ||
| 117 | fn test() { | ||
| 118 | let x: &[i32] = &[1]; | ||
| 119 | } | ||
| 120 | "#), | ||
| 121 | @r###" | ||
| 122 | [11; 40) '{ ...[1]; }': () | ||
| 123 | [21; 22) 'x': &[i32] | ||
| 124 | [33; 37) '&[1]': &[i32;_] | ||
| 125 | [34; 37) '[1]': [i32;_] | ||
| 126 | [35; 36) '1': i32 | ||
| 127 | "###); | ||
| 128 | } | ||
| 129 | |||
| 130 | #[test] | ||
| 131 | fn infer_custom_coerce_unsized() { | ||
| 132 | assert_snapshot!( | ||
| 133 | infer(r#" | ||
| 134 | struct A<T: ?Sized>(*const T); | ||
| 135 | struct B<T: ?Sized>(*const T); | ||
| 136 | struct C<T: ?Sized> { inner: *const T } | ||
| 137 | |||
| 138 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} | ||
| 139 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} | ||
| 140 | |||
| 141 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } | ||
| 142 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } | ||
| 143 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } | ||
| 144 | |||
| 145 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { | ||
| 146 | let d = foo1(a); | ||
| 147 | let e = foo2(b); | ||
| 148 | let f = foo3(c); | ||
| 149 | } | ||
| 150 | "#), | ||
| 151 | @r###" | ||
| 152 | [258; 259) 'x': A<[T]> | ||
| 153 | [279; 284) '{ x }': A<[T]> | ||
| 154 | [281; 282) 'x': A<[T]> | ||
| 155 | [296; 297) 'x': B<[T]> | ||
| 156 | [317; 322) '{ x }': B<[T]> | ||
| 157 | [319; 320) 'x': B<[T]> | ||
| 158 | [334; 335) 'x': C<[T]> | ||
| 159 | [355; 360) '{ x }': C<[T]> | ||
| 160 | [357; 358) 'x': C<[T]> | ||
| 161 | [370; 371) 'a': A<[u8;_]> | ||
| 162 | [385; 386) 'b': B<[u8;_]> | ||
| 163 | [400; 401) 'c': C<[u8;_]> | ||
| 164 | [415; 481) '{ ...(c); }': () | ||
| 165 | [425; 426) 'd': A<[{unknown}]> | ||
| 166 | [429; 433) 'foo1': fn foo1<{unknown}>(A<[T]>) -> A<[T]> | ||
| 167 | [429; 436) 'foo1(a)': A<[{unknown}]> | ||
| 168 | [434; 435) 'a': A<[u8;_]> | ||
| 169 | [446; 447) 'e': B<[u8]> | ||
| 170 | [450; 454) 'foo2': fn foo2<u8>(B<[T]>) -> B<[T]> | ||
| 171 | [450; 457) 'foo2(b)': B<[u8]> | ||
| 172 | [455; 456) 'b': B<[u8;_]> | ||
| 173 | [467; 468) 'f': C<[u8]> | ||
| 174 | [471; 475) 'foo3': fn foo3<u8>(C<[T]>) -> C<[T]> | ||
| 175 | [471; 478) 'foo3(c)': C<[u8]> | ||
| 176 | [476; 477) 'c': C<[u8;_]> | ||
| 177 | "### | ||
| 178 | ); | ||
| 179 | } | ||
| 180 | |||
| 181 | #[test] | ||
| 182 | fn infer_if_coerce() { | ||
| 183 | assert_snapshot!( | ||
| 184 | infer(r#" | ||
| 185 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
| 186 | fn test() { | ||
| 187 | let x = if true { | ||
| 188 | foo(&[1]) | ||
| 189 | } else { | ||
| 190 | &[1] | ||
| 191 | }; | ||
| 192 | } | ||
| 193 | "#), | ||
| 194 | @r###" | ||
| 195 | [11; 12) 'x': &[T] | ||
| 196 | [28; 39) '{ loop {} }': &[T] | ||
| 197 | [30; 37) 'loop {}': ! | ||
| 198 | [35; 37) '{}': () | ||
| 199 | [50; 126) '{ ... }; }': () | ||
| 200 | [60; 61) 'x': &[i32] | ||
| 201 | [64; 123) 'if tru... }': &[i32] | ||
| 202 | [67; 71) 'true': bool | ||
| 203 | [72; 97) '{ ... }': &[i32] | ||
| 204 | [82; 85) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
| 205 | [82; 91) 'foo(&[1])': &[i32] | ||
| 206 | [86; 90) '&[1]': &[i32;_] | ||
| 207 | [87; 90) '[1]': [i32;_] | ||
| 208 | [88; 89) '1': i32 | ||
| 209 | [103; 123) '{ ... }': &[i32;_] | ||
| 210 | [113; 117) '&[1]': &[i32;_] | ||
| 211 | [114; 117) '[1]': [i32;_] | ||
| 212 | [115; 116) '1': i32 | ||
| 213 | "### | ||
| 214 | ); | ||
| 215 | } | ||
| 216 | |||
| 217 | #[test] | ||
| 218 | fn infer_if_else_coerce() { | ||
| 219 | assert_snapshot!( | ||
| 220 | infer(r#" | ||
| 221 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
| 222 | fn test() { | ||
| 223 | let x = if true { | ||
| 224 | &[1] | ||
| 225 | } else { | ||
| 226 | foo(&[1]) | ||
| 227 | }; | ||
| 228 | } | ||
| 229 | "#), | ||
| 230 | @r###" | ||
| 231 | [11; 12) 'x': &[T] | ||
| 232 | [28; 39) '{ loop {} }': &[T] | ||
| 233 | [30; 37) 'loop {}': ! | ||
| 234 | [35; 37) '{}': () | ||
| 235 | [50; 126) '{ ... }; }': () | ||
| 236 | [60; 61) 'x': &[i32] | ||
| 237 | [64; 123) 'if tru... }': &[i32] | ||
| 238 | [67; 71) 'true': bool | ||
| 239 | [72; 92) '{ ... }': &[i32;_] | ||
| 240 | [82; 86) '&[1]': &[i32;_] | ||
| 241 | [83; 86) '[1]': [i32;_] | ||
| 242 | [84; 85) '1': i32 | ||
| 243 | [98; 123) '{ ... }': &[i32] | ||
| 244 | [108; 111) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
| 245 | [108; 117) 'foo(&[1])': &[i32] | ||
| 246 | [112; 116) '&[1]': &[i32;_] | ||
| 247 | [113; 116) '[1]': [i32;_] | ||
| 248 | [114; 115) '1': i32 | ||
| 249 | "### | ||
| 250 | ); | ||
| 251 | } | ||
| 252 | |||
| 253 | #[test] | ||
| 254 | fn infer_match_first_coerce() { | ||
| 255 | assert_snapshot!( | ||
| 256 | infer(r#" | ||
| 257 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
| 258 | fn test(i: i32) { | ||
| 259 | let x = match i { | ||
| 260 | 2 => foo(&[2]), | ||
| 261 | 1 => &[1], | ||
| 262 | _ => &[3], | ||
| 263 | }; | ||
| 264 | } | ||
| 265 | "#), | ||
| 266 | @r###" | ||
| 267 | [11; 12) 'x': &[T] | ||
| 268 | [28; 39) '{ loop {} }': &[T] | ||
| 269 | [30; 37) 'loop {}': ! | ||
| 270 | [35; 37) '{}': () | ||
| 271 | [48; 49) 'i': i32 | ||
| 272 | [56; 150) '{ ... }; }': () | ||
| 273 | [66; 67) 'x': &[i32] | ||
| 274 | [70; 147) 'match ... }': &[i32] | ||
| 275 | [76; 77) 'i': i32 | ||
| 276 | [88; 89) '2': i32 | ||
| 277 | [93; 96) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
| 278 | [93; 102) 'foo(&[2])': &[i32] | ||
| 279 | [97; 101) '&[2]': &[i32;_] | ||
| 280 | [98; 101) '[2]': [i32;_] | ||
| 281 | [99; 100) '2': i32 | ||
| 282 | [112; 113) '1': i32 | ||
| 283 | [117; 121) '&[1]': &[i32;_] | ||
| 284 | [118; 121) '[1]': [i32;_] | ||
| 285 | [119; 120) '1': i32 | ||
| 286 | [131; 132) '_': i32 | ||
| 287 | [136; 140) '&[3]': &[i32;_] | ||
| 288 | [137; 140) '[3]': [i32;_] | ||
| 289 | [138; 139) '3': i32 | ||
| 290 | "### | ||
| 291 | ); | ||
| 292 | } | ||
| 293 | |||
| 294 | #[test] | ||
| 295 | fn infer_match_second_coerce() { | ||
| 296 | assert_snapshot!( | ||
| 297 | infer(r#" | ||
| 298 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | ||
| 299 | fn test(i: i32) { | ||
| 300 | let x = match i { | ||
| 301 | 1 => &[1], | ||
| 302 | 2 => foo(&[2]), | ||
| 303 | _ => &[3], | ||
| 304 | }; | ||
| 305 | } | ||
| 306 | "#), | ||
| 307 | @r###" | ||
| 308 | [11; 12) 'x': &[T] | ||
| 309 | [28; 39) '{ loop {} }': &[T] | ||
| 310 | [30; 37) 'loop {}': ! | ||
| 311 | [35; 37) '{}': () | ||
| 312 | [48; 49) 'i': i32 | ||
| 313 | [56; 150) '{ ... }; }': () | ||
| 314 | [66; 67) 'x': &[i32] | ||
| 315 | [70; 147) 'match ... }': &[i32] | ||
| 316 | [76; 77) 'i': i32 | ||
| 317 | [88; 89) '1': i32 | ||
| 318 | [93; 97) '&[1]': &[i32;_] | ||
| 319 | [94; 97) '[1]': [i32;_] | ||
| 320 | [95; 96) '1': i32 | ||
| 321 | [107; 108) '2': i32 | ||
| 322 | [112; 115) 'foo': fn foo<i32>(&[T]) -> &[T] | ||
| 323 | [112; 121) 'foo(&[2])': &[i32] | ||
| 324 | [116; 120) '&[2]': &[i32;_] | ||
| 325 | [117; 120) '[2]': [i32;_] | ||
| 326 | [118; 119) '2': i32 | ||
| 327 | [131; 132) '_': i32 | ||
| 328 | [136; 140) '&[3]': &[i32;_] | ||
| 329 | [137; 140) '[3]': [i32;_] | ||
| 330 | [138; 139) '3': i32 | ||
| 331 | "### | ||
| 332 | ); | ||
| 333 | } | ||
| 334 | |||
| 335 | #[test] | ||
| 336 | fn coerce_merge_one_by_one1() { | ||
| 337 | covers!(coerce_merge_fail_fallback); | ||
| 338 | |||
| 339 | assert_snapshot!( | ||
| 340 | infer(r#" | ||
| 341 | fn test() { | ||
| 342 | let t = &mut 1; | ||
| 343 | let x = match 1 { | ||
| 344 | 1 => t as *mut i32, | ||
| 345 | 2 => t as &i32, | ||
| 346 | _ => t as *const i32, | ||
| 347 | }; | ||
| 348 | } | ||
| 349 | "#), | ||
| 350 | @r###" | ||
| 351 | [11; 145) '{ ... }; }': () | ||
| 352 | [21; 22) 't': &mut i32 | ||
| 353 | [25; 31) '&mut 1': &mut i32 | ||
| 354 | [30; 31) '1': i32 | ||
| 355 | [41; 42) 'x': *const i32 | ||
| 356 | [45; 142) 'match ... }': *const i32 | ||
| 357 | [51; 52) '1': i32 | ||
| 358 | [63; 64) '1': i32 | ||
| 359 | [68; 69) 't': &mut i32 | ||
| 360 | [68; 81) 't as *mut i32': *mut i32 | ||
| 361 | [91; 92) '2': i32 | ||
| 362 | [96; 97) 't': &mut i32 | ||
| 363 | [96; 105) 't as &i32': &i32 | ||
| 364 | [115; 116) '_': i32 | ||
| 365 | [120; 121) 't': &mut i32 | ||
| 366 | [120; 135) 't as *const i32': *const i32 | ||
| 367 | "### | ||
| 368 | ); | ||
| 369 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs new file mode 100644 index 000000000..c202f545a --- /dev/null +++ b/crates/ra_hir_ty/src/tests/never_type.rs | |||
| @@ -0,0 +1,246 @@ | |||
| 1 | use super::type_at; | ||
| 2 | |||
| 3 | #[test] | ||
| 4 | fn infer_never1() { | ||
| 5 | let t = type_at( | ||
| 6 | r#" | ||
| 7 | //- /main.rs | ||
| 8 | fn test() { | ||
| 9 | let t = return; | ||
| 10 | t<|>; | ||
| 11 | } | ||
| 12 | "#, | ||
| 13 | ); | ||
| 14 | assert_eq!(t, "!"); | ||
| 15 | } | ||
| 16 | |||
| 17 | #[test] | ||
| 18 | fn infer_never2() { | ||
| 19 | let t = type_at( | ||
| 20 | r#" | ||
| 21 | //- /main.rs | ||
| 22 | fn gen<T>() -> T { loop {} } | ||
| 23 | |||
| 24 | fn test() { | ||
| 25 | let a = gen(); | ||
| 26 | if false { a } else { loop {} }; | ||
| 27 | a<|>; | ||
| 28 | } | ||
| 29 | "#, | ||
| 30 | ); | ||
| 31 | assert_eq!(t, "!"); | ||
| 32 | } | ||
| 33 | |||
| 34 | #[test] | ||
| 35 | fn infer_never3() { | ||
| 36 | let t = type_at( | ||
| 37 | r#" | ||
| 38 | //- /main.rs | ||
| 39 | fn gen<T>() -> T { loop {} } | ||
| 40 | |||
| 41 | fn test() { | ||
| 42 | let a = gen(); | ||
| 43 | if false { loop {} } else { a }; | ||
| 44 | a<|>; | ||
| 45 | } | ||
| 46 | "#, | ||
| 47 | ); | ||
| 48 | assert_eq!(t, "!"); | ||
| 49 | } | ||
| 50 | |||
| 51 | #[test] | ||
| 52 | fn never_type_in_generic_args() { | ||
| 53 | let t = type_at( | ||
| 54 | r#" | ||
| 55 | //- /main.rs | ||
| 56 | enum Option<T> { None, Some(T) } | ||
| 57 | |||
| 58 | fn test() { | ||
| 59 | let a = if true { Option::None } else { Option::Some(return) }; | ||
| 60 | a<|>; | ||
| 61 | } | ||
| 62 | "#, | ||
| 63 | ); | ||
| 64 | assert_eq!(t, "Option<!>"); | ||
| 65 | } | ||
| 66 | |||
| 67 | #[test] | ||
| 68 | fn never_type_can_be_reinferred1() { | ||
| 69 | let t = type_at( | ||
| 70 | r#" | ||
| 71 | //- /main.rs | ||
| 72 | fn gen<T>() -> T { loop {} } | ||
| 73 | |||
| 74 | fn test() { | ||
| 75 | let a = gen(); | ||
| 76 | if false { loop {} } else { a }; | ||
| 77 | a<|>; | ||
| 78 | if false { a }; | ||
| 79 | } | ||
| 80 | "#, | ||
| 81 | ); | ||
| 82 | assert_eq!(t, "()"); | ||
| 83 | } | ||
| 84 | |||
| 85 | #[test] | ||
| 86 | fn never_type_can_be_reinferred2() { | ||
| 87 | let t = type_at( | ||
| 88 | r#" | ||
| 89 | //- /main.rs | ||
| 90 | enum Option<T> { None, Some(T) } | ||
| 91 | |||
| 92 | fn test() { | ||
| 93 | let a = if true { Option::None } else { Option::Some(return) }; | ||
| 94 | a<|>; | ||
| 95 | match 42 { | ||
| 96 | 42 => a, | ||
| 97 | _ => Option::Some(42), | ||
| 98 | }; | ||
| 99 | } | ||
| 100 | "#, | ||
| 101 | ); | ||
| 102 | assert_eq!(t, "Option<i32>"); | ||
| 103 | } | ||
| 104 | #[test] | ||
| 105 | fn never_type_can_be_reinferred3() { | ||
| 106 | let t = type_at( | ||
| 107 | r#" | ||
| 108 | //- /main.rs | ||
| 109 | enum Option<T> { None, Some(T) } | ||
| 110 | |||
| 111 | fn test() { | ||
| 112 | let a = if true { Option::None } else { Option::Some(return) }; | ||
| 113 | a<|>; | ||
| 114 | match 42 { | ||
| 115 | 42 => a, | ||
| 116 | _ => Option::Some("str"), | ||
| 117 | }; | ||
| 118 | } | ||
| 119 | "#, | ||
| 120 | ); | ||
| 121 | assert_eq!(t, "Option<&str>"); | ||
| 122 | } | ||
| 123 | |||
| 124 | #[test] | ||
| 125 | fn match_no_arm() { | ||
| 126 | let t = type_at( | ||
| 127 | r#" | ||
| 128 | //- /main.rs | ||
| 129 | enum Void {} | ||
| 130 | |||
| 131 | fn test(a: Void) { | ||
| 132 | let t = match a {}; | ||
| 133 | t<|>; | ||
| 134 | } | ||
| 135 | "#, | ||
| 136 | ); | ||
| 137 | assert_eq!(t, "!"); | ||
| 138 | } | ||
| 139 | |||
| 140 | #[test] | ||
| 141 | fn if_never() { | ||
| 142 | let t = type_at( | ||
| 143 | r#" | ||
| 144 | //- /main.rs | ||
| 145 | fn test() { | ||
| 146 | let i = if true { | ||
| 147 | loop {} | ||
| 148 | } else { | ||
| 149 | 3.0 | ||
| 150 | }; | ||
| 151 | i<|>; | ||
| 152 | } | ||
| 153 | "#, | ||
| 154 | ); | ||
| 155 | assert_eq!(t, "f64"); | ||
| 156 | } | ||
| 157 | |||
| 158 | #[test] | ||
| 159 | fn if_else_never() { | ||
| 160 | let t = type_at( | ||
| 161 | r#" | ||
| 162 | //- /main.rs | ||
| 163 | fn test(input: bool) { | ||
| 164 | let i = if input { | ||
| 165 | 2.0 | ||
| 166 | } else { | ||
| 167 | return | ||
| 168 | }; | ||
| 169 | i<|>; | ||
| 170 | } | ||
| 171 | "#, | ||
| 172 | ); | ||
| 173 | assert_eq!(t, "f64"); | ||
| 174 | } | ||
| 175 | |||
| 176 | #[test] | ||
| 177 | fn match_first_arm_never() { | ||
| 178 | let t = type_at( | ||
| 179 | r#" | ||
| 180 | //- /main.rs | ||
| 181 | fn test(a: i32) { | ||
| 182 | let i = match a { | ||
| 183 | 1 => return, | ||
| 184 | 2 => 2.0, | ||
| 185 | 3 => loop {}, | ||
| 186 | _ => 3.0, | ||
| 187 | }; | ||
| 188 | i<|>; | ||
| 189 | } | ||
| 190 | "#, | ||
| 191 | ); | ||
| 192 | assert_eq!(t, "f64"); | ||
| 193 | } | ||
| 194 | |||
| 195 | #[test] | ||
| 196 | fn match_second_arm_never() { | ||
| 197 | let t = type_at( | ||
| 198 | r#" | ||
| 199 | //- /main.rs | ||
| 200 | fn test(a: i32) { | ||
| 201 | let i = match a { | ||
| 202 | 1 => 3.0, | ||
| 203 | 2 => loop {}, | ||
| 204 | 3 => 3.0, | ||
| 205 | _ => return, | ||
| 206 | }; | ||
| 207 | i<|>; | ||
| 208 | } | ||
| 209 | "#, | ||
| 210 | ); | ||
| 211 | assert_eq!(t, "f64"); | ||
| 212 | } | ||
| 213 | |||
| 214 | #[test] | ||
| 215 | fn match_all_arms_never() { | ||
| 216 | let t = type_at( | ||
| 217 | r#" | ||
| 218 | //- /main.rs | ||
| 219 | fn test(a: i32) { | ||
| 220 | let i = match a { | ||
| 221 | 2 => return, | ||
| 222 | _ => loop {}, | ||
| 223 | }; | ||
| 224 | i<|>; | ||
| 225 | } | ||
| 226 | "#, | ||
| 227 | ); | ||
| 228 | assert_eq!(t, "!"); | ||
| 229 | } | ||
| 230 | |||
| 231 | #[test] | ||
| 232 | fn match_no_never_arms() { | ||
| 233 | let t = type_at( | ||
| 234 | r#" | ||
| 235 | //- /main.rs | ||
| 236 | fn test(a: i32) { | ||
| 237 | let i = match a { | ||
| 238 | 2 => 2.0, | ||
| 239 | _ => 3.0, | ||
| 240 | }; | ||
| 241 | i<|>; | ||
| 242 | } | ||
| 243 | "#, | ||
| 244 | ); | ||
| 245 | assert_eq!(t, "f64"); | ||
| 246 | } | ||
