From b82899ad764502eab0ee1410afb42888bbd5099e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 20 Jul 2020 19:23:32 +0300 Subject: Use expect in coercion tests --- crates/ra_hir_ty/src/tests/coercion.rs | 1358 ++++++++++++++++---------------- 1 file changed, 684 insertions(+), 674 deletions(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index d7fb6a962..7704774b7 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -1,10 +1,9 @@ -use insta::assert_snapshot; use test_utils::mark; -use super::infer_with_mismatches; +use expect::{expect, Expect}; // Infer with some common definitions and impls. -fn infer(source: &str) -> String { +fn check_infer(ra_fixture: &str, expect: Expect) { let defs = r#" #[lang = "sized"] pub trait Sized {} @@ -18,328 +17,338 @@ fn infer(source: &str) -> String { "#; // Append to the end to keep positions unchanged. - super::infer(&format!("{}{}", source, defs)) + let mut actual = super::infer(&format!("{}{}", ra_fixture, defs)); + actual.push('\n'); + expect.assert_eq(&actual); +} + +fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) { + let mut actual = super::infer_with_mismatches(ra_fixture, true); + actual.push('\n'); + expect.assert_eq(&actual); } #[test] fn infer_block_expr_type_mismatch() { - assert_snapshot!( - infer(r#" -fn test() { - let a: i32 = { 1i64 }; -} -"#), - @r###" - 10..40 '{ ...4 }; }': () - 20..21 'a': i32 - 29..37 '{ 1i64 }': i64 - 31..35 '1i64': i64 - "###); + check_infer( + r" + fn test() { + let a: i32 = { 1i64 }; + } + ", + expect![[r" + 10..40 '{ ...4 }; }': () + 20..21 'a': i32 + 29..37 '{ 1i64 }': i64 + 31..35 '1i64': i64 + "]], + ); } #[test] fn coerce_places() { - assert_snapshot!( - infer(r#" -struct S { a: T } + check_infer( + r" + struct S { a: T } -fn f(_: &[T]) -> T { loop {} } -fn g(_: S<&[T]>) -> T { loop {} } + fn f(_: &[T]) -> T { loop {} } + fn g(_: S<&[T]>) -> T { loop {} } -fn gen() -> *mut [T; 2] { loop {} } -fn test1() -> *mut [U] { - gen() -} + fn gen() -> *mut [T; 2] { loop {} } + fn test1() -> *mut [U] { + gen() + } -fn test2() { - let arr: &[u8; 1] = &[1]; + fn test2() { + let arr: &[u8; 1] = &[1]; - let a: &[_] = arr; - let b = f(arr); - let c: &[_] = { arr }; - let d = g(S { a: arr }); - let e: [&[_]; 1] = [arr]; - let f: [&[_]; 2] = [arr; 2]; - let g: (&[_], &[_]) = (arr, arr); -} -"#), - @r###" - 30..31 '_': &[T] - 44..55 '{ loop {} }': T - 46..53 'loop {}': ! - 51..53 '{}': () - 64..65 '_': S<&[T]> - 81..92 '{ loop {} }': T - 83..90 'loop {}': ! - 88..90 '{}': () - 121..132 '{ loop {} }': *mut [T; _] - 123..130 'loop {}': ! - 128..130 '{}': () - 159..172 '{ gen() }': *mut [U] - 165..168 'gen': fn gen() -> *mut [U; _] - 165..170 'gen()': *mut [U; _] - 185..419 '{ ...rr); }': () - 195..198 'arr': &[u8; _] - 211..215 '&[1]': &[u8; _] - 212..215 '[1]': [u8; _] - 213..214 '1': u8 - 226..227 'a': &[u8] - 236..239 'arr': &[u8; _] - 249..250 'b': u8 - 253..254 'f': fn f(&[u8]) -> u8 - 253..259 'f(arr)': u8 - 255..258 'arr': &[u8; _] - 269..270 'c': &[u8] - 279..286 '{ arr }': &[u8] - 281..284 'arr': &[u8; _] - 296..297 'd': u8 - 300..301 'g': fn g(S<&[u8]>) -> u8 - 300..315 'g(S { a: arr })': u8 - 302..314 'S { a: arr }': S<&[u8]> - 309..312 'arr': &[u8; _] - 325..326 'e': [&[u8]; _] - 340..345 '[arr]': [&[u8]; _] - 341..344 'arr': &[u8; _] - 355..356 'f': [&[u8]; _] - 370..378 '[arr; 2]': [&[u8]; _] - 371..374 'arr': &[u8; _] - 376..377 '2': usize - 388..389 'g': (&[u8], &[u8]) - 406..416 '(arr, arr)': (&[u8], &[u8]) - 407..410 'arr': &[u8; _] - 412..415 'arr': &[u8; _] - "### + let a: &[_] = arr; + let b = f(arr); + let c: &[_] = { arr }; + let d = g(S { a: arr }); + let e: [&[_]; 1] = [arr]; + let f: [&[_]; 2] = [arr; 2]; + let g: (&[_], &[_]) = (arr, arr); + } + ", + expect![[r" + 30..31 '_': &[T] + 44..55 '{ loop {} }': T + 46..53 'loop {}': ! + 51..53 '{}': () + 64..65 '_': S<&[T]> + 81..92 '{ loop {} }': T + 83..90 'loop {}': ! + 88..90 '{}': () + 121..132 '{ loop {} }': *mut [T; _] + 123..130 'loop {}': ! + 128..130 '{}': () + 159..172 '{ gen() }': *mut [U] + 165..168 'gen': fn gen() -> *mut [U; _] + 165..170 'gen()': *mut [U; _] + 185..419 '{ ...rr); }': () + 195..198 'arr': &[u8; _] + 211..215 '&[1]': &[u8; _] + 212..215 '[1]': [u8; _] + 213..214 '1': u8 + 226..227 'a': &[u8] + 236..239 'arr': &[u8; _] + 249..250 'b': u8 + 253..254 'f': fn f(&[u8]) -> u8 + 253..259 'f(arr)': u8 + 255..258 'arr': &[u8; _] + 269..270 'c': &[u8] + 279..286 '{ arr }': &[u8] + 281..284 'arr': &[u8; _] + 296..297 'd': u8 + 300..301 'g': fn g(S<&[u8]>) -> u8 + 300..315 'g(S { a: arr })': u8 + 302..314 'S { a: arr }': S<&[u8]> + 309..312 'arr': &[u8; _] + 325..326 'e': [&[u8]; _] + 340..345 '[arr]': [&[u8]; _] + 341..344 'arr': &[u8; _] + 355..356 'f': [&[u8]; _] + 370..378 '[arr; 2]': [&[u8]; _] + 371..374 'arr': &[u8; _] + 376..377 '2': usize + 388..389 'g': (&[u8], &[u8]) + 406..416 '(arr, arr)': (&[u8], &[u8]) + 407..410 'arr': &[u8; _] + 412..415 'arr': &[u8; _] + "]], ); } #[test] fn infer_let_stmt_coerce() { - assert_snapshot!( - infer(r#" -fn test() { - let x: &[isize] = &[1]; - let x: *const [isize] = &[1]; -} -"#), - @r###" - 10..75 '{ ...[1]; }': () - 20..21 'x': &[isize] - 34..38 '&[1]': &[isize; _] - 35..38 '[1]': [isize; _] - 36..37 '1': isize - 48..49 'x': *const [isize] - 68..72 '&[1]': &[isize; _] - 69..72 '[1]': [isize; _] - 70..71 '1': isize - "###); + check_infer( + r" + fn test() { + let x: &[isize] = &[1]; + let x: *const [isize] = &[1]; + } + ", + expect![[r" + 10..75 '{ ...[1]; }': () + 20..21 'x': &[isize] + 34..38 '&[1]': &[isize; _] + 35..38 '[1]': [isize; _] + 36..37 '1': isize + 48..49 'x': *const [isize] + 68..72 '&[1]': &[isize; _] + 69..72 '[1]': [isize; _] + 70..71 '1': isize + "]], + ); } #[test] fn infer_custom_coerce_unsized() { - assert_snapshot!( - infer(r#" -struct A(*const T); -struct B(*const T); -struct C { inner: *const T } - -impl, U: ?Sized> CoerceUnsized> for B {} -impl, U: ?Sized> CoerceUnsized> for C {} - -fn foo1(x: A<[T]>) -> A<[T]> { x } -fn foo2(x: B<[T]>) -> B<[T]> { x } -fn foo3(x: C<[T]>) -> C<[T]> { x } - -fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { - let d = foo1(a); - let e = foo2(b); - let f = foo3(c); -} -"#), - @r###" - 257..258 'x': A<[T]> - 278..283 '{ x }': A<[T]> - 280..281 'x': A<[T]> - 295..296 'x': B<[T]> - 316..321 '{ x }': B<[T]> - 318..319 'x': B<[T]> - 333..334 'x': C<[T]> - 354..359 '{ x }': C<[T]> - 356..357 'x': C<[T]> - 369..370 'a': A<[u8; _]> - 384..385 'b': B<[u8; _]> - 399..400 'c': C<[u8; _]> - 414..480 '{ ...(c); }': () - 424..425 'd': A<[{unknown}]> - 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> - 428..435 'foo1(a)': A<[{unknown}]> - 433..434 'a': A<[u8; _]> - 445..446 'e': B<[u8]> - 449..453 'foo2': fn foo2(B<[u8]>) -> B<[u8]> - 449..456 'foo2(b)': B<[u8]> - 454..455 'b': B<[u8; _]> - 466..467 'f': C<[u8]> - 470..474 'foo3': fn foo3(C<[u8]>) -> C<[u8]> - 470..477 'foo3(c)': C<[u8]> - 475..476 'c': C<[u8; _]> - "### + check_infer( + r" + struct A(*const T); + struct B(*const T); + struct C { inner: *const T } + + impl, U: ?Sized> CoerceUnsized> for B {} + impl, U: ?Sized> CoerceUnsized> for C {} + + fn foo1(x: A<[T]>) -> A<[T]> { x } + fn foo2(x: B<[T]>) -> B<[T]> { x } + fn foo3(x: C<[T]>) -> C<[T]> { x } + + fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { + let d = foo1(a); + let e = foo2(b); + let f = foo3(c); + } + ", + expect![[r" + 257..258 'x': A<[T]> + 278..283 '{ x }': A<[T]> + 280..281 'x': A<[T]> + 295..296 'x': B<[T]> + 316..321 '{ x }': B<[T]> + 318..319 'x': B<[T]> + 333..334 'x': C<[T]> + 354..359 '{ x }': C<[T]> + 356..357 'x': C<[T]> + 369..370 'a': A<[u8; _]> + 384..385 'b': B<[u8; _]> + 399..400 'c': C<[u8; _]> + 414..480 '{ ...(c); }': () + 424..425 'd': A<[{unknown}]> + 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> + 428..435 'foo1(a)': A<[{unknown}]> + 433..434 'a': A<[u8; _]> + 445..446 'e': B<[u8]> + 449..453 'foo2': fn foo2(B<[u8]>) -> B<[u8]> + 449..456 'foo2(b)': B<[u8]> + 454..455 'b': B<[u8; _]> + 466..467 'f': C<[u8]> + 470..474 'foo3': fn foo3(C<[u8]>) -> C<[u8]> + 470..477 'foo3(c)': C<[u8]> + 475..476 'c': C<[u8; _]> + "]], ); } #[test] fn infer_if_coerce() { - assert_snapshot!( - infer(r#" -fn foo(x: &[T]) -> &[T] { loop {} } -fn test() { - let x = if true { - foo(&[1]) - } else { - &[1] - }; -} -"#), - @r###" - 10..11 'x': &[T] - 27..38 '{ loop {} }': &[T] - 29..36 'loop {}': ! - 34..36 '{}': () - 49..125 '{ ... }; }': () - 59..60 'x': &[i32] - 63..122 'if tru... }': &[i32] - 66..70 'true': bool - 71..96 '{ ... }': &[i32] - 81..84 'foo': fn foo(&[i32]) -> &[i32] - 81..90 'foo(&[1])': &[i32] - 85..89 '&[1]': &[i32; _] - 86..89 '[1]': [i32; _] - 87..88 '1': i32 - 102..122 '{ ... }': &[i32; _] - 112..116 '&[1]': &[i32; _] - 113..116 '[1]': [i32; _] - 114..115 '1': i32 - "### + check_infer( + r" + fn foo(x: &[T]) -> &[T] { loop {} } + fn test() { + let x = if true { + foo(&[1]) + } else { + &[1] + }; + } + ", + expect![[r" + 10..11 'x': &[T] + 27..38 '{ loop {} }': &[T] + 29..36 'loop {}': ! + 34..36 '{}': () + 49..125 '{ ... }; }': () + 59..60 'x': &[i32] + 63..122 'if tru... }': &[i32] + 66..70 'true': bool + 71..96 '{ ... }': &[i32] + 81..84 'foo': fn foo(&[i32]) -> &[i32] + 81..90 'foo(&[1])': &[i32] + 85..89 '&[1]': &[i32; _] + 86..89 '[1]': [i32; _] + 87..88 '1': i32 + 102..122 '{ ... }': &[i32; _] + 112..116 '&[1]': &[i32; _] + 113..116 '[1]': [i32; _] + 114..115 '1': i32 + "]], ); } #[test] fn infer_if_else_coerce() { - assert_snapshot!( - infer(r#" -fn foo(x: &[T]) -> &[T] { loop {} } -fn test() { - let x = if true { - &[1] - } else { - foo(&[1]) - }; -} -"#), - @r###" - 10..11 'x': &[T] - 27..38 '{ loop {} }': &[T] - 29..36 'loop {}': ! - 34..36 '{}': () - 49..125 '{ ... }; }': () - 59..60 'x': &[i32] - 63..122 'if tru... }': &[i32] - 66..70 'true': bool - 71..91 '{ ... }': &[i32; _] - 81..85 '&[1]': &[i32; _] - 82..85 '[1]': [i32; _] - 83..84 '1': i32 - 97..122 '{ ... }': &[i32] - 107..110 'foo': fn foo(&[i32]) -> &[i32] - 107..116 'foo(&[1])': &[i32] - 111..115 '&[1]': &[i32; _] - 112..115 '[1]': [i32; _] - 113..114 '1': i32 - "### - ); + check_infer( + r" + fn foo(x: &[T]) -> &[T] { loop {} } + fn test() { + let x = if true { + &[1] + } else { + foo(&[1]) + }; + } + ", + expect![[r" + 10..11 'x': &[T] + 27..38 '{ loop {} }': &[T] + 29..36 'loop {}': ! + 34..36 '{}': () + 49..125 '{ ... }; }': () + 59..60 'x': &[i32] + 63..122 'if tru... }': &[i32] + 66..70 'true': bool + 71..91 '{ ... }': &[i32; _] + 81..85 '&[1]': &[i32; _] + 82..85 '[1]': [i32; _] + 83..84 '1': i32 + 97..122 '{ ... }': &[i32] + 107..110 'foo': fn foo(&[i32]) -> &[i32] + 107..116 'foo(&[1])': &[i32] + 111..115 '&[1]': &[i32; _] + 112..115 '[1]': [i32; _] + 113..114 '1': i32 + "]], + ) } #[test] fn infer_match_first_coerce() { - assert_snapshot!( - infer(r#" -fn foo(x: &[T]) -> &[T] { loop {} } -fn test(i: i32) { - let x = match i { - 2 => foo(&[2]), - 1 => &[1], - _ => &[3], - }; -} -"#), - @r###" - 10..11 'x': &[T] - 27..38 '{ loop {} }': &[T] - 29..36 'loop {}': ! - 34..36 '{}': () - 47..48 'i': i32 - 55..149 '{ ... }; }': () - 65..66 'x': &[i32] - 69..146 'match ... }': &[i32] - 75..76 'i': i32 - 87..88 '2': i32 - 87..88 '2': i32 - 92..95 'foo': fn foo(&[i32]) -> &[i32] - 92..101 'foo(&[2])': &[i32] - 96..100 '&[2]': &[i32; _] - 97..100 '[2]': [i32; _] - 98..99 '2': i32 - 111..112 '1': i32 - 111..112 '1': i32 - 116..120 '&[1]': &[i32; _] - 117..120 '[1]': [i32; _] - 118..119 '1': i32 - 130..131 '_': i32 - 135..139 '&[3]': &[i32; _] - 136..139 '[3]': [i32; _] - 137..138 '3': i32 - "### + check_infer( + r" + fn foo(x: &[T]) -> &[T] { loop {} } + fn test(i: i32) { + let x = match i { + 2 => foo(&[2]), + 1 => &[1], + _ => &[3], + }; + } + ", + expect![[r" + 10..11 'x': &[T] + 27..38 '{ loop {} }': &[T] + 29..36 'loop {}': ! + 34..36 '{}': () + 47..48 'i': i32 + 55..149 '{ ... }; }': () + 65..66 'x': &[i32] + 69..146 'match ... }': &[i32] + 75..76 'i': i32 + 87..88 '2': i32 + 87..88 '2': i32 + 92..95 'foo': fn foo(&[i32]) -> &[i32] + 92..101 'foo(&[2])': &[i32] + 96..100 '&[2]': &[i32; _] + 97..100 '[2]': [i32; _] + 98..99 '2': i32 + 111..112 '1': i32 + 111..112 '1': i32 + 116..120 '&[1]': &[i32; _] + 117..120 '[1]': [i32; _] + 118..119 '1': i32 + 130..131 '_': i32 + 135..139 '&[3]': &[i32; _] + 136..139 '[3]': [i32; _] + 137..138 '3': i32 + "]], ); } #[test] fn infer_match_second_coerce() { - assert_snapshot!( - infer(r#" -fn foo(x: &[T]) -> &[T] { loop {} } -fn test(i: i32) { - let x = match i { - 1 => &[1], - 2 => foo(&[2]), - _ => &[3], - }; -} -"#), - @r###" - 10..11 'x': &[T] - 27..38 '{ loop {} }': &[T] - 29..36 'loop {}': ! - 34..36 '{}': () - 47..48 'i': i32 - 55..149 '{ ... }; }': () - 65..66 'x': &[i32] - 69..146 'match ... }': &[i32] - 75..76 'i': i32 - 87..88 '1': i32 - 87..88 '1': i32 - 92..96 '&[1]': &[i32; _] - 93..96 '[1]': [i32; _] - 94..95 '1': i32 - 106..107 '2': i32 - 106..107 '2': i32 - 111..114 'foo': fn foo(&[i32]) -> &[i32] - 111..120 'foo(&[2])': &[i32] - 115..119 '&[2]': &[i32; _] - 116..119 '[2]': [i32; _] - 117..118 '2': i32 - 130..131 '_': i32 - 135..139 '&[3]': &[i32; _] - 136..139 '[3]': [i32; _] - 137..138 '3': i32 - "### + check_infer( + r" + fn foo(x: &[T]) -> &[T] { loop {} } + fn test(i: i32) { + let x = match i { + 1 => &[1], + 2 => foo(&[2]), + _ => &[3], + }; + } + ", + expect![[r" + 10..11 'x': &[T] + 27..38 '{ loop {} }': &[T] + 29..36 'loop {}': ! + 34..36 '{}': () + 47..48 'i': i32 + 55..149 '{ ... }; }': () + 65..66 'x': &[i32] + 69..146 'match ... }': &[i32] + 75..76 'i': i32 + 87..88 '1': i32 + 87..88 '1': i32 + 92..96 '&[1]': &[i32; _] + 93..96 '[1]': [i32; _] + 94..95 '1': i32 + 106..107 '2': i32 + 106..107 '2': i32 + 111..114 'foo': fn foo(&[i32]) -> &[i32] + 111..120 'foo(&[2])': &[i32] + 115..119 '&[2]': &[i32; _] + 116..119 '[2]': [i32; _] + 117..118 '2': i32 + 130..131 '_': i32 + 135..139 '&[3]': &[i32; _] + 136..139 '[3]': [i32; _] + 137..138 '3': i32 + "]], ); } @@ -347,360 +356,361 @@ fn test(i: i32) { fn coerce_merge_one_by_one1() { mark::check!(coerce_merge_fail_fallback); - assert_snapshot!( - infer(r#" -fn test() { - let t = &mut 1; - let x = match 1 { - 1 => t as *mut i32, - 2 => t as &i32, - _ => t as *const i32, - }; -} -"#), - @r###" - 10..144 '{ ... }; }': () - 20..21 't': &mut i32 - 24..30 '&mut 1': &mut i32 - 29..30 '1': i32 - 40..41 'x': *const i32 - 44..141 'match ... }': *const i32 - 50..51 '1': i32 - 62..63 '1': i32 - 62..63 '1': i32 - 67..68 't': &mut i32 - 67..80 't as *mut i32': *mut i32 - 90..91 '2': i32 - 90..91 '2': i32 - 95..96 't': &mut i32 - 95..104 't as &i32': &i32 - 114..115 '_': i32 - 119..120 't': &mut i32 - 119..134 't as *const i32': *const i32 - "### + check_infer( + r" + fn test() { + let t = &mut 1; + let x = match 1 { + 1 => t as *mut i32, + 2 => t as &i32, + _ => t as *const i32, + }; + } + ", + expect![[r" + 10..144 '{ ... }; }': () + 20..21 't': &mut i32 + 24..30 '&mut 1': &mut i32 + 29..30 '1': i32 + 40..41 'x': *const i32 + 44..141 'match ... }': *const i32 + 50..51 '1': i32 + 62..63 '1': i32 + 62..63 '1': i32 + 67..68 't': &mut i32 + 67..80 't as *mut i32': *mut i32 + 90..91 '2': i32 + 90..91 '2': i32 + 95..96 't': &mut i32 + 95..104 't as &i32': &i32 + 114..115 '_': i32 + 119..120 't': &mut i32 + 119..134 't as *const i32': *const i32 + "]], ); } #[test] fn return_coerce_unknown() { - assert_snapshot!( - infer_with_mismatches(r#" -fn foo() -> u32 { - return unknown; -} -"#, true), - @r###" - 16..39 '{ ...own; }': u32 - 22..36 'return unknown': ! - 29..36 'unknown': u32 - "### + check_infer_with_mismatches( + r" + fn foo() -> u32 { + return unknown; + } + ", + expect![[r" + 16..39 '{ ...own; }': u32 + 22..36 'return unknown': ! + 29..36 'unknown': u32 + "]], ); } #[test] fn coerce_autoderef() { - assert_snapshot!( - infer_with_mismatches(r#" -struct Foo; -fn takes_ref_foo(x: &Foo) {} -fn test() { - takes_ref_foo(&Foo); - takes_ref_foo(&&Foo); - takes_ref_foo(&&&Foo); -} -"#, true), - @r###" - 29..30 'x': &Foo - 38..40 '{}': () - 51..132 '{ ...oo); }': () - 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo) - 57..76 'takes_...(&Foo)': () - 71..75 '&Foo': &Foo - 72..75 'Foo': Foo - 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo) - 82..102 'takes_...&&Foo)': () - 96..101 '&&Foo': &&Foo - 97..101 '&Foo': &Foo - 98..101 'Foo': Foo - 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo) - 108..129 'takes_...&&Foo)': () - 122..128 '&&&Foo': &&&Foo - 123..128 '&&Foo': &&Foo - 124..128 '&Foo': &Foo - 125..128 'Foo': Foo - "### + check_infer_with_mismatches( + r" + struct Foo; + fn takes_ref_foo(x: &Foo) {} + fn test() { + takes_ref_foo(&Foo); + takes_ref_foo(&&Foo); + takes_ref_foo(&&&Foo); + } + ", + expect![[r" + 29..30 'x': &Foo + 38..40 '{}': () + 51..132 '{ ...oo); }': () + 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo) + 57..76 'takes_...(&Foo)': () + 71..75 '&Foo': &Foo + 72..75 'Foo': Foo + 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo) + 82..102 'takes_...&&Foo)': () + 96..101 '&&Foo': &&Foo + 97..101 '&Foo': &Foo + 98..101 'Foo': Foo + 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo) + 108..129 'takes_...&&Foo)': () + 122..128 '&&&Foo': &&&Foo + 123..128 '&&Foo': &&Foo + 124..128 '&Foo': &Foo + 125..128 'Foo': Foo + "]], ); } #[test] fn coerce_autoderef_generic() { - assert_snapshot!( - infer_with_mismatches(r#" -struct Foo; -fn takes_ref(x: &T) -> T { *x } -fn test() { - takes_ref(&Foo); - takes_ref(&&Foo); - takes_ref(&&&Foo); -} -"#, true), - @r###" - 28..29 'x': &T - 40..46 '{ *x }': T - 42..44 '*x': T - 43..44 'x': &T - 57..126 '{ ...oo); }': () - 63..72 'takes_ref': fn takes_ref(&Foo) -> Foo - 63..78 'takes_ref(&Foo)': Foo - 73..77 '&Foo': &Foo - 74..77 'Foo': Foo - 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo - 84..100 'takes_...&&Foo)': &Foo - 94..99 '&&Foo': &&Foo - 95..99 '&Foo': &Foo - 96..99 'Foo': Foo - 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo - 106..123 'takes_...&&Foo)': &&Foo - 116..122 '&&&Foo': &&&Foo - 117..122 '&&Foo': &&Foo - 118..122 '&Foo': &Foo - 119..122 'Foo': Foo - "### + check_infer_with_mismatches( + r" + struct Foo; + fn takes_ref(x: &T) -> T { *x } + fn test() { + takes_ref(&Foo); + takes_ref(&&Foo); + takes_ref(&&&Foo); + } + ", + expect![[r" + 28..29 'x': &T + 40..46 '{ *x }': T + 42..44 '*x': T + 43..44 'x': &T + 57..126 '{ ...oo); }': () + 63..72 'takes_ref': fn takes_ref(&Foo) -> Foo + 63..78 'takes_ref(&Foo)': Foo + 73..77 '&Foo': &Foo + 74..77 'Foo': Foo + 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo + 84..100 'takes_...&&Foo)': &Foo + 94..99 '&&Foo': &&Foo + 95..99 '&Foo': &Foo + 96..99 'Foo': Foo + 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo + 106..123 'takes_...&&Foo)': &&Foo + 116..122 '&&&Foo': &&&Foo + 117..122 '&&Foo': &&Foo + 118..122 '&Foo': &Foo + 119..122 'Foo': Foo + "]], ); } #[test] fn coerce_autoderef_block() { - assert_snapshot!( - infer_with_mismatches(r#" -struct String {} -#[lang = "deref"] -trait Deref { type Target; } -impl Deref for String { type Target = str; } -fn takes_ref_str(x: &str) {} -fn returns_string() -> String { loop {} } -fn test() { - takes_ref_str(&{ returns_string() }); -} -"#, true), - @r###" - 126..127 'x': &str - 135..137 '{}': () - 168..179 '{ loop {} }': String - 170..177 'loop {}': ! - 175..177 '{}': () - 190..235 '{ ... }); }': () - 196..209 'takes_ref_str': fn takes_ref_str(&str) - 196..232 'takes_...g() })': () - 210..231 '&{ ret...ng() }': &String - 211..231 '{ retu...ng() }': String - 213..227 'returns_string': fn returns_string() -> String - 213..229 'return...ring()': String - "### + check_infer_with_mismatches( + r#" + struct String {} + #[lang = "deref"] + trait Deref { type Target; } + impl Deref for String { type Target = str; } + fn takes_ref_str(x: &str) {} + fn returns_string() -> String { loop {} } + fn test() { + takes_ref_str(&{ returns_string() }); + } + "#, + expect![[r" + 126..127 'x': &str + 135..137 '{}': () + 168..179 '{ loop {} }': String + 170..177 'loop {}': ! + 175..177 '{}': () + 190..235 '{ ... }); }': () + 196..209 'takes_ref_str': fn takes_ref_str(&str) + 196..232 'takes_...g() })': () + 210..231 '&{ ret...ng() }': &String + 211..231 '{ retu...ng() }': String + 213..227 'returns_string': fn returns_string() -> String + 213..229 'return...ring()': String + "]], ); } #[test] fn closure_return_coerce() { - assert_snapshot!( - infer_with_mismatches(r#" -fn foo() { - let x = || { - if true { - return &1u32; + check_infer_with_mismatches( + r" + fn foo() { + let x = || { + if true { + return &1u32; + } + &&1u32 + }; } - &&1u32 - }; -} -"#, true), - @r###" - 9..105 '{ ... }; }': () - 19..20 'x': || -> &u32 - 23..102 '|| { ... }': || -> &u32 - 26..102 '{ ... }': &u32 - 36..81 'if tru... }': () - 39..43 'true': bool - 44..81 '{ ... }': () - 58..70 'return &1u32': ! - 65..70 '&1u32': &u32 - 66..70 '1u32': u32 - 90..96 '&&1u32': &&u32 - 91..96 '&1u32': &u32 - 92..96 '1u32': u32 - "### + ", + expect![[r" + 9..105 '{ ... }; }': () + 19..20 'x': || -> &u32 + 23..102 '|| { ... }': || -> &u32 + 26..102 '{ ... }': &u32 + 36..81 'if tru... }': () + 39..43 'true': bool + 44..81 '{ ... }': () + 58..70 'return &1u32': ! + 65..70 '&1u32': &u32 + 66..70 '1u32': u32 + 90..96 '&&1u32': &&u32 + 91..96 '&1u32': &u32 + 92..96 '1u32': u32 + "]], ); } #[test] fn coerce_fn_item_to_fn_ptr() { - assert_snapshot!( - infer_with_mismatches(r#" -fn foo(x: u32) -> isize { 1 } -fn test() { - let f: fn(u32) -> isize = foo; -} -"#, true), - @r###" - 7..8 'x': u32 - 24..29 '{ 1 }': isize - 26..27 '1': isize - 40..78 '{ ...foo; }': () - 50..51 'f': fn(u32) -> isize - 72..75 'foo': fn foo(u32) -> isize - "### + check_infer_with_mismatches( + r" + fn foo(x: u32) -> isize { 1 } + fn test() { + let f: fn(u32) -> isize = foo; + } + ", + expect![[r" + 7..8 'x': u32 + 24..29 '{ 1 }': isize + 26..27 '1': isize + 40..78 '{ ...foo; }': () + 50..51 'f': fn(u32) -> isize + 72..75 'foo': fn foo(u32) -> isize + "]], ); } #[test] fn coerce_fn_items_in_match_arms() { mark::check!(coerce_fn_reification); - assert_snapshot!( - infer_with_mismatches(r#" -fn foo1(x: u32) -> isize { 1 } -fn foo2(x: u32) -> isize { 2 } -fn foo3(x: u32) -> isize { 3 } -fn test() { - let x = match 1 { - 1 => foo1, - 2 => foo2, - _ => foo3, - }; -} -"#, true), - @r###" - 8..9 'x': u32 - 25..30 '{ 1 }': isize - 27..28 '1': isize - 39..40 'x': u32 - 56..61 '{ 2 }': isize - 58..59 '2': isize - 70..71 'x': u32 - 87..92 '{ 3 }': isize - 89..90 '3': isize - 103..192 '{ ... }; }': () - 113..114 'x': fn(u32) -> isize - 117..189 'match ... }': fn(u32) -> isize - 123..124 '1': i32 - 135..136 '1': i32 - 135..136 '1': i32 - 140..144 'foo1': fn foo1(u32) -> isize - 154..155 '2': i32 - 154..155 '2': i32 - 159..163 'foo2': fn foo2(u32) -> isize - 173..174 '_': i32 - 178..182 'foo3': fn foo3(u32) -> isize - "### + + check_infer_with_mismatches( + r" + fn foo1(x: u32) -> isize { 1 } + fn foo2(x: u32) -> isize { 2 } + fn foo3(x: u32) -> isize { 3 } + fn test() { + let x = match 1 { + 1 => foo1, + 2 => foo2, + _ => foo3, + }; + } + ", + expect![[r" + 8..9 'x': u32 + 25..30 '{ 1 }': isize + 27..28 '1': isize + 39..40 'x': u32 + 56..61 '{ 2 }': isize + 58..59 '2': isize + 70..71 'x': u32 + 87..92 '{ 3 }': isize + 89..90 '3': isize + 103..192 '{ ... }; }': () + 113..114 'x': fn(u32) -> isize + 117..189 'match ... }': fn(u32) -> isize + 123..124 '1': i32 + 135..136 '1': i32 + 135..136 '1': i32 + 140..144 'foo1': fn foo1(u32) -> isize + 154..155 '2': i32 + 154..155 '2': i32 + 159..163 'foo2': fn foo2(u32) -> isize + 173..174 '_': i32 + 178..182 'foo3': fn foo3(u32) -> isize + "]], ); } #[test] fn coerce_closure_to_fn_ptr() { - assert_snapshot!( - infer_with_mismatches(r#" -fn test() { - let f: fn(u32) -> isize = |x| { 1 }; -} -"#, true), - @r###" - 10..54 '{ ...1 }; }': () - 20..21 'f': fn(u32) -> isize - 42..51 '|x| { 1 }': |u32| -> isize - 43..44 'x': u32 - 46..51 '{ 1 }': isize - 48..49 '1': isize - "### + check_infer_with_mismatches( + r" + fn test() { + let f: fn(u32) -> isize = |x| { 1 }; + } + ", + expect![[r" + 10..54 '{ ...1 }; }': () + 20..21 'f': fn(u32) -> isize + 42..51 '|x| { 1 }': |u32| -> isize + 43..44 'x': u32 + 46..51 '{ 1 }': isize + 48..49 '1': isize + "]], ); } #[test] fn coerce_placeholder_ref() { // placeholders should unify, even behind references - assert_snapshot!( - infer_with_mismatches(r#" -struct S { t: T } -impl S { - fn get(&self) -> &TT { - &self.t - } -} -"#, true), - @r###" - 50..54 'self': &S - 63..86 '{ ... }': &TT - 73..80 '&self.t': &TT - 74..78 'self': &S - 74..80 'self.t': TT - "### + check_infer_with_mismatches( + r" + struct S { t: T } + impl S { + fn get(&self) -> &TT { + &self.t + } + } + ", + expect![[r" + 50..54 'self': &S + 63..86 '{ ... }': &TT + 73..80 '&self.t': &TT + 74..78 'self': &S + 74..80 'self.t': TT + "]], ); } #[test] fn coerce_unsize_array() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "unsize"] -pub trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} + check_infer_with_mismatches( + r#" + #[lang = "unsize"] + pub trait Unsize {} + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} -impl, U> CoerceUnsized<&U> for &T {} + impl, U> CoerceUnsized<&U> for &T {} -fn test() { - let f: &[usize] = &[1, 2, 3]; -} -"#, true), - @r###" - 161..198 '{ ... 3]; }': () - 171..172 'f': &[usize] - 185..195 '&[1, 2, 3]': &[usize; _] - 186..195 '[1, 2, 3]': [usize; _] - 187..188 '1': usize - 190..191 '2': usize - 193..194 '3': usize - "### + fn test() { + let f: &[usize] = &[1, 2, 3]; + } + "#, + expect![[r" + 161..198 '{ ... 3]; }': () + 171..172 'f': &[usize] + 185..195 '&[1, 2, 3]': &[usize; _] + 186..195 '[1, 2, 3]': [usize; _] + 187..188 '1': usize + 190..191 '2': usize + 193..194 '3': usize + "]], ); } #[test] fn coerce_unsize_trait_object_simple() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "sized"] -pub trait Sized {} -#[lang = "unsize"] -pub trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -impl, U> CoerceUnsized<&U> for &T {} - -trait Foo {} -trait Bar: Foo {} -trait Baz: Bar {} - -struct S; -impl Foo for S {} -impl Bar for S {} -impl Baz for S {} - -fn test() { - let obj: &dyn Baz = &S; - let obj: &dyn Bar<_, i8, i16> = &S; - let obj: &dyn Foo = &S; -} -"#, true), - @r###" - 424..539 '{ ... &S; }': () - 434..437 'obj': &dyn Baz - 459..461 '&S': &S - 460..461 'S': S - 471..474 'obj': &dyn Bar - 499..501 '&S': &S - 500..501 'S': S - 511..514 'obj': &dyn Foo - 534..536 '&S': &S - 535..536 'S': S - "### + check_infer_with_mismatches( + r#" + #[lang = "sized"] + pub trait Sized {} + #[lang = "unsize"] + pub trait Unsize {} + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} + + impl, U> CoerceUnsized<&U> for &T {} + + trait Foo {} + trait Bar: Foo {} + trait Baz: Bar {} + + struct S; + impl Foo for S {} + impl Bar for S {} + impl Baz for S {} + + fn test() { + let obj: &dyn Baz = &S; + let obj: &dyn Bar<_, i8, i16> = &S; + let obj: &dyn Foo = &S; + } + "#, + expect![[r" + 424..539 '{ ... &S; }': () + 434..437 'obj': &dyn Baz + 459..461 '&S': &S + 460..461 'S': S + 471..474 'obj': &dyn Bar + 499..501 '&S': &S + 500..501 'S': S + 511..514 'obj': &dyn Foo + 534..536 '&S': &S + 535..536 'S': S + "]], ); } @@ -709,90 +719,90 @@ fn test() { // it. We used to support it, but Chalk doesn't. #[ignore] fn coerce_unsize_trait_object_to_trait_object() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "sized"] -pub trait Sized {} -#[lang = "unsize"] -pub trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -impl, U> CoerceUnsized<&U> for &T {} - -trait Foo {} -trait Bar: Foo {} -trait Baz: Bar {} - -struct S; -impl Foo for S {} -impl Bar for S {} -impl Baz for S {} - -fn test() { - let obj: &dyn Baz = &S; - let obj: &dyn Bar<_, _, _> = obj; - let obj: &dyn Foo<_, _> = obj; - let obj2: &dyn Baz = &S; - let _: &dyn Foo<_, _> = obj2; -} -"#, true), - @r###" - 424..609 '{ ...bj2; }': () - 434..437 'obj': &dyn Baz - 459..461 '&S': &S - 460..461 'S': S - 471..474 'obj': &dyn Bar - 496..499 'obj': &dyn Baz - 509..512 'obj': &dyn Foo - 531..534 'obj': &dyn Bar - 544..548 'obj2': &dyn Baz - 570..572 '&S': &S - 571..572 'S': S - 582..583 '_': &dyn Foo - 602..606 'obj2': &dyn Baz - "### + check_infer_with_mismatches( + r#" + #[lang = "sized"] + pub trait Sized {} + #[lang = "unsize"] + pub trait Unsize {} + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} + + impl, U> CoerceUnsized<&U> for &T {} + + trait Foo {} + trait Bar: Foo {} + trait Baz: Bar {} + + struct S; + impl Foo for S {} + impl Bar for S {} + impl Baz for S {} + + fn test() { + let obj: &dyn Baz = &S; + let obj: &dyn Bar<_, _, _> = obj; + let obj: &dyn Foo<_, _> = obj; + let obj2: &dyn Baz = &S; + let _: &dyn Foo<_, _> = obj2; + } + "#, + expect![[r" + 424..609 '{ ...bj2; }': () + 434..437 'obj': &dyn Baz + 459..461 '&S': &S + 460..461 'S': S + 471..474 'obj': &dyn Bar + 496..499 'obj': &dyn Baz + 509..512 'obj': &dyn Foo + 531..534 'obj': &dyn Bar + 544..548 'obj2': &dyn Baz + 570..572 '&S': &S + 571..572 'S': S + 582..583 '_': &dyn Foo + 602..606 'obj2': &dyn Baz + "]], ); } #[test] fn coerce_unsize_super_trait_cycle() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "sized"] -pub trait Sized {} -#[lang = "unsize"] -pub trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -impl, U> CoerceUnsized<&U> for &T {} - -trait A {} -trait B: C + A {} -trait C: B {} -trait D: C - -struct S; -impl A for S {} -impl B for S {} -impl C for S {} -impl D for S {} - -fn test() { - let obj: &dyn D = &S; - let obj: &dyn A = &S; -} -"#, true), - @r###" - 328..383 '{ ... &S; }': () - 338..341 'obj': &dyn D - 352..354 '&S': &S - 353..354 'S': S - 364..367 'obj': &dyn A - 378..380 '&S': &S - 379..380 'S': S - "### + check_infer_with_mismatches( + r#" + #[lang = "sized"] + pub trait Sized {} + #[lang = "unsize"] + pub trait Unsize {} + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} + + impl, U> CoerceUnsized<&U> for &T {} + + trait A {} + trait B: C + A {} + trait C: B {} + trait D: C + + struct S; + impl A for S {} + impl B for S {} + impl C for S {} + impl D for S {} + + fn test() { + let obj: &dyn D = &S; + let obj: &dyn A = &S; + } + "#, + expect![[r" + 328..383 '{ ... &S; }': () + 338..341 'obj': &dyn D + 352..354 '&S': &S + 353..354 'S': S + 364..367 'obj': &dyn A + 378..380 '&S': &S + 379..380 'S': S + "]], ); } @@ -801,24 +811,24 @@ fn test() { fn coerce_unsize_generic() { // FIXME: Implement this // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "unsize"] -pub trait Unsize {} -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} + check_infer_with_mismatches( + r#" + #[lang = "unsize"] + pub trait Unsize {} + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} -impl, U> CoerceUnsized<&U> for &T {} + impl, U> CoerceUnsized<&U> for &T {} -struct Foo { t: T }; -struct Bar(Foo); + struct Foo { t: T }; + struct Bar(Foo); -fn test() { - let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; - let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); -} -"#, true), - @r###" - "### + fn test() { + let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; + let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); + } + "#, + expect![[r" + "]], ); } -- cgit v1.2.3