From 6a77ec7bbe6ddbf663dce9529d11d1bb56c5489a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:35:29 +0200 Subject: Rename ra_hir_ty -> hir_ty --- crates/ra_hir_ty/src/tests/coercion.rs | 861 ------ crates/ra_hir_ty/src/tests/display_source_code.rs | 41 - crates/ra_hir_ty/src/tests/macros.rs | 787 ------ crates/ra_hir_ty/src/tests/method_resolution.rs | 1053 ------- crates/ra_hir_ty/src/tests/never_type.rs | 409 --- crates/ra_hir_ty/src/tests/patterns.rs | 656 ----- crates/ra_hir_ty/src/tests/regression.rs | 842 ------ crates/ra_hir_ty/src/tests/simple.rs | 2218 --------------- crates/ra_hir_ty/src/tests/traits.rs | 3113 --------------------- 9 files changed, 9980 deletions(-) delete mode 100644 crates/ra_hir_ty/src/tests/coercion.rs delete mode 100644 crates/ra_hir_ty/src/tests/display_source_code.rs delete mode 100644 crates/ra_hir_ty/src/tests/macros.rs delete mode 100644 crates/ra_hir_ty/src/tests/method_resolution.rs delete mode 100644 crates/ra_hir_ty/src/tests/never_type.rs delete mode 100644 crates/ra_hir_ty/src/tests/patterns.rs delete mode 100644 crates/ra_hir_ty/src/tests/regression.rs delete mode 100644 crates/ra_hir_ty/src/tests/simple.rs delete mode 100644 crates/ra_hir_ty/src/tests/traits.rs (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs deleted file mode 100644 index 17efd75cb..000000000 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ /dev/null @@ -1,861 +0,0 @@ -use expect::expect; -use test_utils::mark; - -use super::{check_infer, check_infer_with_mismatches}; - -#[test] -fn infer_block_expr_type_mismatch() { - 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() { - check_infer( - r#" - struct S { a: T } - - fn f(_: &[T]) -> T { loop {} } - fn g(_: S<&[T]>) -> T { loop {} } - - fn gen() -> *mut [T; 2] { loop {} } - fn test1() -> *mut [U] { - gen() - } - - 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); - } - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} - impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - "#, - 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() { - 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() { - 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); - } - - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} - impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - "#, - 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() { - check_infer( - r#" - fn foo(x: &[T]) -> &[T] { loop {} } - fn test() { - let x = if true { - foo(&[1]) - } else { - &[1] - }; - } - - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - "#, - 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() { - check_infer( - r#" - fn foo(x: &[T]) -> &[T] { loop {} } - fn test() { - let x = if true { - &[1] - } else { - foo(&[1]) - }; - } - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} - impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - "#, - 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() { - check_infer( - r#" - fn foo(x: &[T]) -> &[T] { loop {} } - fn test(i: i32) { - let x = match i { - 2 => foo(&[2]), - 1 => &[1], - _ => &[3], - }; - } - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - "#, - 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() { - check_infer( - r#" - fn foo(x: &[T]) -> &[T] { loop {} } - fn test(i: i32) { - let x = match i { - 1 => &[1], - 2 => foo(&[2]), - _ => &[3], - }; - } - - #[lang = "sized"] - pub trait Sized {} - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} - impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - "#, - 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 - "]], - ); -} - -#[test] -fn coerce_merge_one_by_one1() { - mark::check!(coerce_merge_fail_fallback); - - 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() { - 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() { - 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() { - 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() { - 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() { - check_infer_with_mismatches( - r" - fn foo() { - let x = || { - if true { - return &1u32; - } - &&1u32 - }; - } - ", - 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() { - 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); - - 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() { - 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 - 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() { - check_infer_with_mismatches( - r#" - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl, U> CoerceUnsized<&U> for &T {} - - 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() { - 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 - "]], - ); -} - -#[test] -// The rust reference says this should be possible, but rustc doesn't implement -// it. We used to support it, but Chalk doesn't. -#[ignore] -fn coerce_unsize_trait_object_to_trait_object() { - 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() { - 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 - "]], - ); -} - -#[ignore] -#[test] -fn coerce_unsize_generic() { - // FIXME: Implement this - // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions - check_infer_with_mismatches( - r#" - #[lang = "unsize"] - pub trait Unsize {} - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - impl, U> CoerceUnsized<&U> for &T {} - - 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] }); - } - "#, - expect![[r" - "]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs deleted file mode 100644 index b502135d8..000000000 --- a/crates/ra_hir_ty/src/tests/display_source_code.rs +++ /dev/null @@ -1,41 +0,0 @@ -use super::check_types_source_code; - -#[test] -fn qualify_path_to_submodule() { - check_types_source_code( - r#" -mod foo { - pub struct Foo; -} - -fn bar() { - let foo: foo::Foo = foo::Foo; - foo -} //^ foo::Foo - -"#, - ); -} - -#[test] -fn omit_default_type_parameters() { - check_types_source_code( - r#" -struct Foo { t: T } -fn main() { - let foo = Foo { t: 5u8 }; - foo; -} //^ Foo -"#, - ); - - check_types_source_code( - r#" -struct Foo { k: K, t: T } -fn main() { - let foo = Foo { k: 400, t: 5u8 }; - foo; -} //^ Foo -"#, - ); -} diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs deleted file mode 100644 index d887c7a79..000000000 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ /dev/null @@ -1,787 +0,0 @@ -use std::fs; - -use expect::expect; -use test_utils::project_dir; - -use super::{check_infer, check_types}; - -#[test] -fn cfg_impl_def() { - check_types( - r#" -//- /main.rs crate:main deps:foo cfg:test -use foo::S as T; -struct S; - -#[cfg(test)] -impl S { - fn foo1(&self) -> i32 { 0 } -} - -#[cfg(not(test))] -impl S { - fn foo2(&self) -> i32 { 0 } -} - -fn test() { - let t = (S.foo1(), S.foo2(), T.foo3(), T.foo4()); - t; -} //^ (i32, {unknown}, i32, {unknown}) - -//- /foo.rs crate:foo -struct S; - -#[cfg(not(test))] -impl S { - fn foo3(&self) -> i32 { 0 } -} - -#[cfg(test)] -impl S { - fn foo4(&self) -> i32 { 0 } -} -"#, - ); -} - -#[test] -fn infer_macros_expanded() { - check_infer( - r#" - struct Foo(Vec); - - macro_rules! foo { - ($($item:expr),*) => { - { - Foo(vec![$($item,)*]) - } - }; - } - - fn main() { - let x = foo!(1,2); - } - "#, - expect![[r#" - !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': Foo({unknown}) -> Foo - !1..16 'Foo(vec![1,2,])': Foo - !5..15 'vec![1,2,]': {unknown} - 155..181 '{ ...,2); }': () - 165..166 'x': Foo - "#]], - ); -} - -#[test] -fn infer_legacy_textual_scoped_macros_expanded() { - check_infer( - r#" - struct Foo(Vec); - - #[macro_use] - mod m { - macro_rules! foo { - ($($item:expr),*) => { - { - Foo(vec![$($item,)*]) - } - }; - } - } - - fn main() { - let x = foo!(1,2); - let y = crate::foo!(1,2); - } - "#, - expect![[r#" - !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': Foo({unknown}) -> Foo - !1..16 'Foo(vec![1,2,])': Foo - !5..15 'vec![1,2,]': {unknown} - 194..250 '{ ...,2); }': () - 204..205 'x': Foo - 227..228 'y': {unknown} - 231..247 'crate:...!(1,2)': {unknown} - "#]], - ); -} - -#[test] -fn infer_path_qualified_macros_expanded() { - check_infer( - r#" - #[macro_export] - macro_rules! foo { - () => { 42i32 } - } - - mod m { - pub use super::foo as bar; - } - - fn main() { - let x = crate::foo!(); - let y = m::bar!(); - } - "#, - expect![[r#" - !0..5 '42i32': i32 - !0..5 '42i32': i32 - 110..163 '{ ...!(); }': () - 120..121 'x': i32 - 147..148 'y': i32 - "#]], - ); -} - -#[test] -fn expr_macro_expanded_in_various_places() { - check_infer( - r#" - macro_rules! spam { - () => (1isize); - } - - fn spam() { - spam!(); - (spam!()); - spam!().spam(spam!()); - for _ in spam!() {} - || spam!(); - while spam!() {} - break spam!(); - return spam!(); - match spam!() { - _ if spam!() => spam!(), - } - spam!()(spam!()); - Spam { spam: spam!() }; - spam!()[spam!()]; - await spam!(); - spam!() as usize; - &spam!(); - -spam!(); - spam!()..spam!(); - spam!() + spam!(); - } - "#, - expect![[r#" - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - 53..456 '{ ...!(); }': () - 87..108 'spam!(...am!())': {unknown} - 114..133 'for _ ...!() {}': () - 118..119 '_': {unknown} - 131..133 '{}': () - 138..148 '|| spam!()': || -> isize - 154..170 'while ...!() {}': () - 168..170 '{}': () - 175..188 'break spam!()': ! - 194..208 'return spam!()': ! - 214..268 'match ... }': isize - 238..239 '_': isize - 273..289 'spam!(...am!())': {unknown} - 295..317 'Spam {...m!() }': {unknown} - 323..339 'spam!(...am!()]': {unknown} - 364..380 'spam!(... usize': usize - 386..394 '&spam!()': &isize - 400..408 '-spam!()': isize - 414..430 'spam!(...pam!()': {unknown} - 436..453 'spam!(...pam!()': isize - "#]], - ); -} - -#[test] -fn infer_type_value_macro_having_same_name() { - check_infer( - r#" - #[macro_export] - macro_rules! foo { - () => { - mod foo { - pub use super::foo; - } - }; - ($x:tt) => { - $x - }; - } - - foo!(); - - fn foo() { - let foo = foo::foo!(42i32); - } - "#, - expect![[r#" - !0..5 '42i32': i32 - 170..205 '{ ...32); }': () - 180..183 'foo': i32 - "#]], - ); -} - -#[test] -fn processes_impls_generated_by_macros() { - check_types( - r#" -macro_rules! m { - ($ident:ident) => (impl Trait for $ident {}) -} -trait Trait { fn foo(self) -> u128 {} } -struct S; -m!(S); -fn test() { S.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn infer_assoc_items_generated_by_macros() { - check_types( - r#" -macro_rules! m { - () => (fn foo(&self) -> u128 {0}) -} -struct S; -impl S { - m!(); -} - -fn test() { S.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn infer_assoc_items_generated_by_macros_chain() { - check_types( - r#" -macro_rules! m_inner { - () => {fn foo(&self) -> u128 {0}} -} -macro_rules! m { - () => {m_inner!();} -} - -struct S; -impl S { - m!(); -} - -fn test() { S.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn infer_macro_with_dollar_crate_is_correct_in_expr() { - check_types( - r#" -//- /main.rs crate:main deps:foo -fn test() { - let x = (foo::foo!(1), foo::foo!(2)); - x; -} //^ (i32, usize) - -//- /lib.rs crate:foo -#[macro_export] -macro_rules! foo { - (1) => { $crate::bar!() }; - (2) => { 1 + $crate::baz() }; -} - -#[macro_export] -macro_rules! bar { - () => { 42 } -} - -pub fn baz() -> usize { 31usize } -"#, - ); -} - -#[test] -fn infer_macro_with_dollar_crate_is_correct_in_trait_associate_type() { - check_types( - r#" -//- /main.rs crate:main deps:foo -use foo::Trait; - -fn test() { - let msg = foo::Message(foo::MessageRef); - let r = msg.deref(); - r; - //^ &MessageRef -} - -//- /lib.rs crate:foo -pub struct MessageRef; -pub struct Message(MessageRef); - -pub trait Trait { - type Target; - fn deref(&self) -> &Self::Target; -} - -#[macro_export] -macro_rules! expand { - () => { - impl Trait for Message { - type Target = $crate::MessageRef; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - } -} - -expand!(); -"#, - ); -} - -#[test] -fn infer_type_value_non_legacy_macro_use_as() { - check_infer( - r#" - mod m { - macro_rules! _foo { - ($x:ident) => { type $x = u64; } - } - pub(crate) use _foo as foo; - } - - m::foo!(foo); - use foo as bar; - fn f() -> bar { 0 } - fn main() { - let _a = f(); - } - "#, - expect![[r#" - 158..163 '{ 0 }': u64 - 160..161 '0': u64 - 174..196 '{ ...f(); }': () - 184..186 '_a': u64 - 190..191 'f': fn f() -> u64 - 190..193 'f()': u64 - "#]], - ); -} - -#[test] -fn infer_local_macro() { - check_infer( - r#" - fn main() { - macro_rules! foo { - () => { 1usize } - } - let _a = foo!(); - } - "#, - expect![[r#" - !0..6 '1usize': usize - 10..89 '{ ...!(); }': () - 16..65 'macro_... }': {unknown} - 74..76 '_a': usize - "#]], - ); -} - -#[test] -fn infer_local_inner_macros() { - check_types( - r#" -//- /main.rs crate:main deps:foo -fn test() { - let x = foo::foo!(1); - x; -} //^ i32 - -//- /lib.rs crate:foo -#[macro_export(local_inner_macros)] -macro_rules! foo { - (1) => { bar!() }; -} - -#[macro_export] -macro_rules! bar { - () => { 42 } -} - -"#, - ); -} - -#[test] -fn infer_builtin_macros_line() { - check_infer( - r#" - #[rustc_builtin_macro] - macro_rules! line {() => {}} - - fn main() { - let x = line!(); - } - "#, - expect![[r#" - !0..1 '0': i32 - 63..87 '{ ...!(); }': () - 73..74 'x': i32 - "#]], - ); -} - -#[test] -fn infer_builtin_macros_file() { - check_infer( - r#" - #[rustc_builtin_macro] - macro_rules! file {() => {}} - - fn main() { - let x = file!(); - } - "#, - expect![[r#" - !0..2 '""': &str - 63..87 '{ ...!(); }': () - 73..74 'x': &str - "#]], - ); -} - -#[test] -fn infer_builtin_macros_column() { - check_infer( - r#" - #[rustc_builtin_macro] - macro_rules! column {() => {}} - - fn main() { - let x = column!(); - } - "#, - expect![[r#" - !0..1 '0': i32 - 65..91 '{ ...!(); }': () - 75..76 'x': i32 - "#]], - ); -} - -#[test] -fn infer_builtin_macros_concat() { - check_infer( - r#" - #[rustc_builtin_macro] - macro_rules! concat {() => {}} - - fn main() { - let x = concat!("hello", concat!("world", "!")); - } - "#, - expect![[r#" - !0..13 '"helloworld!"': &str - 65..121 '{ ...")); }': () - 75..76 'x': &str - "#]], - ); -} - -#[test] -fn infer_builtin_macros_include() { - check_types( - r#" -//- /main.rs -#[rustc_builtin_macro] -macro_rules! include {() => {}} - -include!("foo.rs"); - -fn main() { - bar(); -} //^ u32 - -//- /foo.rs -fn bar() -> u32 {0} -"#, - ); -} - -#[test] -#[ignore] -fn include_accidentally_quadratic() { - let file = project_dir().join("crates/syntax/test_data/accidentally_quadratic"); - let big_file = fs::read_to_string(file).unwrap(); - let big_file = vec![big_file; 10].join("\n"); - - let fixture = r#" -//- /main.rs -#[rustc_builtin_macro] -macro_rules! include {() => {}} - -include!("foo.rs"); - -fn main() { - RegisterBlock { }; - //^ RegisterBlock -} - "#; - let fixture = format!("{}\n//- /foo.rs\n{}", fixture, big_file); - check_types(&fixture); -} - -#[test] -fn infer_builtin_macros_include_concat() { - check_types( - r#" -//- /main.rs -#[rustc_builtin_macro] -macro_rules! include {() => {}} - -#[rustc_builtin_macro] -macro_rules! concat {() => {}} - -include!(concat!("f", "oo.rs")); - -fn main() { - bar(); -} //^ u32 - -//- /foo.rs -fn bar() -> u32 {0} -"#, - ); -} - -#[test] -fn infer_builtin_macros_include_concat_with_bad_env_should_failed() { - check_types( - r#" -//- /main.rs -#[rustc_builtin_macro] -macro_rules! include {() => {}} - -#[rustc_builtin_macro] -macro_rules! concat {() => {}} - -#[rustc_builtin_macro] -macro_rules! env {() => {}} - -include!(concat!(env!("OUT_DIR"), "/foo.rs")); - -fn main() { - bar(); -} //^ {unknown} - -//- /foo.rs -fn bar() -> u32 {0} -"#, - ); -} - -#[test] -fn infer_builtin_macros_include_itself_should_failed() { - check_types( - r#" -#[rustc_builtin_macro] -macro_rules! include {() => {}} - -include!("main.rs"); - -fn main() { - 0 -} //^ i32 -"#, - ); -} - -#[test] -fn infer_builtin_macros_concat_with_lazy() { - check_infer( - r#" - macro_rules! hello {() => {"hello"}} - - #[rustc_builtin_macro] - macro_rules! concat {() => {}} - - fn main() { - let x = concat!(hello!(), concat!("world", "!")); - } - "#, - expect![[r#" - !0..13 '"helloworld!"': &str - 103..160 '{ ...")); }': () - 113..114 'x': &str - "#]], - ); -} - -#[test] -fn infer_builtin_macros_env() { - check_infer( - r#" - //- /main.rs env:foo=bar - #[rustc_builtin_macro] - macro_rules! env {() => {}} - - fn main() { - let x = env!("foo"); - } - "#, - expect![[r#" - !0..22 '"__RA_...TED__"': &str - 62..90 '{ ...o"); }': () - 72..73 'x': &str - "#]], - ); -} - -#[test] -fn infer_derive_clone_simple() { - check_types( - r#" -//- /main.rs crate:main deps:core -#[derive(Clone)] -struct S; -fn test() { - S.clone(); -} //^ S - -//- /lib.rs crate:core -#[prelude_import] -use clone::*; -mod clone { - trait Clone { - fn clone(&self) -> Self; - } -} -"#, - ); -} - -#[test] -fn infer_derive_clone_in_core() { - check_types( - r#" -//- /lib.rs crate:core -#[prelude_import] -use clone::*; -mod clone { - trait Clone { - fn clone(&self) -> Self; - } -} -#[derive(Clone)] -pub struct S; - -//- /main.rs crate:main deps:core -use core::S; -fn test() { - S.clone(); -} //^ S -"#, - ); -} - -#[test] -fn infer_derive_clone_with_params() { - check_types( - r#" -//- /main.rs crate:main deps:core -#[derive(Clone)] -struct S; -#[derive(Clone)] -struct Wrapper(T); -struct NonClone; -fn test() { - (Wrapper(S).clone(), Wrapper(NonClone).clone()); - //^ (Wrapper, {unknown}) -} - -//- /lib.rs crate:core -#[prelude_import] -use clone::*; -mod clone { - trait Clone { - fn clone(&self) -> Self; - } -} -"#, - ); -} - -#[test] -fn infer_custom_derive_simple() { - // FIXME: this test current now do nothing - check_types( - r#" -//- /main.rs crate:main -use foo::Foo; - -#[derive(Foo)] -struct S{} - -fn test() { - S{}; -} //^ S -"#, - ); -} - -#[test] -fn macro_in_arm() { - check_infer( - r#" - macro_rules! unit { - () => { () }; - } - - fn main() { - let x = match () { - unit!() => 92u32, - }; - } - "#, - expect![[r#" - 51..110 '{ ... }; }': () - 61..62 'x': u32 - 65..107 'match ... }': u32 - 71..73 '()': () - 84..91 'unit!()': () - 95..100 '92u32': u32 - "#]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs deleted file mode 100644 index fa68355aa..000000000 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ /dev/null @@ -1,1053 +0,0 @@ -use expect::expect; - -use super::{check_infer, check_types}; - -#[test] -fn infer_slice_method() { - check_infer( - r#" - #[lang = "slice"] - impl [T] { - fn foo(&self) -> T { - loop {} - } - } - - #[lang = "slice_alloc"] - impl [T] {} - - fn test(x: &[u8]) { - <[_]>::foo(x); - } - "#, - expect![[r#" - 44..48 'self': &[T] - 55..78 '{ ... }': T - 65..72 'loop {}': ! - 70..72 '{}': () - 130..131 'x': &[u8] - 140..162 '{ ...(x); }': () - 146..156 '<[_]>::foo': fn foo(&[u8]) -> u8 - 146..159 '<[_]>::foo(x)': u8 - 157..158 'x': &[u8] - "#]], - ); -} - -#[test] -fn infer_associated_method_struct() { - check_infer( - r#" - struct A { x: u32 } - - impl A { - fn new() -> A { - A { x: 0 } - } - } - fn test() { - let a = A::new(); - a.x; - } - "#, - expect![[r#" - 48..74 '{ ... }': A - 58..68 'A { x: 0 }': A - 65..66 '0': u32 - 87..121 '{ ...a.x; }': () - 97..98 'a': A - 101..107 'A::new': fn new() -> A - 101..109 'A::new()': A - 115..116 'a': A - 115..118 'a.x': u32 - "#]], - ); -} - -#[test] -fn infer_associated_method_enum() { - check_infer( - r#" - enum A { B, C } - - impl A { - pub fn b() -> A { - A::B - } - pub fn c() -> A { - A::C - } - } - fn test() { - let a = A::b(); - a; - let c = A::c(); - c; - } - "#, - expect![[r#" - 46..66 '{ ... }': A - 56..60 'A::B': A - 87..107 '{ ... }': A - 97..101 'A::C': A - 120..177 '{ ... c; }': () - 130..131 'a': A - 134..138 'A::b': fn b() -> A - 134..140 'A::b()': A - 146..147 'a': A - 157..158 'c': A - 161..165 'A::c': fn c() -> A - 161..167 'A::c()': A - 173..174 'c': A - "#]], - ); -} - -#[test] -fn infer_associated_method_with_modules() { - check_infer( - r#" - mod a { - struct A; - impl A { pub fn thing() -> A { A {} }} - } - - mod b { - struct B; - impl B { pub fn thing() -> u32 { 99 }} - - mod c { - struct C; - impl C { pub fn thing() -> C { C {} }} - } - } - use b::c; - - fn test() { - let x = a::A::thing(); - let y = b::B::thing(); - let z = c::C::thing(); - } - "#, - expect![[r#" - 55..63 '{ A {} }': A - 57..61 'A {}': A - 125..131 '{ 99 }': u32 - 127..129 '99': u32 - 201..209 '{ C {} }': C - 203..207 'C {}': C - 240..324 '{ ...g(); }': () - 250..251 'x': A - 254..265 'a::A::thing': fn thing() -> A - 254..267 'a::A::thing()': A - 277..278 'y': u32 - 281..292 'b::B::thing': fn thing() -> u32 - 281..294 'b::B::thing()': u32 - 304..305 'z': C - 308..319 'c::C::thing': fn thing() -> C - 308..321 'c::C::thing()': C - "#]], - ); -} - -#[test] -fn infer_associated_method_generics() { - check_infer( - r#" - struct Gen { - val: T - } - - impl Gen { - pub fn make(val: T) -> Gen { - Gen { val } - } - } - - fn test() { - let a = Gen::make(0u32); - } - "#, - expect![[r#" - 63..66 'val': T - 81..108 '{ ... }': Gen - 91..102 'Gen { val }': Gen - 97..100 'val': T - 122..154 '{ ...32); }': () - 132..133 'a': Gen - 136..145 'Gen::make': fn make(u32) -> Gen - 136..151 'Gen::make(0u32)': Gen - 146..150 '0u32': u32 - "#]], - ); -} - -#[test] -fn infer_associated_method_generics_without_args() { - check_infer( - r#" - struct Gen { - val: T - } - - impl Gen { - pub fn make() -> Gen { - loop { } - } - } - - fn test() { - let a = Gen::::make(); - } - "#, - expect![[r#" - 75..99 '{ ... }': Gen - 85..93 'loop { }': ! - 90..93 '{ }': () - 113..148 '{ ...e(); }': () - 123..124 'a': Gen - 127..143 'Gen::<...::make': fn make() -> Gen - 127..145 'Gen::<...make()': Gen - "#]], - ); -} - -#[test] -fn infer_associated_method_generics_2_type_params_without_args() { - check_infer( - r#" - struct Gen { - val: T, - val2: U, - } - - impl Gen { - pub fn make() -> Gen { - loop { } - } - } - - fn test() { - let a = Gen::::make(); - } - "#, - expect![[r#" - 101..125 '{ ... }': Gen - 111..119 'loop { }': ! - 116..119 '{ }': () - 139..179 '{ ...e(); }': () - 149..150 'a': Gen - 153..174 'Gen::<...::make': fn make() -> Gen - 153..176 'Gen::<...make()': Gen - "#]], - ); -} - -#[test] -fn cross_crate_associated_method_call() { - check_types( - r#" -//- /main.rs crate:main deps:other_crate -fn test() { - let x = other_crate::foo::S::thing(); - x; -} //^ i128 - -//- /lib.rs crate:other_crate -mod foo { - struct S; - impl S { - fn thing() -> i128 {} - } -} -"#, - ); -} - -#[test] -fn infer_trait_method_simple() { - // the trait implementation is intentionally incomplete -- it shouldn't matter - check_infer( - r#" - trait Trait1 { - fn method(&self) -> u32; - } - struct S1; - impl Trait1 for S1 {} - trait Trait2 { - fn method(&self) -> i128; - } - struct S2; - impl Trait2 for S2 {} - fn test() { - S1.method(); // -> u32 - S2.method(); // -> i128 - } - "#, - expect![[r#" - 30..34 'self': &Self - 109..113 'self': &Self - 169..227 '{ ...i128 }': () - 175..177 'S1': S1 - 175..186 'S1.method()': u32 - 202..204 'S2': S2 - 202..213 'S2.method()': i128 - "#]], - ); -} - -#[test] -fn infer_trait_method_scoped() { - // the trait implementation is intentionally incomplete -- it shouldn't matter - check_infer( - r#" - struct S; - mod foo { - pub trait Trait1 { - fn method(&self) -> u32; - } - impl Trait1 for super::S {} - } - mod bar { - pub trait Trait2 { - fn method(&self) -> i128; - } - impl Trait2 for super::S {} - } - - mod foo_test { - use super::S; - use super::foo::Trait1; - fn test() { - S.method(); // -> u32 - } - } - - mod bar_test { - use super::S; - use super::bar::Trait2; - fn test() { - S.method(); // -> i128 - } - } - "#, - expect![[r#" - 62..66 'self': &Self - 168..172 'self': &Self - 299..336 '{ ... }': () - 309..310 'S': S - 309..319 'S.method()': u32 - 415..453 '{ ... }': () - 425..426 'S': S - 425..435 'S.method()': i128 - "#]], - ); -} - -#[test] -fn infer_trait_method_generic_1() { - // the trait implementation is intentionally incomplete -- it shouldn't matter - check_infer( - r#" - trait Trait { - fn method(&self) -> T; - } - struct S; - impl Trait for S {} - fn test() { - S.method(); - } - "#, - expect![[r#" - 32..36 'self': &Self - 91..110 '{ ...d(); }': () - 97..98 'S': S - 97..107 'S.method()': u32 - "#]], - ); -} - -#[test] -fn infer_trait_method_generic_more_params() { - // the trait implementation is intentionally incomplete -- it shouldn't matter - check_infer( - r#" - trait Trait { - fn method1(&self) -> (T1, T2, T3); - fn method2(&self) -> (T3, T2, T1); - } - struct S1; - impl Trait for S1 {} - struct S2; - impl Trait for S2 {} - fn test() { - S1.method1(); // u8, u16, u32 - S1.method2(); // u32, u16, u8 - S2.method1(); // i8, i16, {unknown} - S2.method2(); // {unknown}, i16, i8 - } - "#, - expect![[r#" - 42..46 'self': &Self - 81..85 'self': &Self - 209..360 '{ ..., i8 }': () - 215..217 'S1': S1 - 215..227 'S1.method1()': (u8, u16, u32) - 249..251 'S1': S1 - 249..261 'S1.method2()': (u32, u16, u8) - 283..285 'S2': S2 - 283..295 'S2.method1()': (i8, i16, {unknown}) - 323..325 'S2': S2 - 323..335 'S2.method2()': ({unknown}, i16, i8) - "#]], - ); -} - -#[test] -fn infer_trait_method_generic_2() { - // the trait implementation is intentionally incomplete -- it shouldn't matter - check_infer( - r#" - trait Trait { - fn method(&self) -> T; - } - struct S(T); - impl Trait for S {} - fn test() { - S(1u32).method(); - } - "#, - expect![[r#" - 32..36 'self': &Self - 101..126 '{ ...d(); }': () - 107..108 'S': S(u32) -> S - 107..114 'S(1u32)': S - 107..123 'S(1u32...thod()': u32 - 109..113 '1u32': u32 - "#]], - ); -} - -#[test] -fn infer_trait_assoc_method() { - check_infer( - r#" - trait Default { - fn default() -> Self; - } - struct S; - impl Default for S {} - fn test() { - let s1: S = Default::default(); - let s2 = S::default(); - let s3 = ::default(); - } - "#, - expect![[r#" - 86..192 '{ ...t(); }': () - 96..98 's1': S - 104..120 'Defaul...efault': fn default() -> S - 104..122 'Defaul...ault()': S - 132..134 's2': S - 137..147 'S::default': fn default() -> S - 137..149 'S::default()': S - 159..161 's3': S - 164..187 '() -> S - 164..189 ' { - fn make() -> T; - } - struct S; - impl Trait for S {} - struct G; - impl Trait for G {} - fn test() { - let a = S::make(); - let b = G::::make(); - let c: f64 = G::make(); - } - "#, - expect![[r#" - 126..210 '{ ...e(); }': () - 136..137 'a': u32 - 140..147 'S::make': fn make() -> u32 - 140..149 'S::make()': u32 - 159..160 'b': u64 - 163..177 'G::::make': fn make, u64>() -> u64 - 163..179 'G::, f64>() -> f64 - 198..207 'G::make()': f64 - "#]], - ); -} - -#[test] -fn infer_trait_assoc_method_generics_2() { - check_infer( - r#" - trait Trait { - fn make() -> (T, U); - } - struct S; - impl Trait for S {} - struct G; - impl Trait for G {} - fn test() { - let a = S::make::(); - let b: (_, i64) = S::make(); - let c = G::::make::(); - let d: (u32, _) = G::make::(); - let e: (u32, i64) = G::make(); - } - "#, - expect![[r#" - 134..312 '{ ...e(); }': () - 144..145 'a': (u32, i64) - 148..162 'S::make::': fn make() -> (u32, i64) - 148..164 'S::mak...i64>()': (u32, i64) - 174..175 'b': (u32, i64) - 188..195 'S::make': fn make() -> (u32, i64) - 188..197 'S::make()': (u32, i64) - 207..208 'c': (u32, i64) - 211..232 'G::': fn make, u32, i64>() -> (u32, i64) - 211..234 'G::()': (u32, i64) - 244..245 'd': (u32, i64) - 258..272 'G::make::': fn make, u32, i64>() -> (u32, i64) - 258..274 'G::mak...i64>()': (u32, i64) - 284..285 'e': (u32, i64) - 300..307 'G::make': fn make, u32, i64>() -> (u32, i64) - 300..309 'G::make()': (u32, i64) - "#]], - ); -} - -#[test] -fn infer_trait_assoc_method_generics_3() { - check_infer( - r#" - trait Trait { - fn make() -> (Self, T); - } - struct S; - impl Trait for S {} - fn test() { - let a = S::make(); - } - "#, - expect![[r#" - 100..126 '{ ...e(); }': () - 110..111 'a': (S, i64) - 114..121 'S::make': fn make, i64>() -> (S, i64) - 114..123 'S::make()': (S, i64) - "#]], - ); -} - -#[test] -fn infer_trait_assoc_method_generics_4() { - check_infer( - r#" - trait Trait { - fn make() -> (Self, T); - } - struct S; - impl Trait for S {} - impl Trait for S {} - fn test() { - let a: (S, _) = S::make(); - let b: (_, i32) = S::make(); - } - "#, - expect![[r#" - 130..202 '{ ...e(); }': () - 140..141 'a': (S, i64) - 157..164 'S::make': fn make, i64>() -> (S, i64) - 157..166 'S::make()': (S, i64) - 176..177 'b': (S, i32) - 190..197 'S::make': fn make, i32>() -> (S, i32) - 190..199 'S::make()': (S, i32) - "#]], - ); -} - -#[test] -fn infer_trait_assoc_method_generics_5() { - check_infer( - r#" - trait Trait { - fn make() -> (Self, T, U); - } - struct S; - impl Trait for S {} - fn test() { - let a = >::make::(); - let b: (S, _, _) = Trait::::make::(); - } - "#, - expect![[r#" - 106..210 '{ ...>(); }': () - 116..117 'a': (S, i64, u8) - 120..149 '': fn make, i64, u8>() -> (S, i64, u8) - 120..151 '()': (S, i64, u8) - 161..162 'b': (S, i64, u8) - 181..205 'Trait:...::': fn make, i64, u8>() -> (S, i64, u8) - 181..207 'Trait:...()': (S, i64, u8) - "#]], - ); -} - -#[test] -fn infer_call_trait_method_on_generic_param_1() { - check_infer( - r#" - trait Trait { - fn method(&self) -> u32; - } - fn test(t: T) { - t.method(); - } - "#, - expect![[r#" - 29..33 'self': &Self - 63..64 't': T - 69..88 '{ ...d(); }': () - 75..76 't': T - 75..85 't.method()': u32 - "#]], - ); -} - -#[test] -fn infer_call_trait_method_on_generic_param_2() { - check_infer( - r#" - trait Trait { - fn method(&self) -> T; - } - fn test>(t: T) { - t.method(); - } - "#, - expect![[r#" - 32..36 'self': &Self - 70..71 't': T - 76..95 '{ ...d(); }': () - 82..83 't': T - 82..92 't.method()': U - "#]], - ); -} - -#[test] -fn infer_with_multiple_trait_impls() { - check_infer( - r#" - trait Into { - fn into(self) -> T; - } - struct S; - impl Into for S {} - impl Into for S {} - fn test() { - let x: u32 = S.into(); - let y: u64 = S.into(); - let z = Into::::into(S); - } - "#, - expect![[r#" - 28..32 'self': Self - 110..201 '{ ...(S); }': () - 120..121 'x': u32 - 129..130 'S': S - 129..137 'S.into()': u32 - 147..148 'y': u64 - 156..157 'S': S - 156..164 'S.into()': u64 - 174..175 'z': u64 - 178..195 'Into::...::into': fn into(S) -> u64 - 178..198 'Into::...nto(S)': u64 - 196..197 'S': S - "#]], - ); -} - -#[test] -fn method_resolution_unify_impl_self_type() { - check_types( - r#" -struct S; -impl S { fn foo(&self) -> u8 {} } -impl S { fn foo(&self) -> i8 {} } -fn test() { (S::.foo(), S::.foo()); } - //^ (u8, i8) -"#, - ); -} - -#[test] -fn method_resolution_trait_before_autoref() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl S { fn foo(&self) -> i8 { 0 } } -impl Trait for S { fn foo(self) -> u128 { 0 } } -fn test() { S.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn method_resolution_by_value_before_autoref() { - check_types( - r#" -trait Clone { fn clone(&self) -> Self; } -struct S; -impl Clone for S {} -impl Clone for &S {} -fn test() { (S.clone(), (&S).clone(), (&&S).clone()); } - //^ (S, S, &S) -"#, - ); -} - -#[test] -fn method_resolution_trait_before_autoderef() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl S { fn foo(self) -> i8 { 0 } } -impl Trait for &S { fn foo(self) -> u128 { 0 } } -fn test() { (&S).foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn method_resolution_impl_before_trait() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl S { fn foo(self) -> i8 { 0 } } -impl Trait for S { fn foo(self) -> u128 { 0 } } -fn test() { S.foo(); } - //^ i8 -"#, - ); -} - -#[test] -fn method_resolution_impl_ref_before_trait() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl S { fn foo(&self) -> i8 { 0 } } -impl Trait for &S { fn foo(self) -> u128 { 0 } } -fn test() { S.foo(); } - //^ i8 -"#, - ); -} - -#[test] -fn method_resolution_trait_autoderef() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for S { fn foo(self) -> u128 { 0 } } -fn test() { (&S).foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn method_resolution_unsize_array() { - check_types( - r#" -#[lang = "slice"] -impl [T] { - fn len(&self) -> usize { loop {} } -} -fn test() { - let a = [1, 2, 3]; - a.len(); -} //^ usize -"#, - ); -} - -#[test] -fn method_resolution_trait_from_prelude() { - check_types( - r#" -//- /main.rs crate:main deps:other_crate -struct S; -impl Clone for S {} - -fn test() { - S.clone(); - //^ S -} - -//- /lib.rs crate:other_crate -#[prelude_import] use foo::*; - -mod foo { - trait Clone { - fn clone(&self) -> Self; - } -} -"#, - ); -} - -#[test] -fn method_resolution_where_clause_for_unknown_trait() { - // The blanket impl currently applies because we ignore the unresolved where clause - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for T where T: UnknownTrait {} -fn test() { (&S).foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn method_resolution_where_clause_not_met() { - // The blanket impl shouldn't apply because we can't prove S: Clone - // This is also to make sure that we don't resolve to the foo method just - // because that's the only method named foo we can find, which would make - // the below tests not work - check_types( - r#" -trait Clone {} -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for T where T: Clone {} -fn test() { (&S).foo(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_where_clause_inline_not_met() { - // The blanket impl shouldn't apply because we can't prove S: Clone - check_types( - r#" -trait Clone {} -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for T {} -fn test() { (&S).foo(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_where_clause_1() { - check_types( - r#" -trait Clone {} -trait Trait { fn foo(self) -> u128; } -struct S; -impl Clone for S {} -impl Trait for T where T: Clone {} -fn test() { S.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn method_resolution_where_clause_2() { - check_types( - r#" -trait Into { fn into(self) -> T; } -trait From { fn from(other: T) -> Self; } -struct S1; -struct S2; -impl From for S1 {} -impl Into for T where U: From {} -fn test() { S2.into(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_where_clause_inline() { - check_types( - r#" -trait Into { fn into(self) -> T; } -trait From { fn from(other: T) -> Self; } -struct S1; -struct S2; -impl From for S1 {} -impl> Into for T {} -fn test() { S2.into(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_overloaded_method() { - test_utils::mark::check!(impl_self_type_match_without_receiver); - check_types( - r#" -struct Wrapper(T); -struct Foo(T); -struct Bar(T); - -impl Wrapper> { - pub fn new(foo_: T) -> Self { - Wrapper(Foo(foo_)) - } -} - -impl Wrapper> { - pub fn new(bar_: T) -> Self { - Wrapper(Bar(bar_)) - } -} - -fn main() { - let a = Wrapper::>::new(1.0); - let b = Wrapper::>::new(1.0); - (a, b); - //^ (Wrapper>, Wrapper>) -} -"#, - ); -} - -#[test] -fn method_resolution_encountering_fn_type() { - check_types( - r#" -//- /main.rs -fn foo() {} -trait FnOnce { fn call(self); } -fn test() { foo.call(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_non_parameter_type() { - check_types( - r#" -mod a { - pub trait Foo { - fn foo(&self); - } -} - -struct Wrapper(T); -fn foo(t: Wrapper) -where - Wrapper: a::Foo, -{ - t.foo(); -} //^ {unknown} -"#, - ); -} - -#[test] -fn method_resolution_3373() { - check_types( - r#" -struct A(T); - -impl A { - fn from(v: i32) -> A { A(v) } -} - -fn main() { - A::from(3); -} //^ A -"#, - ); -} - -#[test] -fn method_resolution_slow() { - // this can get quite slow if we set the solver size limit too high - check_types( - r#" -trait SendX {} - -struct S1; impl SendX for S1 {} -struct S2; impl SendX for S2 {} -struct U1; - -trait Trait { fn method(self); } - -struct X1 {} -impl SendX for X1 where A: SendX, B: SendX {} - -struct S {} - -trait FnX {} - -impl Trait for S where C: FnX, B: SendX {} - -fn test() { (S {}).method(); } - //^ () -"#, - ); -} - -#[test] -fn dyn_trait_super_trait_not_in_scope() { - check_infer( - r#" - mod m { - pub trait SuperTrait { - fn foo(&self) -> u32 { 0 } - } - } - trait Trait: m::SuperTrait {} - - struct S; - impl m::SuperTrait for S {} - impl Trait for S {} - - fn test(d: &dyn Trait) { - d.foo(); - } - "#, - expect![[r#" - 51..55 'self': &Self - 64..69 '{ 0 }': u32 - 66..67 '0': u32 - 176..177 'd': &dyn Trait - 191..207 '{ ...o(); }': () - 197..198 'd': &dyn Trait - 197..204 'd.foo()': u32 - "#]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs deleted file mode 100644 index 49538b572..000000000 --- a/crates/ra_hir_ty/src/tests/never_type.rs +++ /dev/null @@ -1,409 +0,0 @@ -use expect::expect; - -use super::{check_infer_with_mismatches, check_types}; - -#[test] -fn infer_never1() { - check_types( - r#" -fn test() { - let t = return; - t; -} //^ ! -"#, - ); -} - -#[test] -fn infer_never2() { - check_types( - r#" -fn gen() -> T { loop {} } - -fn test() { - let a = gen(); - if false { a } else { loop {} }; - a; -} //^ ! -"#, - ); -} - -#[test] -fn infer_never3() { - check_types( - r#" -fn gen() -> T { loop {} } - -fn test() { - let a = gen(); - if false { loop {} } else { a }; - a; - //^ ! -} -"#, - ); -} - -#[test] -fn never_type_in_generic_args() { - check_types( - r#" -enum Option { None, Some(T) } - -fn test() { - let a = if true { Option::None } else { Option::Some(return) }; - a; -} //^ Option -"#, - ); -} - -#[test] -fn never_type_can_be_reinferred1() { - check_types( - r#" -fn gen() -> T { loop {} } - -fn test() { - let a = gen(); - if false { loop {} } else { a }; - a; - //^ () - if false { a }; -} -"#, - ); -} - -#[test] -fn never_type_can_be_reinferred2() { - check_types( - r#" -enum Option { None, Some(T) } - -fn test() { - let a = if true { Option::None } else { Option::Some(return) }; - a; - //^ Option - match 42 { - 42 => a, - _ => Option::Some(42), - }; -} -"#, - ); -} - -#[test] -fn never_type_can_be_reinferred3() { - check_types( - r#" -enum Option { None, Some(T) } - -fn test() { - let a = if true { Option::None } else { Option::Some(return) }; - a; - //^ Option<&str> - match 42 { - 42 => a, - _ => Option::Some("str"), - }; -} -"#, - ); -} - -#[test] -fn match_no_arm() { - check_types( - r#" -enum Void {} - -fn test(a: Void) { - let t = match a {}; - t; -} //^ ! -"#, - ); -} - -#[test] -fn match_unknown_arm() { - check_types( - r#" -fn test(a: Option) { - let t = match 0 { - _ => unknown, - }; - t; -} //^ {unknown} -"#, - ); -} - -#[test] -fn if_never() { - check_types( - r#" -fn test() { - let i = if true { - loop {} - } else { - 3.0 - }; - i; -} //^ f64 -"#, - ); -} - -#[test] -fn if_else_never() { - check_types( - r#" -fn test(input: bool) { - let i = if input { - 2.0 - } else { - return - }; - i; -} //^ f64 -"#, - ); -} - -#[test] -fn match_first_arm_never() { - check_types( - r#" -fn test(a: i32) { - let i = match a { - 1 => return, - 2 => 2.0, - 3 => loop {}, - _ => 3.0, - }; - i; -} //^ f64 -"#, - ); -} - -#[test] -fn match_second_arm_never() { - check_types( - r#" -fn test(a: i32) { - let i = match a { - 1 => 3.0, - 2 => loop {}, - 3 => 3.0, - _ => return, - }; - i; -} //^ f64 -"#, - ); -} - -#[test] -fn match_all_arms_never() { - check_types( - r#" -fn test(a: i32) { - let i = match a { - 2 => return, - _ => loop {}, - }; - i; -} //^ ! -"#, - ); -} - -#[test] -fn match_no_never_arms() { - check_types( - r#" -fn test(a: i32) { - let i = match a { - 2 => 2.0, - _ => 3.0, - }; - i; -} //^ f64 -"#, - ); -} - -#[test] -fn diverging_expression_1() { - check_infer_with_mismatches( - r" - //- /main.rs - fn test1() { - let x: u32 = return; - } - fn test2() { - let x: u32 = { return; }; - } - fn test3() { - let x: u32 = loop {}; - } - fn test4() { - let x: u32 = { loop {} }; - } - fn test5() { - let x: u32 = { if true { loop {}; } else { loop {}; } }; - } - fn test6() { - let x: u32 = { let y: u32 = { loop {}; }; }; - } - ", - expect![[r" - 11..39 '{ ...urn; }': () - 21..22 'x': u32 - 30..36 'return': ! - 51..84 '{ ...; }; }': () - 61..62 'x': u32 - 70..81 '{ return; }': u32 - 72..78 'return': ! - 96..125 '{ ... {}; }': () - 106..107 'x': u32 - 115..122 'loop {}': ! - 120..122 '{}': () - 137..170 '{ ...} }; }': () - 147..148 'x': u32 - 156..167 '{ loop {} }': u32 - 158..165 'loop {}': ! - 163..165 '{}': () - 182..246 '{ ...} }; }': () - 192..193 'x': u32 - 201..243 '{ if t...}; } }': u32 - 203..241 'if tru... {}; }': u32 - 206..210 'true': bool - 211..223 '{ loop {}; }': u32 - 213..220 'loop {}': ! - 218..220 '{}': () - 229..241 '{ loop {}; }': u32 - 231..238 'loop {}': ! - 236..238 '{}': () - 258..310 '{ ...; }; }': () - 268..269 'x': u32 - 277..307 '{ let ...; }; }': u32 - 283..284 'y': u32 - 292..304 '{ loop {}; }': u32 - 294..301 'loop {}': ! - 299..301 '{}': () - "]], - ); -} - -#[test] -fn diverging_expression_2() { - check_infer_with_mismatches( - r#" - //- /main.rs - fn test1() { - // should give type mismatch - let x: u32 = { loop {}; "foo" }; - } - "#, - expect![[r#" - 11..84 '{ ..." }; }': () - 54..55 'x': u32 - 63..81 '{ loop...foo" }': &str - 65..72 'loop {}': ! - 70..72 '{}': () - 74..79 '"foo"': &str - 63..81: expected u32, got &str - 74..79: expected u32, got &str - "#]], - ); -} - -#[test] -fn diverging_expression_3_break() { - check_infer_with_mismatches( - r" - //- /main.rs - fn test1() { - // should give type mismatch - let x: u32 = { loop { break; } }; - } - fn test2() { - // should give type mismatch - let x: u32 = { for a in b { break; }; }; - // should give type mismatch as well - let x: u32 = { for a in b {}; }; - // should give type mismatch as well - let x: u32 = { for a in b { return; }; }; - } - fn test3() { - // should give type mismatch - let x: u32 = { while true { break; }; }; - // should give type mismatch as well -- there's an implicit break, even if it's never hit - let x: u32 = { while true {}; }; - // should give type mismatch as well - let x: u32 = { while true { return; }; }; - } - ", - expect![[r" - 11..85 '{ ...} }; }': () - 54..55 'x': u32 - 63..82 '{ loop...k; } }': () - 65..80 'loop { break; }': () - 70..80 '{ break; }': () - 72..77 'break': ! - 63..82: expected u32, got () - 65..80: expected u32, got () - 97..343 '{ ...; }; }': () - 140..141 'x': u32 - 149..175 '{ for ...; }; }': () - 151..172 'for a ...eak; }': () - 155..156 'a': {unknown} - 160..161 'b': {unknown} - 162..172 '{ break; }': () - 164..169 'break': ! - 226..227 'x': u32 - 235..253 '{ for ... {}; }': () - 237..250 'for a in b {}': () - 241..242 'a': {unknown} - 246..247 'b': {unknown} - 248..250 '{}': () - 304..305 'x': u32 - 313..340 '{ for ...; }; }': () - 315..337 'for a ...urn; }': () - 319..320 'a': {unknown} - 324..325 'b': {unknown} - 326..337 '{ return; }': () - 328..334 'return': ! - 149..175: expected u32, got () - 235..253: expected u32, got () - 313..340: expected u32, got () - 355..654 '{ ...; }; }': () - 398..399 'x': u32 - 407..433 '{ whil...; }; }': () - 409..430 'while ...eak; }': () - 415..419 'true': bool - 420..430 '{ break; }': () - 422..427 'break': ! - 537..538 'x': u32 - 546..564 '{ whil... {}; }': () - 548..561 'while true {}': () - 554..558 'true': bool - 559..561 '{}': () - 615..616 'x': u32 - 624..651 '{ whil...; }; }': () - 626..648 'while ...urn; }': () - 632..636 'true': bool - 637..648 '{ return; }': () - 639..645 'return': ! - 407..433: expected u32, got () - 546..564: expected u32, got () - 624..651: expected u32, got () - "]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs deleted file mode 100644 index 39fabf7eb..000000000 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ /dev/null @@ -1,656 +0,0 @@ -use expect::expect; -use test_utils::mark; - -use super::{check_infer, check_infer_with_mismatches}; - -#[test] -fn infer_pattern() { - check_infer( - r#" - fn test(x: &i32) { - let y = x; - let &z = x; - let a = z; - let (c, d) = (1, "hello"); - - for (e, f) in some_iter { - let g = e; - } - - if let [val] = opt { - let h = val; - } - - let lambda = |a: u64, b, c: i32| { a + b; c }; - - let ref ref_to_x = x; - let mut mut_x = x; - let ref mut mut_ref_to_x = x; - let k = mut_ref_to_x; - } - "#, - expect![[r#" - 8..9 'x': &i32 - 17..368 '{ ...o_x; }': () - 27..28 'y': &i32 - 31..32 'x': &i32 - 42..44 '&z': &i32 - 43..44 'z': i32 - 47..48 'x': &i32 - 58..59 'a': i32 - 62..63 'z': i32 - 73..79 '(c, d)': (i32, &str) - 74..75 'c': i32 - 77..78 'd': &str - 82..94 '(1, "hello")': (i32, &str) - 83..84 '1': i32 - 86..93 '"hello"': &str - 101..151 'for (e... }': () - 105..111 '(e, f)': ({unknown}, {unknown}) - 106..107 'e': {unknown} - 109..110 'f': {unknown} - 115..124 'some_iter': {unknown} - 125..151 '{ ... }': () - 139..140 'g': {unknown} - 143..144 'e': {unknown} - 157..204 'if let... }': () - 164..169 '[val]': [{unknown}] - 165..168 'val': {unknown} - 172..175 'opt': [{unknown}] - 176..204 '{ ... }': () - 190..191 'h': {unknown} - 194..197 'val': {unknown} - 214..220 'lambda': |u64, u64, i32| -> i32 - 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 - 224..225 'a': u64 - 232..233 'b': u64 - 235..236 'c': i32 - 243..255 '{ a + b; c }': i32 - 245..246 'a': u64 - 245..250 'a + b': u64 - 249..250 'b': u64 - 252..253 'c': i32 - 266..278 'ref ref_to_x': &&i32 - 281..282 'x': &i32 - 292..301 'mut mut_x': &i32 - 304..305 'x': &i32 - 315..335 'ref mu...f_to_x': &mut &i32 - 338..339 'x': &i32 - 349..350 'k': &mut &i32 - 353..365 'mut_ref_to_x': &mut &i32 - "#]], - ); -} - -#[test] -fn infer_literal_pattern() { - check_infer_with_mismatches( - r#" - fn any() -> T { loop {} } - fn test(x: &i32) { - if let "foo" = any() {} - if let 1 = any() {} - if let 1u32 = any() {} - if let 1f32 = any() {} - if let 1.0 = any() {} - if let true = any() {} - } - "#, - expect![[r#" - 17..28 '{ loop {} }': T - 19..26 'loop {}': ! - 24..26 '{}': () - 37..38 'x': &i32 - 46..208 '{ ...) {} }': () - 52..75 'if let...y() {}': () - 59..64 '"foo"': &str - 59..64 '"foo"': &str - 67..70 'any': fn any<&str>() -> &str - 67..72 'any()': &str - 73..75 '{}': () - 80..99 'if let...y() {}': () - 87..88 '1': i32 - 87..88 '1': i32 - 91..94 'any': fn any() -> i32 - 91..96 'any()': i32 - 97..99 '{}': () - 104..126 'if let...y() {}': () - 111..115 '1u32': u32 - 111..115 '1u32': u32 - 118..121 'any': fn any() -> u32 - 118..123 'any()': u32 - 124..126 '{}': () - 131..153 'if let...y() {}': () - 138..142 '1f32': f32 - 138..142 '1f32': f32 - 145..148 'any': fn any() -> f32 - 145..150 'any()': f32 - 151..153 '{}': () - 158..179 'if let...y() {}': () - 165..168 '1.0': f64 - 165..168 '1.0': f64 - 171..174 'any': fn any() -> f64 - 171..176 'any()': f64 - 177..179 '{}': () - 184..206 'if let...y() {}': () - 191..195 'true': bool - 191..195 'true': bool - 198..201 'any': fn any() -> bool - 198..203 'any()': bool - 204..206 '{}': () - "#]], - ); -} - -#[test] -fn infer_range_pattern() { - check_infer_with_mismatches( - r#" - fn test(x: &i32) { - if let 1..76 = 2u32 {} - if let 1..=76 = 2u32 {} - } - "#, - expect![[r#" - 8..9 'x': &i32 - 17..75 '{ ...2 {} }': () - 23..45 'if let...u32 {}': () - 30..35 '1..76': u32 - 38..42 '2u32': u32 - 43..45 '{}': () - 50..73 'if let...u32 {}': () - 57..63 '1..=76': u32 - 66..70 '2u32': u32 - 71..73 '{}': () - "#]], - ); -} - -#[test] -fn infer_pattern_match_ergonomics() { - check_infer( - r#" - struct A(T); - - fn test() { - let A(n) = &A(1); - let A(n) = &mut A(1); - } - "#, - expect![[r#" - 27..78 '{ ...(1); }': () - 37..41 'A(n)': A - 39..40 'n': &i32 - 44..49 '&A(1)': &A - 45..46 'A': A(i32) -> A - 45..49 'A(1)': A - 47..48 '1': i32 - 59..63 'A(n)': A - 61..62 'n': &mut i32 - 66..75 '&mut A(1)': &mut A - 71..72 'A': A(i32) -> A - 71..75 'A(1)': A - 73..74 '1': i32 - "#]], - ); -} - -#[test] -fn infer_pattern_match_ergonomics_ref() { - mark::check!(match_ergonomics_ref); - check_infer( - r#" - fn test() { - let v = &(1, &2); - let (_, &w) = v; - } - "#, - expect![[r#" - 10..56 '{ ...= v; }': () - 20..21 'v': &(i32, &i32) - 24..32 '&(1, &2)': &(i32, &i32) - 25..32 '(1, &2)': (i32, &i32) - 26..27 '1': i32 - 29..31 '&2': &i32 - 30..31 '2': i32 - 42..49 '(_, &w)': (i32, &i32) - 43..44 '_': i32 - 46..48 '&w': &i32 - 47..48 'w': i32 - 52..53 'v': &(i32, &i32) - "#]], - ); -} - -#[test] -fn infer_pattern_match_slice() { - check_infer( - r#" - fn test() { - let slice: &[f64] = &[0.0]; - match slice { - &[] => {}, - &[a] => { - a; - }, - &[b, c] => { - b; - c; - } - _ => {} - } - } - "#, - expect![[r#" - 10..209 '{ ... } }': () - 20..25 'slice': &[f64] - 36..42 '&[0.0]': &[f64; _] - 37..42 '[0.0]': [f64; _] - 38..41 '0.0': f64 - 48..207 'match ... }': () - 54..59 'slice': &[f64] - 70..73 '&[]': &[f64] - 71..73 '[]': [f64] - 77..79 '{}': () - 89..93 '&[a]': &[f64] - 90..93 '[a]': [f64] - 91..92 'a': f64 - 97..123 '{ ... }': () - 111..112 'a': f64 - 133..140 '&[b, c]': &[f64] - 134..140 '[b, c]': [f64] - 135..136 'b': f64 - 138..139 'c': f64 - 144..185 '{ ... }': () - 158..159 'b': f64 - 173..174 'c': f64 - 194..195 '_': &[f64] - 199..201 '{}': () - "#]], - ); -} - -#[test] -fn infer_pattern_match_string_literal() { - check_infer_with_mismatches( - r#" - fn test() { - let s: &str = "hello"; - match s { - "hello" => {} - _ => {} - } - } - "#, - expect![[r#" - 10..98 '{ ... } }': () - 20..21 's': &str - 30..37 '"hello"': &str - 43..96 'match ... }': () - 49..50 's': &str - 61..68 '"hello"': &str - 61..68 '"hello"': &str - 72..74 '{}': () - 83..84 '_': &str - 88..90 '{}': () - "#]], - ); -} - -#[test] -fn infer_pattern_match_or() { - check_infer_with_mismatches( - r#" - fn test() { - let s: &str = "hello"; - match s { - "hello" | "world" => {} - _ => {} - } - } - "#, - expect![[r#" - 10..108 '{ ... } }': () - 20..21 's': &str - 30..37 '"hello"': &str - 43..106 'match ... }': () - 49..50 's': &str - 61..68 '"hello"': &str - 61..68 '"hello"': &str - 61..78 '"hello...world"': &str - 71..78 '"world"': &str - 71..78 '"world"': &str - 82..84 '{}': () - 93..94 '_': &str - 98..100 '{}': () - "#]], - ); -} - -#[test] -fn infer_pattern_match_arr() { - check_infer( - r#" - fn test() { - let arr: [f64; 2] = [0.0, 1.0]; - match arr { - [1.0, a] => { - a; - }, - [b, c] => { - b; - c; - } - } - } - "#, - expect![[r#" - 10..179 '{ ... } }': () - 20..23 'arr': [f64; _] - 36..46 '[0.0, 1.0]': [f64; _] - 37..40 '0.0': f64 - 42..45 '1.0': f64 - 52..177 'match ... }': () - 58..61 'arr': [f64; _] - 72..80 '[1.0, a]': [f64; _] - 73..76 '1.0': f64 - 73..76 '1.0': f64 - 78..79 'a': f64 - 84..110 '{ ... }': () - 98..99 'a': f64 - 120..126 '[b, c]': [f64; _] - 121..122 'b': f64 - 124..125 'c': f64 - 130..171 '{ ... }': () - 144..145 'b': f64 - 159..160 'c': f64 - "#]], - ); -} - -#[test] -fn infer_adt_pattern() { - check_infer( - r#" - enum E { - A { x: usize }, - B - } - - struct S(u32, E); - - fn test() { - let e = E::A { x: 3 }; - - let S(y, z) = foo; - let E::A { x: new_var } = e; - - match e { - E::A { x } => x, - E::B if foo => 1, - E::B => 10, - }; - - let ref d @ E::A { .. } = e; - d; - } - "#, - expect![[r#" - 67..288 '{ ... d; }': () - 77..78 'e': E - 81..94 'E::A { x: 3 }': E - 91..92 '3': usize - 105..112 'S(y, z)': S - 107..108 'y': u32 - 110..111 'z': E - 115..118 'foo': S - 128..147 'E::A {..._var }': E - 138..145 'new_var': usize - 150..151 'e': E - 158..244 'match ... }': usize - 164..165 'e': E - 176..186 'E::A { x }': E - 183..184 'x': usize - 190..191 'x': usize - 201..205 'E::B': E - 209..212 'foo': bool - 216..217 '1': usize - 227..231 'E::B': E - 235..237 '10': usize - 255..274 'ref d ...{ .. }': &E - 263..274 'E::A { .. }': E - 277..278 'e': E - 284..285 'd': &E - "#]], - ); -} - -#[test] -fn enum_variant_through_self_in_pattern() { - check_infer( - r#" - enum E { - A { x: usize }, - B(usize), - C - } - - impl E { - fn test() { - match (loop {}) { - Self::A { x } => { x; }, - Self::B(x) => { x; }, - Self::C => {}, - }; - } - } - "#, - expect![[r#" - 75..217 '{ ... }': () - 85..210 'match ... }': () - 92..99 'loop {}': ! - 97..99 '{}': () - 115..128 'Self::A { x }': E - 125..126 'x': usize - 132..138 '{ x; }': () - 134..135 'x': usize - 152..162 'Self::B(x)': E - 160..161 'x': usize - 166..172 '{ x; }': () - 168..169 'x': usize - 186..193 'Self::C': E - 197..199 '{}': () - "#]], - ); -} - -#[test] -fn infer_generics_in_patterns() { - check_infer( - r#" - struct A { - x: T, - } - - enum Option { - Some(T), - None, - } - - fn test(a1: A, o: Option) { - let A { x: x2 } = a1; - let A:: { x: x3 } = A { x: 1 }; - match o { - Option::Some(t) => t, - _ => 1, - }; - } - "#, - expect![[r#" - 78..80 'a1': A - 90..91 'o': Option - 106..243 '{ ... }; }': () - 116..127 'A { x: x2 }': A - 123..125 'x2': u32 - 130..132 'a1': A - 142..160 'A:: - 156..158 'x3': i64 - 163..173 'A { x: 1 }': A - 170..171 '1': i64 - 179..240 'match ... }': u64 - 185..186 'o': Option - 197..212 'Option::Some(t)': Option - 210..211 't': u64 - 216..217 't': u64 - 227..228 '_': Option - 232..233 '1': u64 - "#]], - ); -} - -#[test] -fn infer_const_pattern() { - check_infer_with_mismatches( - r#" - enum Option { None } - use Option::None; - struct Foo; - const Bar: usize = 1; - - fn test() { - let a: Option = None; - let b: Option = match a { - None => None, - }; - let _: () = match () { Foo => Foo }; // Expected mismatch - let _: () = match () { Bar => Bar }; // Expected mismatch - } - "#, - expect![[r#" - 73..74 '1': usize - 87..309 '{ ...atch }': () - 97..98 'a': Option - 114..118 'None': Option - 128..129 'b': Option - 145..182 'match ... }': Option - 151..152 'a': Option - 163..167 'None': Option - 171..175 'None': Option - 192..193 '_': () - 200..223 'match ... Foo }': Foo - 206..208 '()': () - 211..214 'Foo': Foo - 218..221 'Foo': Foo - 254..255 '_': () - 262..285 'match ... Bar }': usize - 268..270 '()': () - 273..276 'Bar': usize - 280..283 'Bar': usize - 200..223: expected (), got Foo - 262..285: expected (), got usize - "#]], - ); -} - -#[test] -fn infer_guard() { - check_infer( - r#" -struct S; -impl S { fn foo(&self) -> bool { false } } - -fn main() { - match S { - s if s.foo() => (), - } -} - "#, - expect![[r#" - 27..31 'self': &S - 41..50 '{ false }': bool - 43..48 'false': bool - 64..115 '{ ... } }': () - 70..113 'match ... }': () - 76..77 'S': S - 88..89 's': S - 93..94 's': S - 93..100 's.foo()': bool - 104..106 '()': () - "#]], - ) -} - -#[test] -fn match_ergonomics_in_closure_params() { - check_infer( - r#" - #[lang = "fn_once"] - trait FnOnce { - type Output; - } - - fn foo U>(t: T, f: F) -> U { loop {} } - - fn test() { - foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics - foo(&(1, "a"), |(x, y)| x); - } - "#, - expect![[r#" - 93..94 't': T - 99..100 'f': F - 110..121 '{ loop {} }': U - 112..119 'loop {}': ! - 117..119 '{}': () - 133..232 '{ ... x); }': () - 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 - 139..166 'foo(&(...y)| x)': i32 - 143..152 '&(1, "a")': &(i32, &str) - 144..152 '(1, "a")': (i32, &str) - 145..146 '1': i32 - 148..151 '"a"': &str - 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 - 155..162 '&(x, y)': &(i32, &str) - 156..162 '(x, y)': (i32, &str) - 157..158 'x': i32 - 160..161 'y': &str - 164..165 'x': i32 - 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 - 203..229 'foo(&(...y)| x)': &i32 - 207..216 '&(1, "a")': &(i32, &str) - 208..216 '(1, "a")': (i32, &str) - 209..210 '1': i32 - 212..215 '"a"': &str - 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 - 219..225 '(x, y)': (i32, &str) - 220..221 'x': &i32 - 223..224 'y': &&str - 227..228 'x': &i32 - "#]], - ); -} - -#[test] -fn slice_tail_pattern() { - check_infer( - r#" - fn foo(params: &[i32]) { - match params { - [head, tail @ ..] => { - } - } - } - "#, - expect![[r#" - 7..13 'params': &[i32] - 23..92 '{ ... } }': () - 29..90 'match ... }': () - 35..41 'params': &[i32] - 52..69 '[head,... @ ..]': [i32] - 53..57 'head': &i32 - 59..68 'tail @ ..': &[i32] - 66..68 '..': [i32] - 73..84 '{ }': () - "#]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs deleted file mode 100644 index b9ab0f357..000000000 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ /dev/null @@ -1,842 +0,0 @@ -use expect::expect; -use test_utils::mark; - -use super::{check_infer, check_types}; - -#[test] -fn bug_484() { - check_infer( - r#" - fn test() { - let x = if true {}; - } - "#, - expect![[r#" - 10..37 '{ ... {}; }': () - 20..21 'x': () - 24..34 'if true {}': () - 27..31 'true': bool - 32..34 '{}': () - "#]], - ); -} - -#[test] -fn no_panic_on_field_of_enum() { - check_infer( - r#" - enum X {} - - fn test(x: X) { - x.some_field; - } - "#, - expect![[r#" - 19..20 'x': X - 25..46 '{ ...eld; }': () - 31..32 'x': X - 31..43 'x.some_field': {unknown} - "#]], - ); -} - -#[test] -fn bug_585() { - check_infer( - r#" - fn test() { - X {}; - match x { - A::B {} => (), - A::Y() => (), - } - } - "#, - expect![[r#" - 10..88 '{ ... } }': () - 16..20 'X {}': {unknown} - 26..86 'match ... }': () - 32..33 'x': {unknown} - 44..51 'A::B {}': {unknown} - 55..57 '()': () - 67..73 'A::Y()': {unknown} - 77..79 '()': () - "#]], - ); -} - -#[test] -fn bug_651() { - check_infer( - r#" - fn quux() { - let y = 92; - 1 + y; - } - "#, - expect![[r#" - 10..40 '{ ...+ y; }': () - 20..21 'y': i32 - 24..26 '92': i32 - 32..33 '1': i32 - 32..37 '1 + y': i32 - 36..37 'y': i32 - "#]], - ); -} - -#[test] -fn recursive_vars() { - mark::check!(type_var_cycles_resolve_completely); - mark::check!(type_var_cycles_resolve_as_possible); - check_infer( - r#" - fn test() { - let y = unknown; - [y, &y]; - } - "#, - expect![[r#" - 10..47 '{ ...&y]; }': () - 20..21 'y': &{unknown} - 24..31 'unknown': &{unknown} - 37..44 '[y, &y]': [&&{unknown}; _] - 38..39 'y': &{unknown} - 41..43 '&y': &&{unknown} - 42..43 'y': &{unknown} - "#]], - ); -} - -#[test] -fn recursive_vars_2() { - check_infer( - r#" - fn test() { - let x = unknown; - let y = unknown; - [(x, y), (&y, &x)]; - } - "#, - expect![[r#" - 10..79 '{ ...x)]; }': () - 20..21 'x': &&{unknown} - 24..31 'unknown': &&{unknown} - 41..42 'y': &&{unknown} - 45..52 'unknown': &&{unknown} - 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] - 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) - 60..61 'x': &&{unknown} - 63..64 'y': &&{unknown} - 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) - 68..70 '&y': &&&{unknown} - 69..70 'y': &&{unknown} - 72..74 '&x': &&&{unknown} - 73..74 'x': &&{unknown} - "#]], - ); -} - -#[test] -fn infer_std_crash_1() { - // caused stack overflow, taken from std - check_infer( - r#" - enum Maybe { - Real(T), - Fake, - } - - fn write() { - match something_unknown { - Maybe::Real(ref mut something) => (), - } - } - "#, - expect![[r#" - 53..138 '{ ... } }': () - 59..136 'match ... }': () - 65..82 'someth...nknown': Maybe<{unknown}> - 93..123 'Maybe:...thing)': Maybe<{unknown}> - 105..122 'ref mu...ething': &mut {unknown} - 127..129 '()': () - "#]], - ); -} - -#[test] -fn infer_std_crash_2() { - mark::check!(type_var_resolves_to_int_var); - // caused "equating two type variables, ...", taken from std - check_infer( - r#" - fn test_line_buffer() { - &[0, b'\n', 1, b'\n']; - } - "#, - expect![[r#" - 22..52 '{ ...n']; }': () - 28..49 '&[0, b...b'\n']': &[u8; _] - 29..49 '[0, b'...b'\n']': [u8; _] - 30..31 '0': u8 - 33..38 'b'\n'': u8 - 40..41 '1': u8 - 43..48 'b'\n'': u8 - "#]], - ); -} - -#[test] -fn infer_std_crash_3() { - // taken from rustc - check_infer( - r#" - pub fn compute() { - match nope!() { - SizeSkeleton::Pointer { non_zero: true, tail } => {} - } - } - "#, - expect![[r#" - 17..107 '{ ... } }': () - 23..105 'match ... }': () - 29..36 'nope!()': {unknown} - 47..93 'SizeSk...tail }': {unknown} - 81..85 'true': bool - 81..85 'true': bool - 87..91 'tail': {unknown} - 97..99 '{}': () - "#]], - ); -} - -#[test] -fn infer_std_crash_4() { - // taken from rustc - check_infer( - r#" - pub fn primitive_type() { - match *self { - BorrowedRef { type_: Primitive(p), ..} => {}, - } - } - "#, - expect![[r#" - 24..105 '{ ... } }': () - 30..103 'match ... }': () - 36..41 '*self': {unknown} - 37..41 'self': {unknown} - 52..90 'Borrow...), ..}': {unknown} - 73..85 'Primitive(p)': {unknown} - 83..84 'p': {unknown} - 94..96 '{}': () - "#]], - ); -} - -#[test] -fn infer_std_crash_5() { - // taken from rustc - check_infer( - r#" - fn extra_compiler_flags() { - for content in doesnt_matter { - let name = if doesnt_matter { - first - } else { - &content - }; - - let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { - name - } else { - content - }; - } - } - "#, - expect![[r#" - 26..322 '{ ... } }': () - 32..320 'for co... }': () - 36..43 'content': &{unknown} - 47..60 'doesnt_matter': {unknown} - 61..320 '{ ... }': () - 75..79 'name': &&{unknown} - 82..166 'if doe... }': &&{unknown} - 85..98 'doesnt_matter': bool - 99..128 '{ ... }': &&{unknown} - 113..118 'first': &&{unknown} - 134..166 '{ ... }': &&{unknown} - 148..156 '&content': &&{unknown} - 149..156 'content': &{unknown} - 181..188 'content': &{unknown} - 191..313 'if ICE... }': &{unknown} - 194..231 'ICE_RE..._VALUE': {unknown} - 194..247 'ICE_RE...&name)': bool - 241..246 '&name': &&&{unknown} - 242..246 'name': &&{unknown} - 248..276 '{ ... }': &&{unknown} - 262..266 'name': &&{unknown} - 282..313 '{ ... }': &{unknown} - 296..303 'content': &{unknown} - "#]], - ); -} - -#[test] -fn infer_nested_generics_crash() { - // another crash found typechecking rustc - check_infer( - r#" - struct Canonical { - value: V, - } - struct QueryResponse { - value: V, - } - fn test(query_response: Canonical>) { - &query_response.value; - } - "#, - expect![[r#" - 91..105 'query_response': Canonical> - 136..166 '{ ...lue; }': () - 142..163 '&query....value': &QueryResponse - 143..157 'query_response': Canonical> - 143..163 'query_....value': QueryResponse - "#]], - ); -} - -#[test] -fn infer_paren_macro_call() { - check_infer( - r#" - macro_rules! bar { () => {0u32} } - fn test() { - let a = (bar!()); - } - "#, - expect![[r#" - !0..4 '0u32': u32 - 44..69 '{ ...()); }': () - 54..55 'a': u32 - "#]], - ); -} - -#[test] -fn bug_1030() { - check_infer( - r#" - struct HashSet; - struct FxHasher; - type FxHashSet = HashSet; - - impl HashSet { - fn default() -> HashSet {} - } - - pub fn main_loop() { - FxHashSet::default(); - } - "#, - expect![[r#" - 143..145 '{}': () - 168..197 '{ ...t(); }': () - 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> - 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> - "#]], - ); -} - -#[test] -fn issue_2669() { - check_infer( - r#" - trait A {} - trait Write {} - struct Response {} - - trait D { - fn foo(); - } - - impl D for Response { - fn foo() { - end(); - fn end() { - let _x: T = loop {}; - } - } - } - "#, - expect![[r#" - 119..214 '{ ... }': () - 129..132 'end': fn end<{unknown}>() - 129..134 'end()': () - 163..208 '{ ... }': () - 181..183 '_x': ! - 190..197 'loop {}': ! - 195..197 '{}': () - "#]], - ) -} - -#[test] -fn issue_2705() { - check_infer( - r#" - trait Trait {} - fn test() { - >::foo() - } - "#, - expect![[r#" - 25..52 '{ ...oo() }': () - 31..48 '::foo': {unknown} - 31..50 '; - (chars.next(), chars.nth(1)); -} //^ (Option, Option) - -//- /std.rs crate:std -#[prelude_import] -use prelude::*; - -pub mod prelude { - pub use crate::iter::Iterator; - pub use crate::option::Option; -} - -pub mod iter { - pub use self::traits::Iterator; - pub mod traits { - pub use self::iterator::Iterator; - - pub mod iterator { - pub trait Iterator { - type Item; - fn next(&mut self) -> Option; - fn nth(&mut self, n: usize) -> Option {} - } - } - } -} - -pub mod option { - pub enum Option {} -} - -pub mod str { - pub struct Chars<'a> {} - impl<'a> Iterator for Chars<'a> { - type Item = char; - fn next(&mut self) -> Option {} - } -} -"#, - ); -} - -#[test] -fn issue_3642_bad_macro_stackover() { - check_types( - r#" -#[macro_export] -macro_rules! match_ast { - (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; - - (match ($node:expr) { - $( ast::$ast:ident($it:ident) => $res:expr, )* - _ => $catch_all:expr $(,)? - }) => {{ - $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )* - { $catch_all } - }}; -} - -fn main() { - let anchor = match_ast! { - //^ () - match parent { - as => {}, - _ => return None - } - }; -}"#, - ); -} - -#[test] -fn issue_3999_slice() { - check_infer( - r#" - fn foo(params: &[usize]) { - match params { - [ps @ .., _] => {} - } - } - "#, - expect![[r#" - 7..13 'params': &[usize] - 25..80 '{ ... } }': () - 31..78 'match ... }': () - 37..43 'params': &[usize] - 54..66 '[ps @ .., _]': [usize] - 55..62 'ps @ ..': &[usize] - 60..62 '..': [usize] - 64..65 '_': usize - 70..72 '{}': () - "#]], - ); -} - -#[test] -fn issue_3999_struct() { - // rust-analyzer should not panic on seeing this malformed - // record pattern. - check_infer( - r#" - struct Bar { - a: bool, - } - fn foo(b: Bar) { - match b { - Bar { a: .. } => {}, - } - } - "#, - expect![[r#" - 35..36 'b': Bar - 43..95 '{ ... } }': () - 49..93 'match ... }': () - 55..56 'b': Bar - 67..80 'Bar { a: .. }': Bar - 76..78 '..': bool - 84..86 '{}': () - "#]], - ); -} - -#[test] -fn issue_4235_name_conflicts() { - check_infer( - r#" - struct FOO {} - static FOO:FOO = FOO {}; - - impl FOO { - fn foo(&self) {} - } - - fn main() { - let a = &FOO; - a.foo(); - } - "#, - expect![[r#" - 31..37 'FOO {}': FOO - 63..67 'self': &FOO - 69..71 '{}': () - 85..119 '{ ...o(); }': () - 95..96 'a': &FOO - 99..103 '&FOO': &FOO - 100..103 'FOO': FOO - 109..110 'a': &FOO - 109..116 'a.foo()': () - "#]], - ); -} - -#[test] -fn issue_4465_dollar_crate_at_type() { - check_infer( - r#" - pub struct Foo {} - pub fn anything() -> T { - loop {} - } - macro_rules! foo { - () => {{ - let r: $crate::Foo = anything(); - r - }}; - } - fn main() { - let _a = foo!(); - } - "#, - expect![[r#" - 44..59 '{ loop {} }': T - 50..57 'loop {}': ! - 55..57 '{}': () - !0..31 '{letr:...g();r}': Foo - !4..5 'r': Foo - !18..26 'anything': fn anything() -> Foo - !18..28 'anything()': Foo - !29..30 'r': Foo - 163..187 '{ ...!(); }': () - 173..175 '_a': Foo - "#]], - ); -} - -#[test] -fn issue_4053_diesel_where_clauses() { - check_infer( - r#" - trait BoxedDsl { - type Output; - fn internal_into_boxed(self) -> Self::Output; - } - - struct SelectStatement { - order: Order, - } - - trait QueryFragment {} - - trait Into { fn into(self) -> T; } - - impl BoxedDsl - for SelectStatement - where - O: Into>, - { - type Output = XXX; - - fn internal_into_boxed(self) -> Self::Output { - self.order.into(); - } - } - "#, - expect![[r#" - 65..69 'self': Self - 267..271 'self': Self - 466..470 'self': SelectStatement - 488..522 '{ ... }': () - 498..502 'self': SelectStatement - 498..508 'self.order': O - 498..515 'self.o...into()': dyn QueryFragment - "#]], - ); -} - -#[test] -fn issue_4953() { - check_infer( - r#" - pub struct Foo(pub i64); - impl Foo { - fn test() -> Self { Self(0i64) } - } - "#, - expect![[r#" - 58..72 '{ Self(0i64) }': Foo - 60..64 'Self': Foo(i64) -> Foo - 60..70 'Self(0i64)': Foo - 65..69 '0i64': i64 - "#]], - ); - check_infer( - r#" - pub struct Foo(pub T); - impl Foo { - fn test() -> Self { Self(0i64) } - } - "#, - expect![[r#" - 64..78 '{ Self(0i64) }': Foo - 66..70 'Self': Foo(i64) -> Foo - 66..76 'Self(0i64)': Foo - 71..75 '0i64': i64 - "#]], - ); -} - -#[test] -fn issue_4931() { - check_infer( - r#" - trait Div { - type Output; - } - - trait CheckedDiv: Div<()> {} - - trait PrimInt: CheckedDiv { - fn pow(self); - } - - fn check(i: T) { - i.pow(); - } - "#, - expect![[r#" - 117..121 'self': Self - 148..149 'i': T - 154..170 '{ ...w(); }': () - 160..161 'i': T - 160..167 'i.pow()': () - "#]], - ); -} - -#[test] -fn issue_4885() { - check_infer( - r#" - #[lang = "coerce_unsized"] - pub trait CoerceUnsized {} - - trait Future { - type Output; - } - trait Foo { - type Bar; - } - fn foo(key: &K) -> impl Future - where - K: Foo, - { - bar(key) - } - fn bar(key: &K) -> impl Future - where - K: Foo, - { - } - "#, - expect![[r#" - 136..139 'key': &K - 198..214 '{ ...key) }': impl Future>::Bar> - 204..207 'bar': fn bar(&K) -> impl Future>::Bar> - 204..212 'bar(key)': impl Future>::Bar> - 208..211 'key': &K - 228..231 'key': &K - 290..293 '{ }': () - "#]], - ); -} - -#[test] -fn issue_4800() { - check_infer( - r#" - trait Debug {} - - struct Foo; - - type E1 = (T, T, T); - type E2 = E1>>; - - impl Debug for Foo> {} - - struct Request; - - pub trait Future { - type Output; - } - - pub struct PeerSet; - - impl Service for PeerSet - where - D: Discover, - D::Key: Debug, - { - type Error = (); - type Future = dyn Future; - - fn call(&mut self) -> Self::Future { - loop {} - } - } - - pub trait Discover { - type Key; - } - - pub trait Service { - type Error; - type Future: Future; - fn call(&mut self) -> Self::Future; - } - "#, - expect![[r#" - 379..383 'self': &mut PeerSet - 401..424 '{ ... }': dyn Future - 411..418 'loop {}': ! - 416..418 '{}': () - 575..579 'self': &mut Self - "#]], - ); -} - -#[test] -fn issue_4966() { - check_infer( - r#" - pub trait IntoIterator { - type Item; - } - - struct Repeat { element: A } - - struct Map { f: F } - - struct Vec {} - - #[lang = "deref"] - pub trait Deref { - type Target; - } - - impl Deref for Vec { - type Target = [T]; - } - - fn from_iter>(iter: T) -> Vec {} - - fn main() { - let inner = Map { f: |_: &f64| 0.0 }; - - let repeat = Repeat { element: inner }; - - let vec = from_iter(repeat); - - vec.foo_bar(); - } - "#, - expect![[r#" - 270..274 'iter': T - 289..291 '{}': () - 303..447 '{ ...r(); }': () - 313..318 'inner': Map<|&f64| -> f64> - 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> - 330..343 '|_: &f64| 0.0': |&f64| -> f64 - 331..332 '_': &f64 - 340..343 '0.0': f64 - 356..362 'repeat': Repeat f64>> - 365..390 'Repeat...nner }': Repeat f64>> - 383..388 'inner': Map<|&f64| -> f64> - 401..404 'vec': Vec f64>>>> - 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec f64>>>> - 407..424 'from_i...epeat)': Vec f64>>>> - 417..423 'repeat': Repeat f64>> - 431..434 'vec': Vec f64>>>> - 431..444 'vec.foo_bar()': {unknown} - "#]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs deleted file mode 100644 index 59eb59d5f..000000000 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ /dev/null @@ -1,2218 +0,0 @@ -use expect::expect; - -use super::{check_infer, check_types}; - -#[test] -fn infer_box() { - check_types( - r#" -//- /main.rs crate:main deps:std -fn test() { - let x = box 1; - let t = (x, box x, box &1, box [1]); - t; -} //^ (Box, Box>, Box<&i32>, Box<[i32; _]>) - -//- /std.rs crate:std -#[prelude_import] use prelude::*; -mod prelude {} - -mod boxed { - #[lang = "owned_box"] - pub struct Box { - inner: *mut T, - } -} -"#, - ); -} - -#[test] -fn infer_adt_self() { - check_types( - r#" -enum Nat { Succ(Self), Demo(Nat), Zero } - -fn test() { - let foo: Nat = Nat::Zero; - if let Nat::Succ(x) = foo { - x - } //^ Nat -} -"#, - ); -} - -#[test] -fn self_in_struct_lit() { - check_infer( - r#" - //- /main.rs - struct S { x: T } - - impl S { - fn foo() { - Self { x: 1 }; - } - } - "#, - expect![[r#" - 49..79 '{ ... }': () - 59..72 'Self { x: 1 }': S - 69..70 '1': u32 - "#]], - ); -} - -#[test] -fn type_alias_in_struct_lit() { - check_infer( - r#" - //- /main.rs - struct S { x: T } - - type SS = S; - - fn foo() { - SS { x: 1 }; - } - "#, - expect![[r#" - 50..70 '{ ...1 }; }': () - 56..67 'SS { x: 1 }': S - 64..65 '1': u32 - "#]], - ); -} - -#[test] -fn infer_ranges() { - check_types( - r#" -//- /main.rs crate:main deps:core -fn test() { - let a = ..; - let b = 1..; - let c = ..2u32; - let d = 1..2usize; - let e = ..=10; - let f = 'a'..='z'; - - let t = (a, b, c, d, e, f); - t; -} //^ (RangeFull, RangeFrom, RangeTo, Range, RangeToInclusive, RangeInclusive) - -//- /core.rs crate:core -#[prelude_import] use prelude::*; -mod prelude {} - -pub mod ops { - pub struct Range { - pub start: Idx, - pub end: Idx, - } - pub struct RangeFrom { - pub start: Idx, - } - struct RangeFull; - pub struct RangeInclusive { - start: Idx, - end: Idx, - is_empty: u8, - } - pub struct RangeTo { - pub end: Idx, - } - pub struct RangeToInclusive { - pub end: Idx, - } -} -"#, - ); -} - -#[test] -fn infer_while_let() { - check_types( - r#" -enum Option { Some(T), None } - -fn test() { - let foo: Option = None; - while let Option::Some(x) = foo { - x - } //^ f32 -} -"#, - ); -} - -#[test] -fn infer_basics() { - check_infer( - r#" - fn test(a: u32, b: isize, c: !, d: &str) { - a; - b; - c; - d; - 1usize; - 1isize; - "test"; - 1.0f32; - }"#, - expect![[r#" - 8..9 'a': u32 - 16..17 'b': isize - 26..27 'c': ! - 32..33 'd': &str - 41..120 '{ ...f32; }': () - 47..48 'a': u32 - 54..55 'b': isize - 61..62 'c': ! - 68..69 'd': &str - 75..81 '1usize': usize - 87..93 '1isize': isize - 99..105 '"test"': &str - 111..117 '1.0f32': f32 - "#]], - ); -} - -#[test] -fn infer_let() { - check_infer( - r#" - fn test() { - let a = 1isize; - let b: usize = 1; - let c = b; - let d: u32; - let e; - let f: i32 = e; - } - "#, - expect![[r#" - 10..117 '{ ...= e; }': () - 20..21 'a': isize - 24..30 '1isize': isize - 40..41 'b': usize - 51..52 '1': usize - 62..63 'c': usize - 66..67 'b': usize - 77..78 'd': u32 - 93..94 'e': i32 - 104..105 'f': i32 - 113..114 'e': i32 - "#]], - ); -} - -#[test] -fn infer_paths() { - check_infer( - r#" - fn a() -> u32 { 1 } - - mod b { - fn c() -> u32 { 1 } - } - - fn test() { - a(); - b::c(); - } - "#, - expect![[r#" - 14..19 '{ 1 }': u32 - 16..17 '1': u32 - 47..52 '{ 1 }': u32 - 49..50 '1': u32 - 66..90 '{ ...c(); }': () - 72..73 'a': fn a() -> u32 - 72..75 'a()': u32 - 81..85 'b::c': fn c() -> u32 - 81..87 'b::c()': u32 - "#]], - ); -} - -#[test] -fn infer_path_type() { - check_infer( - r#" - struct S; - - impl S { - fn foo() -> i32 { 1 } - } - - fn test() { - S::foo(); - ::foo(); - } - "#, - expect![[r#" - 40..45 '{ 1 }': i32 - 42..43 '1': i32 - 59..92 '{ ...o(); }': () - 65..71 'S::foo': fn foo() -> i32 - 65..73 'S::foo()': i32 - 79..87 '::foo': fn foo() -> i32 - 79..89 '::foo()': i32 - "#]], - ); -} - -#[test] -fn infer_struct() { - check_infer( - r#" - struct A { - b: B, - c: C, - } - struct B; - struct C(usize); - - fn test() { - let c = C(1); - B; - let a: A = A { b: B, c: C(1) }; - a.b; - a.c; - } - "#, - expect![[r#" - 71..153 '{ ...a.c; }': () - 81..82 'c': C - 85..86 'C': C(usize) -> C - 85..89 'C(1)': C - 87..88 '1': usize - 95..96 'B': B - 106..107 'a': A - 113..132 'A { b:...C(1) }': A - 120..121 'B': B - 126..127 'C': C(usize) -> C - 126..130 'C(1)': C - 128..129 '1': usize - 138..139 'a': A - 138..141 'a.b': B - 147..148 'a': A - 147..150 'a.c': C - "#]], - ); -} - -#[test] -fn infer_enum() { - check_infer( - r#" - enum E { - V1 { field: u32 }, - V2 - } - fn test() { - E::V1 { field: 1 }; - E::V2; - }"#, - expect![[r#" - 51..89 '{ ...:V2; }': () - 57..75 'E::V1 ...d: 1 }': E - 72..73 '1': u32 - 81..86 'E::V2': E - "#]], - ); -} - -#[test] -fn infer_union() { - check_infer( - r#" - union MyUnion { - foo: u32, - bar: f32, - } - - fn test() { - let u = MyUnion { foo: 0 }; - unsafe { baz(u); } - let u = MyUnion { bar: 0.0 }; - unsafe { baz(u); } - } - - unsafe fn baz(u: MyUnion) { - let inner = u.foo; - let inner = u.bar; - } - "#, - expect![[r#" - 57..172 '{ ...); } }': () - 67..68 'u': MyUnion - 71..89 'MyUnio...o: 0 }': MyUnion - 86..87 '0': u32 - 95..113 'unsafe...(u); }': () - 102..113 '{ baz(u); }': () - 104..107 'baz': fn baz(MyUnion) - 104..110 'baz(u)': () - 108..109 'u': MyUnion - 122..123 'u': MyUnion - 126..146 'MyUnio... 0.0 }': MyUnion - 141..144 '0.0': f32 - 152..170 'unsafe...(u); }': () - 159..170 '{ baz(u); }': () - 161..164 'baz': fn baz(MyUnion) - 161..167 'baz(u)': () - 165..166 'u': MyUnion - 188..189 'u': MyUnion - 200..249 '{ ...bar; }': () - 210..215 'inner': u32 - 218..219 'u': MyUnion - 218..223 'u.foo': u32 - 233..238 'inner': f32 - 241..242 'u': MyUnion - 241..246 'u.bar': f32 - "#]], - ); -} - -#[test] -fn infer_refs() { - check_infer( - r#" - fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { - a; - *a; - &a; - &mut a; - b; - *b; - &b; - c; - *c; - d; - *d; - } - "#, - expect![[r#" - 8..9 'a': &u32 - 17..18 'b': &mut u32 - 30..31 'c': *const u32 - 45..46 'd': *mut u32 - 58..149 '{ ... *d; }': () - 64..65 'a': &u32 - 71..73 '*a': u32 - 72..73 'a': &u32 - 79..81 '&a': &&u32 - 80..81 'a': &u32 - 87..93 '&mut a': &mut &u32 - 92..93 'a': &u32 - 99..100 'b': &mut u32 - 106..108 '*b': u32 - 107..108 'b': &mut u32 - 114..116 '&b': &&mut u32 - 115..116 'b': &mut u32 - 122..123 'c': *const u32 - 129..131 '*c': u32 - 130..131 'c': *const u32 - 137..138 'd': *mut u32 - 144..146 '*d': u32 - 145..146 'd': *mut u32 - "#]], - ); -} - -#[test] -fn infer_raw_ref() { - check_infer( - r#" - fn test(a: i32) { - &raw mut a; - &raw const a; - } - "#, - expect![[r#" - 8..9 'a': i32 - 16..53 '{ ...t a; }': () - 22..32 '&raw mut a': *mut i32 - 31..32 'a': i32 - 38..50 '&raw const a': *const i32 - 49..50 'a': i32 - "#]], - ); -} - -#[test] -fn infer_literals() { - check_infer( - r##" - fn test() { - 5i32; - 5f32; - 5f64; - "hello"; - b"bytes"; - 'c'; - b'b'; - 3.14; - 5000; - false; - true; - r#" - //! doc - // non-doc - mod foo {} - "#; - br#"yolo"#; - } - "##, - expect![[r##" - 10..216 '{ ...o"#; }': () - 16..20 '5i32': i32 - 26..30 '5f32': f32 - 36..40 '5f64': f64 - 46..53 '"hello"': &str - 59..67 'b"bytes"': &[u8; _] - 73..76 ''c'': char - 82..86 'b'b'': u8 - 92..96 '3.14': f64 - 102..106 '5000': i32 - 112..117 'false': bool - 123..127 'true': bool - 133..197 'r#" ... "#': &str - 203..213 'br#"yolo"#': &[u8; _] - "##]], - ); -} - -#[test] -fn infer_unary_op() { - check_infer( - r#" - enum SomeType {} - - fn test(x: SomeType) { - let b = false; - let c = !b; - let a = 100; - let d: i128 = -a; - let e = -100; - let f = !!!true; - let g = !42; - let h = !10u32; - let j = !a; - -3.14; - !3; - -x; - !x; - -"hello"; - !"hello"; - } - "#, - expect![[r#" - 26..27 'x': SomeType - 39..271 '{ ...lo"; }': () - 49..50 'b': bool - 53..58 'false': bool - 68..69 'c': bool - 72..74 '!b': bool - 73..74 'b': bool - 84..85 'a': i128 - 88..91 '100': i128 - 101..102 'd': i128 - 111..113 '-a': i128 - 112..113 'a': i128 - 123..124 'e': i32 - 127..131 '-100': i32 - 128..131 '100': i32 - 141..142 'f': bool - 145..152 '!!!true': bool - 146..152 '!!true': bool - 147..152 '!true': bool - 148..152 'true': bool - 162..163 'g': i32 - 166..169 '!42': i32 - 167..169 '42': i32 - 179..180 'h': u32 - 183..189 '!10u32': u32 - 184..189 '10u32': u32 - 199..200 'j': i128 - 203..205 '!a': i128 - 204..205 'a': i128 - 211..216 '-3.14': f64 - 212..216 '3.14': f64 - 222..224 '!3': i32 - 223..224 '3': i32 - 230..232 '-x': {unknown} - 231..232 'x': SomeType - 238..240 '!x': {unknown} - 239..240 'x': SomeType - 246..254 '-"hello"': {unknown} - 247..254 '"hello"': &str - 260..268 '!"hello"': {unknown} - 261..268 '"hello"': &str - "#]], - ); -} - -#[test] -fn infer_backwards() { - check_infer( - r#" - fn takes_u32(x: u32) {} - - struct S { i32_field: i32 } - - fn test() -> &mut &f64 { - let a = unknown_function(); - takes_u32(a); - let b = unknown_function(); - S { i32_field: b }; - let c = unknown_function(); - &mut &c - } - "#, - expect![[r#" - 13..14 'x': u32 - 21..23 '{}': () - 77..230 '{ ...t &c }': &mut &f64 - 87..88 'a': u32 - 91..107 'unknow...nction': {unknown} - 91..109 'unknow...tion()': u32 - 115..124 'takes_u32': fn takes_u32(u32) - 115..127 'takes_u32(a)': () - 125..126 'a': u32 - 137..138 'b': i32 - 141..157 'unknow...nction': {unknown} - 141..159 'unknow...tion()': i32 - 165..183 'S { i3...d: b }': S - 180..181 'b': i32 - 193..194 'c': f64 - 197..213 'unknow...nction': {unknown} - 197..215 'unknow...tion()': f64 - 221..228 '&mut &c': &mut &f64 - 226..228 '&c': &f64 - 227..228 'c': f64 - "#]], - ); -} - -#[test] -fn infer_self() { - check_infer( - r#" - struct S; - - impl S { - fn test(&self) { - self; - } - fn test2(self: &Self) { - self; - } - fn test3() -> Self { - S {} - } - fn test4() -> Self { - Self {} - } - } - "#, - expect![[r#" - 33..37 'self': &S - 39..60 '{ ... }': () - 49..53 'self': &S - 74..78 'self': &S - 87..108 '{ ... }': () - 97..101 'self': &S - 132..152 '{ ... }': S - 142..146 'S {}': S - 176..199 '{ ... }': S - 186..193 'Self {}': S - "#]], - ); -} - -#[test] -fn infer_self_as_path() { - check_infer( - r#" - struct S1; - struct S2(isize); - enum E { - V1, - V2(u32), - } - - impl S1 { - fn test() { - Self; - } - } - impl S2 { - fn test() { - Self(1); - } - } - impl E { - fn test() { - Self::V1; - Self::V2(1); - } - } - "#, - expect![[r#" - 86..107 '{ ... }': () - 96..100 'Self': S1 - 134..158 '{ ... }': () - 144..148 'Self': S2(isize) -> S2 - 144..151 'Self(1)': S2 - 149..150 '1': isize - 184..230 '{ ... }': () - 194..202 'Self::V1': E - 212..220 'Self::V2': V2(u32) -> E - 212..223 'Self::V2(1)': E - 221..222 '1': u32 - "#]], - ); -} - -#[test] -fn infer_binary_op() { - check_infer( - r#" - fn f(x: bool) -> i32 { - 0i32 - } - - fn test() -> bool { - let x = a && b; - let y = true || false; - let z = x == y; - let t = x != y; - let minus_forty: isize = -40isize; - let h = minus_forty <= CONST_2; - let c = f(z || y) + 5; - let d = b; - let g = minus_forty ^= i; - let ten: usize = 10; - let ten_is_eleven = ten == some_num; - - ten < 3 - } - "#, - expect![[r#" - 5..6 'x': bool - 21..33 '{ 0i32 }': i32 - 27..31 '0i32': i32 - 53..369 '{ ... < 3 }': bool - 63..64 'x': bool - 67..68 'a': bool - 67..73 'a && b': bool - 72..73 'b': bool - 83..84 'y': bool - 87..91 'true': bool - 87..100 'true || false': bool - 95..100 'false': bool - 110..111 'z': bool - 114..115 'x': bool - 114..120 'x == y': bool - 119..120 'y': bool - 130..131 't': bool - 134..135 'x': bool - 134..140 'x != y': bool - 139..140 'y': bool - 150..161 'minus_forty': isize - 171..179 '-40isize': isize - 172..179 '40isize': isize - 189..190 'h': bool - 193..204 'minus_forty': isize - 193..215 'minus_...ONST_2': bool - 208..215 'CONST_2': isize - 225..226 'c': i32 - 229..230 'f': fn f(bool) -> i32 - 229..238 'f(z || y)': i32 - 229..242 'f(z || y) + 5': i32 - 231..232 'z': bool - 231..237 'z || y': bool - 236..237 'y': bool - 241..242 '5': i32 - 252..253 'd': {unknown} - 256..257 'b': {unknown} - 267..268 'g': () - 271..282 'minus_forty': isize - 271..287 'minus_...y ^= i': () - 286..287 'i': isize - 297..300 'ten': usize - 310..312 '10': usize - 322..335 'ten_is_eleven': bool - 338..341 'ten': usize - 338..353 'ten == some_num': bool - 345..353 'some_num': usize - 360..363 'ten': usize - 360..367 'ten < 3': bool - 366..367 '3': usize - "#]], - ); -} - -#[test] -fn infer_shift_op() { - check_infer( - r#" - fn test() { - 1u32 << 5u8; - 1u32 >> 5u8; - } - "#, - expect![[r#" - 10..47 '{ ...5u8; }': () - 16..20 '1u32': u32 - 16..27 '1u32 << 5u8': u32 - 24..27 '5u8': u8 - 33..37 '1u32': u32 - 33..44 '1u32 >> 5u8': u32 - 41..44 '5u8': u8 - "#]], - ); -} - -#[test] -fn infer_field_autoderef() { - check_infer( - r#" - struct A { - b: B, - } - struct B; - - fn test1(a: A) { - let a1 = a; - a1.b; - let a2 = &a; - a2.b; - let a3 = &mut a; - a3.b; - let a4 = &&&&&&&a; - a4.b; - let a5 = &mut &&mut &&mut a; - a5.b; - } - - fn test2(a1: *const A, a2: *mut A) { - a1.b; - a2.b; - } - "#, - expect![[r#" - 43..44 'a': A - 49..212 '{ ...5.b; }': () - 59..61 'a1': A - 64..65 'a': A - 71..73 'a1': A - 71..75 'a1.b': B - 85..87 'a2': &A - 90..92 '&a': &A - 91..92 'a': A - 98..100 'a2': &A - 98..102 'a2.b': B - 112..114 'a3': &mut A - 117..123 '&mut a': &mut A - 122..123 'a': A - 129..131 'a3': &mut A - 129..133 'a3.b': B - 143..145 'a4': &&&&&&&A - 148..156 '&&&&&&&a': &&&&&&&A - 149..156 '&&&&&&a': &&&&&&A - 150..156 '&&&&&a': &&&&&A - 151..156 '&&&&a': &&&&A - 152..156 '&&&a': &&&A - 153..156 '&&a': &&A - 154..156 '&a': &A - 155..156 'a': A - 162..164 'a4': &&&&&&&A - 162..166 'a4.b': B - 176..178 'a5': &mut &&mut &&mut A - 181..199 '&mut &...&mut a': &mut &&mut &&mut A - 186..199 '&&mut &&mut a': &&mut &&mut A - 187..199 '&mut &&mut a': &mut &&mut A - 192..199 '&&mut a': &&mut A - 193..199 '&mut a': &mut A - 198..199 'a': A - 205..207 'a5': &mut &&mut &&mut A - 205..209 'a5.b': B - 223..225 'a1': *const A - 237..239 'a2': *mut A - 249..272 '{ ...2.b; }': () - 255..257 'a1': *const A - 255..259 'a1.b': B - 265..267 'a2': *mut A - 265..269 'a2.b': B - "#]], - ); -} - -#[test] -fn infer_argument_autoderef() { - check_infer( - r#" - #[lang = "deref"] - pub trait Deref { - type Target; - fn deref(&self) -> &Self::Target; - } - - struct A(T); - - impl A { - fn foo(&self) -> &T { - &self.0 - } - } - - struct B(T); - - impl Deref for B { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - fn test() { - let t = A::foo(&&B(B(A(42)))); - } - "#, - expect![[r#" - 67..71 'self': &Self - 138..142 'self': &A - 150..173 '{ ... }': &T - 160..167 '&self.0': &T - 161..165 'self': &A - 161..167 'self.0': T - 254..258 'self': &B - 277..300 '{ ... }': &T - 287..294 '&self.0': &T - 288..292 'self': &B - 288..294 'self.0': T - 314..352 '{ ...))); }': () - 324..325 't': &i32 - 328..334 'A::foo': fn foo(&A) -> &i32 - 328..349 'A::foo...42))))': &i32 - 335..348 '&&B(B(A(42)))': &&B>> - 336..348 '&B(B(A(42)))': &B>> - 337..338 'B': B>>(B>) -> B>> - 337..348 'B(B(A(42)))': B>> - 339..340 'B': B>(A) -> B> - 339..347 'B(A(42))': B> - 341..342 'A': A(i32) -> A - 341..346 'A(42)': A - 343..345 '42': i32 - "#]], - ); -} - -#[test] -fn infer_method_argument_autoderef() { - check_infer( - r#" - #[lang = "deref"] - pub trait Deref { - type Target; - fn deref(&self) -> &Self::Target; - } - - struct A(*mut T); - - impl A { - fn foo(&self, x: &A) -> &T { - &*x.0 - } - } - - struct B(T); - - impl Deref for B { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - fn test(a: A) { - let t = A(0 as *mut _).foo(&&B(B(a))); - } - "#, - expect![[r#" - 67..71 'self': &Self - 143..147 'self': &A - 149..150 'x': &A - 165..186 '{ ... }': &T - 175..180 '&*x.0': &T - 176..180 '*x.0': T - 177..178 'x': &A - 177..180 'x.0': *mut T - 267..271 'self': &B - 290..313 '{ ... }': &T - 300..307 '&self.0': &T - 301..305 'self': &B - 301..307 'self.0': T - 325..326 'a': A - 336..382 '{ ...))); }': () - 346..347 't': &i32 - 350..351 'A': A(*mut i32) -> A - 350..364 'A(0 as *mut _)': A - 350..379 'A(0 as...B(a)))': &i32 - 352..353 '0': i32 - 352..363 '0 as *mut _': *mut i32 - 369..378 '&&B(B(a))': &&B>> - 370..378 '&B(B(a))': &B>> - 371..372 'B': B>>(B>) -> B>> - 371..378 'B(B(a))': B>> - 373..374 'B': B>(A) -> B> - 373..377 'B(a)': B> - 375..376 'a': A - "#]], - ); -} - -#[test] -fn infer_in_elseif() { - check_infer( - r#" - struct Foo { field: i32 } - fn main(foo: Foo) { - if true { - - } else if false { - foo.field - } - } - "#, - expect![[r#" - 34..37 'foo': Foo - 44..108 '{ ... } }': () - 50..106 'if tru... }': () - 53..57 'true': bool - 58..66 '{ }': () - 72..106 'if fal... }': i32 - 75..80 'false': bool - 81..106 '{ ... }': i32 - 91..94 'foo': Foo - 91..100 'foo.field': i32 - "#]], - ) -} - -#[test] -fn infer_if_match_with_return() { - check_infer( - r#" - fn foo() { - let _x1 = if true { - 1 - } else { - return; - }; - let _x2 = if true { - 2 - } else { - return - }; - let _x3 = match true { - true => 3, - _ => { - return; - } - }; - let _x4 = match true { - true => 4, - _ => return - }; - }"#, - expect![[r#" - 9..322 '{ ... }; }': () - 19..22 '_x1': i32 - 25..79 'if tru... }': i32 - 28..32 'true': bool - 33..50 '{ ... }': i32 - 43..44 '1': i32 - 56..79 '{ ... }': i32 - 66..72 'return': ! - 89..92 '_x2': i32 - 95..148 'if tru... }': i32 - 98..102 'true': bool - 103..120 '{ ... }': i32 - 113..114 '2': i32 - 126..148 '{ ... }': ! - 136..142 'return': ! - 158..161 '_x3': i32 - 164..246 'match ... }': i32 - 170..174 'true': bool - 185..189 'true': bool - 185..189 'true': bool - 193..194 '3': i32 - 204..205 '_': bool - 209..240 '{ ... }': i32 - 223..229 'return': ! - 256..259 '_x4': i32 - 262..319 'match ... }': i32 - 268..272 'true': bool - 283..287 'true': bool - 283..287 'true': bool - 291..292 '4': i32 - 302..303 '_': bool - 307..313 'return': ! - "#]], - ) -} - -#[test] -fn infer_inherent_method() { - check_infer( - r#" - struct A; - - impl A { - fn foo(self, x: u32) -> i32 {} - } - - mod b { - impl super::A { - fn bar(&self, x: u64) -> i64 {} - } - } - - fn test(a: A) { - a.foo(1); - (&a).bar(1); - a.bar(1); - } - "#, - expect![[r#" - 31..35 'self': A - 37..38 'x': u32 - 52..54 '{}': () - 102..106 'self': &A - 108..109 'x': u64 - 123..125 '{}': () - 143..144 'a': A - 149..197 '{ ...(1); }': () - 155..156 'a': A - 155..163 'a.foo(1)': i32 - 161..162 '1': u32 - 169..180 '(&a).bar(1)': i64 - 170..172 '&a': &A - 171..172 'a': A - 178..179 '1': u64 - 186..187 'a': A - 186..194 'a.bar(1)': i64 - 192..193 '1': u64 - "#]], - ); -} - -#[test] -fn infer_inherent_method_str() { - check_infer( - r#" - #[lang = "str"] - impl str { - fn foo(&self) -> i32 {} - } - - fn test() { - "foo".foo(); - } - "#, - expect![[r#" - 39..43 'self': &str - 52..54 '{}': () - 68..88 '{ ...o(); }': () - 74..79 '"foo"': &str - 74..85 '"foo".foo()': i32 - "#]], - ); -} - -#[test] -fn infer_tuple() { - check_infer( - r#" - fn test(x: &str, y: isize) { - let a: (u32, &str) = (1, "a"); - let b = (a, x); - let c = (y, x); - let d = (c, x); - let e = (1, "e"); - let f = (e, "d"); - } - "#, - expect![[r#" - 8..9 'x': &str - 17..18 'y': isize - 27..169 '{ ...d"); }': () - 37..38 'a': (u32, &str) - 54..62 '(1, "a")': (u32, &str) - 55..56 '1': u32 - 58..61 '"a"': &str - 72..73 'b': ((u32, &str), &str) - 76..82 '(a, x)': ((u32, &str), &str) - 77..78 'a': (u32, &str) - 80..81 'x': &str - 92..93 'c': (isize, &str) - 96..102 '(y, x)': (isize, &str) - 97..98 'y': isize - 100..101 'x': &str - 112..113 'd': ((isize, &str), &str) - 116..122 '(c, x)': ((isize, &str), &str) - 117..118 'c': (isize, &str) - 120..121 'x': &str - 132..133 'e': (i32, &str) - 136..144 '(1, "e")': (i32, &str) - 137..138 '1': i32 - 140..143 '"e"': &str - 154..155 'f': ((i32, &str), &str) - 158..166 '(e, "d")': ((i32, &str), &str) - 159..160 'e': (i32, &str) - 162..165 '"d"': &str - "#]], - ); -} - -#[test] -fn infer_array() { - check_infer( - r#" - fn test(x: &str, y: isize) { - let a = [x]; - let b = [a, a]; - let c = [b, b]; - - let d = [y, 1, 2, 3]; - let d = [1, y, 2, 3]; - let e = [y]; - let f = [d, d]; - let g = [e, e]; - - let h = [1, 2]; - let i = ["a", "b"]; - - let b = [a, ["b"]]; - let x: [u8; 0] = []; - } - "#, - expect![[r#" - 8..9 'x': &str - 17..18 'y': isize - 27..292 '{ ... []; }': () - 37..38 'a': [&str; _] - 41..44 '[x]': [&str; _] - 42..43 'x': &str - 54..55 'b': [[&str; _]; _] - 58..64 '[a, a]': [[&str; _]; _] - 59..60 'a': [&str; _] - 62..63 'a': [&str; _] - 74..75 'c': [[[&str; _]; _]; _] - 78..84 '[b, b]': [[[&str; _]; _]; _] - 79..80 'b': [[&str; _]; _] - 82..83 'b': [[&str; _]; _] - 95..96 'd': [isize; _] - 99..111 '[y, 1, 2, 3]': [isize; _] - 100..101 'y': isize - 103..104 '1': isize - 106..107 '2': isize - 109..110 '3': isize - 121..122 'd': [isize; _] - 125..137 '[1, y, 2, 3]': [isize; _] - 126..127 '1': isize - 129..130 'y': isize - 132..133 '2': isize - 135..136 '3': isize - 147..148 'e': [isize; _] - 151..154 '[y]': [isize; _] - 152..153 'y': isize - 164..165 'f': [[isize; _]; _] - 168..174 '[d, d]': [[isize; _]; _] - 169..170 'd': [isize; _] - 172..173 'd': [isize; _] - 184..185 'g': [[isize; _]; _] - 188..194 '[e, e]': [[isize; _]; _] - 189..190 'e': [isize; _] - 192..193 'e': [isize; _] - 205..206 'h': [i32; _] - 209..215 '[1, 2]': [i32; _] - 210..211 '1': i32 - 213..214 '2': i32 - 225..226 'i': [&str; _] - 229..239 '["a", "b"]': [&str; _] - 230..233 '"a"': &str - 235..238 '"b"': &str - 250..251 'b': [[&str; _]; _] - 254..264 '[a, ["b"]]': [[&str; _]; _] - 255..256 'a': [&str; _] - 258..263 '["b"]': [&str; _] - 259..262 '"b"': &str - 274..275 'x': [u8; _] - 287..289 '[]': [u8; _] - "#]], - ); -} - -#[test] -fn infer_struct_generics() { - check_infer( - r#" - struct A { - x: T, - } - - fn test(a1: A, i: i32) { - a1.x; - let a2 = A { x: i }; - a2.x; - let a3 = A:: { x: 1 }; - a3.x; - } - "#, - expect![[r#" - 35..37 'a1': A - 47..48 'i': i32 - 55..146 '{ ...3.x; }': () - 61..63 'a1': A - 61..65 'a1.x': u32 - 75..77 'a2': A - 80..90 'A { x: i }': A - 87..88 'i': i32 - 96..98 'a2': A - 96..100 'a2.x': i32 - 110..112 'a3': A - 115..133 'A:: - 130..131 '1': i128 - 139..141 'a3': A - 139..143 'a3.x': i128 - "#]], - ); -} - -#[test] -fn infer_tuple_struct_generics() { - check_infer( - r#" - struct A(T); - enum Option { Some(T), None } - use Option::*; - - fn test() { - A(42); - A(42u128); - Some("x"); - Option::Some("x"); - None; - let x: Option = None; - } - "#, - expect![[r#" - 75..183 '{ ...one; }': () - 81..82 'A': A(i32) -> A - 81..86 'A(42)': A - 83..85 '42': i32 - 92..93 'A': A(u128) -> A - 92..101 'A(42u128)': A - 94..100 '42u128': u128 - 107..111 'Some': Some<&str>(&str) -> Option<&str> - 107..116 'Some("x")': Option<&str> - 112..115 '"x"': &str - 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> - 122..139 'Option...e("x")': Option<&str> - 135..138 '"x"': &str - 145..149 'None': Option<{unknown}> - 159..160 'x': Option - 176..180 'None': Option - "#]], - ); -} - -#[test] -fn infer_function_generics() { - check_infer( - r#" - fn id(t: T) -> T { t } - - fn test() { - id(1u32); - id::(1); - let x: u64 = id(1); - } - "#, - expect![[r#" - 9..10 't': T - 20..25 '{ t }': T - 22..23 't': T - 37..97 '{ ...(1); }': () - 43..45 'id': fn id(u32) -> u32 - 43..51 'id(1u32)': u32 - 46..50 '1u32': u32 - 57..67 'id::': fn id(i128) -> i128 - 57..70 'id::(1)': i128 - 68..69 '1': i128 - 80..81 'x': u64 - 89..91 'id': fn id(u64) -> u64 - 89..94 'id(1)': u64 - 92..93 '1': u64 - "#]], - ); -} - -#[test] -fn infer_impl_generics_basic() { - check_infer( - r#" - struct A { - x: T1, - y: T2, - } - impl A { - fn x(self) -> X { - self.x - } - fn y(self) -> Y { - self.y - } - fn z(self, t: T) -> (X, Y, T) { - (self.x, self.y, t) - } - } - - fn test() -> i128 { - let a = A { x: 1u64, y: 1i64 }; - a.x(); - a.y(); - a.z(1i128); - a.z::(1); - } - "#, - expect![[r#" - 73..77 'self': A - 84..106 '{ ... }': X - 94..98 'self': A - 94..100 'self.x': X - 116..120 'self': A - 127..149 '{ ... }': Y - 137..141 'self': A - 137..143 'self.y': Y - 162..166 'self': A - 168..169 't': T - 187..222 '{ ... }': (X, Y, T) - 197..216 '(self.....y, t)': (X, Y, T) - 198..202 'self': A - 198..204 'self.x': X - 206..210 'self': A - 206..212 'self.y': Y - 214..215 't': T - 244..341 '{ ...(1); }': () - 254..255 'a': A - 258..280 'A { x:...1i64 }': A - 265..269 '1u64': u64 - 274..278 '1i64': i64 - 286..287 'a': A - 286..291 'a.x()': u64 - 297..298 'a': A - 297..302 'a.y()': i64 - 308..309 'a': A - 308..318 'a.z(1i128)': (u64, i64, i128) - 312..317 '1i128': i128 - 324..325 'a': A - 324..338 'a.z::(1)': (u64, i64, u128) - 336..337 '1': u128 - "#]], - ); -} - -#[test] -fn infer_impl_generics_with_autoderef() { - check_infer( - r#" - enum Option { - Some(T), - None, - } - impl Option { - fn as_ref(&self) -> Option<&T> {} - } - fn test(o: Option) { - (&o).as_ref(); - o.as_ref(); - } - "#, - expect![[r#" - 77..81 'self': &Option - 97..99 '{}': () - 110..111 'o': Option - 126..164 '{ ...f(); }': () - 132..145 '(&o).as_ref()': Option<&u32> - 133..135 '&o': &Option - 134..135 'o': Option - 151..152 'o': Option - 151..161 'o.as_ref()': Option<&u32> - "#]], - ); -} - -#[test] -fn infer_generic_chain() { - check_infer( - r#" - struct A { - x: T, - } - impl A { - fn x(self) -> T2 { - self.x - } - } - fn id(t: T) -> T { t } - - fn test() -> i128 { - let x = 1; - let y = id(x); - let a = A { x: id(y) }; - let z = id(a.x); - let b = A { x: z }; - b.x() - } - "#, - expect![[r#" - 52..56 'self': A - 64..86 '{ ... }': T2 - 74..78 'self': A - 74..80 'self.x': T2 - 98..99 't': T - 109..114 '{ t }': T - 111..112 't': T - 134..254 '{ ....x() }': i128 - 144..145 'x': i128 - 148..149 '1': i128 - 159..160 'y': i128 - 163..165 'id': fn id(i128) -> i128 - 163..168 'id(x)': i128 - 166..167 'x': i128 - 178..179 'a': A - 182..196 'A { x: id(y) }': A - 189..191 'id': fn id(i128) -> i128 - 189..194 'id(y)': i128 - 192..193 'y': i128 - 206..207 'z': i128 - 210..212 'id': fn id(i128) -> i128 - 210..217 'id(a.x)': i128 - 213..214 'a': A - 213..216 'a.x': i128 - 227..228 'b': A - 231..241 'A { x: z }': A - 238..239 'z': i128 - 247..248 'b': A - 247..252 'b.x()': i128 - "#]], - ); -} - -#[test] -fn infer_associated_const() { - check_infer( - r#" - struct Struct; - - impl Struct { - const FOO: u32 = 1; - } - - enum Enum {} - - impl Enum { - const BAR: u32 = 2; - } - - trait Trait { - const ID: u32; - } - - struct TraitTest; - - impl Trait for TraitTest { - const ID: u32 = 5; - } - - fn test() { - let x = Struct::FOO; - let y = Enum::BAR; - let z = TraitTest::ID; - } - "#, - expect![[r#" - 51..52 '1': u32 - 104..105 '2': u32 - 212..213 '5': u32 - 228..306 '{ ...:ID; }': () - 238..239 'x': u32 - 242..253 'Struct::FOO': u32 - 263..264 'y': u32 - 267..276 'Enum::BAR': u32 - 286..287 'z': u32 - 290..303 'TraitTest::ID': u32 - "#]], - ); -} - -#[test] -fn infer_type_alias() { - check_infer( - r#" - struct A { x: X, y: Y } - type Foo = A; - type Bar = A; - type Baz = A; - fn test(x: Foo, y: Bar<&str>, z: Baz) { - x.x; - x.y; - y.x; - y.y; - z.x; - z.y; - } - "#, - expect![[r#" - 115..116 'x': A - 123..124 'y': A<&str, u128> - 137..138 'z': A - 153..210 '{ ...z.y; }': () - 159..160 'x': A - 159..162 'x.x': u32 - 168..169 'x': A - 168..171 'x.y': i128 - 177..178 'y': A<&str, u128> - 177..180 'y.x': &str - 186..187 'y': A<&str, u128> - 186..189 'y.y': u128 - 195..196 'z': A - 195..198 'z.x': u8 - 204..205 'z': A - 204..207 'z.y': i8 - "#]], - ) -} - -#[test] -fn recursive_type_alias() { - check_infer( - r#" - struct A {} - type Foo = Foo; - type Bar = A; - fn test(x: Foo) {} - "#, - expect![[r#" - 58..59 'x': {unknown} - 66..68 '{}': () - "#]], - ) -} - -#[test] -fn infer_type_param() { - check_infer( - r#" - fn id(x: T) -> T { - x - } - - fn clone(x: &T) -> T { - *x - } - - fn test() { - let y = 10u32; - id(y); - let x: bool = clone(z); - id::(1); - } - "#, - expect![[r#" - 9..10 'x': T - 20..29 '{ x }': T - 26..27 'x': T - 43..44 'x': &T - 55..65 '{ *x }': T - 61..63 '*x': T - 62..63 'x': &T - 77..157 '{ ...(1); }': () - 87..88 'y': u32 - 91..96 '10u32': u32 - 102..104 'id': fn id(u32) -> u32 - 102..107 'id(y)': u32 - 105..106 'y': u32 - 117..118 'x': bool - 127..132 'clone': fn clone(&bool) -> bool - 127..135 'clone(z)': bool - 133..134 'z': &bool - 141..151 'id::': fn id(i128) -> i128 - 141..154 'id::(1)': i128 - 152..153 '1': i128 - "#]], - ); -} - -#[test] -fn infer_const() { - check_infer( - r#" - struct Foo; - impl Foo { const ASSOC_CONST: u32 = 0; } - const GLOBAL_CONST: u32 = 101; - fn test() { - const LOCAL_CONST: u32 = 99; - let x = LOCAL_CONST; - let z = GLOBAL_CONST; - let id = Foo::ASSOC_CONST; - } - "#, - expect![[r#" - 48..49 '0': u32 - 79..82 '101': u32 - 94..212 '{ ...NST; }': () - 137..138 'x': u32 - 141..152 'LOCAL_CONST': u32 - 162..163 'z': u32 - 166..178 'GLOBAL_CONST': u32 - 188..190 'id': u32 - 193..209 'Foo::A..._CONST': u32 - 125..127 '99': u32 - "#]], - ); -} - -#[test] -fn infer_static() { - check_infer( - r#" - static GLOBAL_STATIC: u32 = 101; - static mut GLOBAL_STATIC_MUT: u32 = 101; - fn test() { - static LOCAL_STATIC: u32 = 99; - static mut LOCAL_STATIC_MUT: u32 = 99; - let x = LOCAL_STATIC; - let y = LOCAL_STATIC_MUT; - let z = GLOBAL_STATIC; - let w = GLOBAL_STATIC_MUT; - } - "#, - expect![[r#" - 28..31 '101': u32 - 69..72 '101': u32 - 84..279 '{ ...MUT; }': () - 172..173 'x': u32 - 176..188 'LOCAL_STATIC': u32 - 198..199 'y': u32 - 202..218 'LOCAL_...IC_MUT': u32 - 228..229 'z': u32 - 232..245 'GLOBAL_STATIC': u32 - 255..256 'w': u32 - 259..276 'GLOBAL...IC_MUT': u32 - 117..119 '99': u32 - 160..162 '99': u32 - "#]], - ); -} - -#[test] -fn shadowing_primitive() { - check_types( - r#" -struct i32; -struct Foo; - -impl i32 { fn foo(&self) -> Foo { Foo } } - -fn main() { - let x: i32 = i32; - x.foo(); - //^ Foo -}"#, - ); -} - -#[test] -fn not_shadowing_primitive_by_module() { - check_types( - r#" -//- /str.rs -fn foo() {} - -//- /main.rs -mod str; -fn foo() -> &'static str { "" } - -fn main() { - foo(); - //^ &str -}"#, - ); -} - -#[test] -fn not_shadowing_module_by_primitive() { - check_types( - r#" -//- /str.rs -fn foo() -> u32 {0} - -//- /main.rs -mod str; -fn foo() -> &'static str { "" } - -fn main() { - str::foo(); - //^ u32 -}"#, - ); -} - -// This test is actually testing the shadowing behavior within hir_def. It -// lives here because the testing infrastructure in hir_def isn't currently -// capable of asserting the necessary conditions. -#[test] -fn should_be_shadowing_imports() { - check_types( - r#" -mod a { - pub fn foo() -> i8 {0} - pub struct foo { a: i8 } -} -mod b { pub fn foo () -> u8 {0} } -mod c { pub struct foo { a: u8 } } -mod d { - pub use super::a::*; - pub use super::c::foo; - pub use super::b::foo; -} - -fn main() { - d::foo(); - //^ u8 - d::foo{a:0}; - //^ u8 -}"#, - ); -} - -#[test] -fn closure_return() { - check_infer( - r#" - fn foo() -> u32 { - let x = || -> usize { return 1; }; - } - "#, - expect![[r#" - 16..58 '{ ...; }; }': () - 26..27 'x': || -> usize - 30..55 '|| -> ...n 1; }': || -> usize - 42..55 '{ return 1; }': usize - 44..52 'return 1': ! - 51..52 '1': usize - "#]], - ); -} - -#[test] -fn closure_return_unit() { - check_infer( - r#" - fn foo() -> u32 { - let x = || { return; }; - } - "#, - expect![[r#" - 16..47 '{ ...; }; }': () - 26..27 'x': || -> () - 30..44 '|| { return; }': || -> () - 33..44 '{ return; }': () - 35..41 'return': ! - "#]], - ); -} - -#[test] -fn closure_return_inferred() { - check_infer( - r#" - fn foo() -> u32 { - let x = || { "test" }; - } - "#, - expect![[r#" - 16..46 '{ ..." }; }': () - 26..27 'x': || -> &str - 30..43 '|| { "test" }': || -> &str - 33..43 '{ "test" }': &str - 35..41 '"test"': &str - "#]], - ); -} - -#[test] -fn fn_pointer_return() { - check_infer( - r#" - struct Vtable { - method: fn(), - } - - fn main() { - let vtable = Vtable { method: || {} }; - let m = vtable.method; - } - "#, - expect![[r#" - 47..120 '{ ...hod; }': () - 57..63 'vtable': Vtable - 66..90 'Vtable...| {} }': Vtable - 83..88 '|| {}': || -> () - 86..88 '{}': () - 100..101 'm': fn() - 104..110 'vtable': Vtable - 104..117 'vtable.method': fn() - "#]], - ); -} - -#[test] -fn effects_smoke_test() { - check_infer( - r#" - fn main() { - let x = unsafe { 92 }; - let y = async { async { () }.await }; - let z = try { () }; - let t = 'a: { 92 }; - } - "#, - expect![[r#" - 10..130 '{ ...2 }; }': () - 20..21 'x': i32 - 24..37 'unsafe { 92 }': i32 - 31..37 '{ 92 }': i32 - 33..35 '92': i32 - 47..48 'y': {unknown} - 57..79 '{ asyn...wait }': {unknown} - 59..77 'async ....await': {unknown} - 65..71 '{ () }': () - 67..69 '()': () - 89..90 'z': {unknown} - 93..103 'try { () }': {unknown} - 97..103 '{ () }': () - 99..101 '()': () - 113..114 't': i32 - 121..127 '{ 92 }': i32 - 123..125 '92': i32 - "#]], - ) -} - -#[test] -fn infer_generic_from_later_assignment() { - check_infer( - r#" - enum Option { Some(T), None } - use Option::*; - - fn test() { - let mut end = None; - loop { - end = Some(true); - } - } - "#, - expect![[r#" - 59..129 '{ ... } }': () - 69..76 'mut end': Option - 79..83 'None': Option - 89..127 'loop {... }': ! - 94..127 '{ ... }': () - 104..107 'end': Option - 104..120 'end = ...(true)': () - 110..114 'Some': Some(bool) -> Option - 110..120 'Some(true)': Option - 115..119 'true': bool - "#]], - ); -} - -#[test] -fn infer_loop_break_with_val() { - check_infer( - r#" - enum Option { Some(T), None } - use Option::*; - - fn test() { - let x = loop { - if false { - break None; - } - - break Some(true); - }; - } - "#, - expect![[r#" - 59..168 '{ ... }; }': () - 69..70 'x': Option - 73..165 'loop {... }': Option - 78..165 '{ ... }': () - 88..132 'if fal... }': () - 91..96 'false': bool - 97..132 '{ ... }': () - 111..121 'break None': ! - 117..121 'None': Option - 142..158 'break ...(true)': ! - 148..152 'Some': Some(bool) -> Option - 148..158 'Some(true)': Option - 153..157 'true': bool - "#]], - ); -} - -#[test] -fn infer_loop_break_without_val() { - check_infer( - r#" - enum Option { Some(T), None } - use Option::*; - - fn test() { - let x = loop { - if false { - break; - } - }; - } - "#, - expect![[r#" - 59..136 '{ ... }; }': () - 69..70 'x': () - 73..133 'loop {... }': () - 78..133 '{ ... }': () - 88..127 'if fal... }': () - 91..96 'false': bool - 97..127 '{ ... }': () - 111..116 'break': ! - "#]], - ); -} - -#[test] -fn infer_labelled_break_with_val() { - check_infer( - r#" - fn foo() { - let _x = || 'outer: loop { - let inner = 'inner: loop { - let i = Default::default(); - if (break 'outer i) { - loop { break 'inner 5i8; }; - } else if true { - break 'inner 6; - } - break 7; - }; - break inner < 8; - }; - } - "#, - expect![[r#" - 9..335 '{ ... }; }': () - 19..21 '_x': || -> bool - 24..332 '|| 'ou... }': || -> bool - 27..332 ''outer... }': bool - 40..332 '{ ... }': () - 54..59 'inner': i8 - 62..300 ''inner... }': i8 - 75..300 '{ ... }': () - 93..94 'i': bool - 97..113 'Defaul...efault': {unknown} - 97..115 'Defaul...ault()': bool - 129..269 'if (br... }': () - 133..147 'break 'outer i': ! - 146..147 'i': bool - 149..208 '{ ... }': () - 167..193 'loop {...5i8; }': ! - 172..193 '{ brea...5i8; }': () - 174..190 'break ...er 5i8': ! - 187..190 '5i8': i8 - 214..269 'if tru... }': () - 217..221 'true': bool - 222..269 '{ ... }': () - 240..254 'break 'inner 6': ! - 253..254 '6': i8 - 282..289 'break 7': ! - 288..289 '7': i8 - 310..325 'break inner < 8': ! - 316..321 'inner': i8 - 316..325 'inner < 8': bool - 324..325 '8': i8 - "#]], - ); -} - -#[test] -fn generic_default() { - check_infer( - r#" - struct Thing { t: T } - enum OtherThing { - One { t: T }, - Two(T), - } - - fn test(t1: Thing, t2: OtherThing, t3: Thing, t4: OtherThing) { - t1.t; - t3.t; - match t2 { - OtherThing::One { t } => { t; }, - OtherThing::Two(t) => { t; }, - } - match t4 { - OtherThing::One { t } => { t; }, - OtherThing::Two(t) => { t; }, - } - } - "#, - expect![[r#" - 97..99 't1': Thing<()> - 108..110 't2': OtherThing<()> - 124..126 't3': Thing - 140..142 't4': OtherThing - 161..384 '{ ... } }': () - 167..169 't1': Thing<()> - 167..171 't1.t': () - 177..179 't3': Thing - 177..181 't3.t': i32 - 187..282 'match ... }': () - 193..195 't2': OtherThing<()> - 206..227 'OtherT... { t }': OtherThing<()> - 224..225 't': () - 231..237 '{ t; }': () - 233..234 't': () - 247..265 'OtherT...Two(t)': OtherThing<()> - 263..264 't': () - 269..275 '{ t; }': () - 271..272 't': () - 287..382 'match ... }': () - 293..295 't4': OtherThing - 306..327 'OtherT... { t }': OtherThing - 324..325 't': i32 - 331..337 '{ t; }': () - 333..334 't': i32 - 347..365 'OtherT...Two(t)': OtherThing - 363..364 't': i32 - 369..375 '{ t; }': () - 371..372 't': i32 - "#]], - ); -} - -#[test] -fn generic_default_in_struct_literal() { - check_infer( - r#" - struct Thing { t: T } - enum OtherThing { - One { t: T }, - Two(T), - } - - fn test() { - let x = Thing { t: loop {} }; - let y = Thing { t: () }; - let z = Thing { t: 1i32 }; - if let Thing { t } = z { - t; - } - - let a = OtherThing::One { t: 1i32 }; - let b = OtherThing::Two(1i32); - } - "#, - expect![[r#" - 99..319 '{ ...32); }': () - 109..110 'x': Thing - 113..133 'Thing ...p {} }': Thing - 124..131 'loop {}': ! - 129..131 '{}': () - 143..144 'y': Thing<()> - 147..162 'Thing { t: () }': Thing<()> - 158..160 '()': () - 172..173 'z': Thing - 176..193 'Thing ...1i32 }': Thing - 187..191 '1i32': i32 - 199..240 'if let... }': () - 206..217 'Thing { t }': Thing - 214..215 't': i32 - 220..221 'z': Thing - 222..240 '{ ... }': () - 232..233 't': i32 - 250..251 'a': OtherThing - 254..281 'OtherT...1i32 }': OtherThing - 275..279 '1i32': i32 - 291..292 'b': OtherThing - 295..310 'OtherThing::Two': Two(i32) -> OtherThing - 295..316 'OtherT...(1i32)': OtherThing - 311..315 '1i32': i32 - "#]], - ); -} - -#[test] -fn generic_default_depending_on_other_type_arg() { - // FIXME: the {unknown} is a bug - check_infer( - r#" - struct Thing T> { t: T } - - fn test(t1: Thing, t2: Thing) { - t1; - t2; - Thing::<_> { t: 1u32 }; - } - "#, - expect![[r#" - 56..58 't1': Thing u32> - 72..74 't2': Thing u128> - 83..130 '{ ...2 }; }': () - 89..91 't1': Thing u32> - 97..99 't2': Thing u128> - 105..127 'Thing:...1u32 }': Thing {unknown}> - 121..125 '1u32': u32 - "#]], - ); -} - -#[test] -fn generic_default_depending_on_other_type_arg_forward() { - // the {unknown} here is intentional, as defaults are not allowed to - // refer to type parameters coming later - check_infer( - r#" - struct Thing T, T = u128> { t: T } - - fn test(t1: Thing) { - t1; - } - "#, - expect![[r#" - 56..58 't1': Thing {unknown}, u128> - 67..78 '{ t1; }': () - 73..75 't1': Thing {unknown}, u128> - "#]], - ); -} diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs deleted file mode 100644 index 526e61caf..000000000 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ /dev/null @@ -1,3113 +0,0 @@ -use expect::expect; -use test_utils::mark; - -use super::{check_infer, check_infer_with_mismatches, check_types}; - -#[test] -fn infer_await() { - check_types( - r#" -//- /main.rs crate:main deps:core -struct IntFuture; - -impl Future for IntFuture { - type Output = u64; -} - -fn test() { - let r = IntFuture; - let v = r.await; - v; -} //^ u64 - -//- /core.rs crate:core -#[prelude_import] use future::*; -mod future { - #[lang = "future_trait"] - trait Future { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_async() { - check_types( - r#" -//- /main.rs crate:main deps:core -async fn foo() -> u64 { - 128 -} - -fn test() { - let r = foo(); - let v = r.await; - v; -} //^ u64 - -//- /core.rs crate:core -#[prelude_import] use future::*; -mod future { - #[lang = "future_trait"] - trait Future { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_desugar_async() { - check_types( - r#" -//- /main.rs crate:main deps:core -async fn foo() -> u64 { - 128 -} - -fn test() { - let r = foo(); - r; -} //^ impl Future - -//- /core.rs crate:core -#[prelude_import] use future::*; -mod future { - trait Future { - type Output; - } -} - -"#, - ); -} - -#[test] -fn infer_try() { - check_types( - r#" -//- /main.rs crate:main deps:core -fn test() { - let r: Result = Result::Ok(1); - let v = r?; - v; -} //^ i32 - -//- /core.rs crate:core -#[prelude_import] use ops::*; -mod ops { - trait Try { - type Ok; - type Error; - } -} - -#[prelude_import] use result::*; -mod result { - enum Result { - Ok(O), - Err(E) - } - - impl crate::ops::Try for Result { - type Ok = O; - type Error = E; - } -} -"#, - ); -} - -#[test] -fn infer_for_loop() { - check_types( - r#" -//- /main.rs crate:main deps:core,alloc -use alloc::collections::Vec; - -fn test() { - let v = Vec::new(); - v.push("foo"); - for x in v { - x; - } //^ &str -} - -//- /core.rs crate:core -#[prelude_import] use iter::*; -mod iter { - trait IntoIterator { - type Item; - } -} - -//- /alloc.rs crate:alloc deps:core -mod collections { - struct Vec {} - impl Vec { - fn new() -> Self { Vec {} } - fn push(&mut self, t: T) { } - } - - impl IntoIterator for Vec { - type Item=T; - } -} -"#, - ); -} - -#[test] -fn infer_ops_neg() { - check_types( - r#" -//- /main.rs crate:main deps:std -struct Bar; -struct Foo; - -impl std::ops::Neg for Bar { - type Output = Foo; -} - -fn test() { - let a = Bar; - let b = -a; - b; -} //^ Foo - -//- /std.rs crate:std -#[prelude_import] use ops::*; -mod ops { - #[lang = "neg"] - pub trait Neg { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_ops_not() { - check_types( - r#" -//- /main.rs crate:main deps:std -struct Bar; -struct Foo; - -impl std::ops::Not for Bar { - type Output = Foo; -} - -fn test() { - let a = Bar; - let b = !a; - b; -} //^ Foo - -//- /std.rs crate:std -#[prelude_import] use ops::*; -mod ops { - #[lang = "not"] - pub trait Not { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_from_bound_1() { - check_infer( - r#" - trait Trait {} - struct S(T); - impl Trait for S {} - fn foo>(t: T) {} - fn test() { - let s = S(unknown); - foo(s); - } - "#, - expect![[r#" - 85..86 't': T - 91..93 '{}': () - 104..143 '{ ...(s); }': () - 114..115 's': S - 118..119 'S': S(u32) -> S - 118..128 'S(unknown)': S - 120..127 'unknown': u32 - 134..137 'foo': fn foo>(S) - 134..140 'foo(s)': () - 138..139 's': S - "#]], - ); -} - -#[test] -fn infer_from_bound_2() { - check_infer( - r#" - trait Trait {} - struct S(T); - impl Trait for S {} - fn foo>(t: T) -> U {} - fn test() { - let s = S(unknown); - let x: u32 = foo(s); - } - "#, - expect![[r#" - 86..87 't': T - 97..99 '{}': () - 110..162 '{ ...(s); }': () - 120..121 's': S - 124..125 'S': S(u32) -> S - 124..134 'S(unknown)': S - 126..133 'unknown': u32 - 144..145 'x': u32 - 153..156 'foo': fn foo>(S) -> u32 - 153..159 'foo(s)': u32 - 157..158 's': S - "#]], - ); -} - -#[test] -fn trait_default_method_self_bound_implements_trait() { - mark::check!(trait_self_implements_self); - check_infer( - r#" - trait Trait { - fn foo(&self) -> i64; - fn bar(&self) -> { - let x = self.foo(); - } - } - "#, - expect![[r#" - 26..30 'self': &Self - 52..56 'self': &Self - 61..96 '{ ... }': () - 75..76 'x': i64 - 79..83 'self': &Self - 79..89 'self.foo()': i64 - "#]], - ); -} - -#[test] -fn trait_default_method_self_bound_implements_super_trait() { - check_infer( - r#" - trait SuperTrait { - fn foo(&self) -> i64; - } - trait Trait: SuperTrait { - fn bar(&self) -> { - let x = self.foo(); - } - } - "#, - expect![[r#" - 31..35 'self': &Self - 85..89 'self': &Self - 94..129 '{ ... }': () - 108..109 'x': i64 - 112..116 'self': &Self - 112..122 'self.foo()': i64 - "#]], - ); -} - -#[test] -fn infer_project_associated_type() { - check_infer( - r#" - trait Iterable { - type Item; - } - struct S; - impl Iterable for S { type Item = u32; } - fn test() { - let x: ::Item = 1; - let y: ::Item = no_matter; - let z: T::Item = no_matter; - let a: ::Item = no_matter; - } - "#, - expect![[r#" - 108..261 '{ ...ter; }': () - 118..119 'x': u32 - 145..146 '1': u32 - 156..157 'y': Iterable::Item - 183..192 'no_matter': Iterable::Item - 202..203 'z': Iterable::Item - 215..224 'no_matter': Iterable::Item - 234..235 'a': Iterable::Item - 249..258 'no_matter': Iterable::Item - "#]], - ); -} - -#[test] -fn infer_return_associated_type() { - check_infer( - r#" - trait Iterable { - type Item; - } - struct S; - impl Iterable for S { type Item = u32; } - fn foo1(t: T) -> T::Item {} - fn foo2(t: T) -> ::Item {} - fn foo3(t: T) -> ::Item {} - fn test() { - let x = foo1(S); - let y = foo2(S); - let z = foo3(S); - } - "#, - expect![[r#" - 106..107 't': T - 123..125 '{}': () - 147..148 't': T - 178..180 '{}': () - 202..203 't': T - 221..223 '{}': () - 234..300 '{ ...(S); }': () - 244..245 'x': u32 - 248..252 'foo1': fn foo1(S) -> ::Item - 248..255 'foo1(S)': u32 - 253..254 'S': S - 265..266 'y': u32 - 269..273 'foo2': fn foo2(S) -> ::Item - 269..276 'foo2(S)': u32 - 274..275 'S': S - 286..287 'z': u32 - 290..294 'foo3': fn foo3(S) -> ::Item - 290..297 'foo3(S)': u32 - 295..296 'S': S - "#]], - ); -} - -#[test] -fn infer_associated_type_bound() { - check_infer( - r#" - trait Iterable { - type Item; - } - fn test>() { - let y: T::Item = unknown; - } - "#, - expect![[r#" - 67..100 '{ ...own; }': () - 77..78 'y': u32 - 90..97 'unknown': u32 - "#]], - ); -} - -#[test] -fn infer_const_body() { - check_infer( - r#" - const A: u32 = 1 + 1; - static B: u64 = { let x = 1; x }; - "#, - expect![[r#" - 15..16 '1': u32 - 15..20 '1 + 1': u32 - 19..20 '1': u32 - 38..54 '{ let ...1; x }': u64 - 44..45 'x': u64 - 48..49 '1': u64 - 51..52 'x': u64 - "#]], - ); -} - -#[test] -fn tuple_struct_fields() { - check_infer( - r#" - struct S(i32, u64); - fn test() -> u64 { - let a = S(4, 6); - let b = a.0; - a.1 - } - "#, - expect![[r#" - 37..86 '{ ... a.1 }': u64 - 47..48 'a': S - 51..52 'S': S(i32, u64) -> S - 51..58 'S(4, 6)': S - 53..54 '4': i32 - 56..57 '6': u64 - 68..69 'b': i32 - 72..73 'a': S - 72..75 'a.0': i32 - 81..82 'a': S - 81..84 'a.1': u64 - "#]], - ); -} - -#[test] -fn tuple_struct_with_fn() { - check_infer( - r#" - struct S(fn(u32) -> u64); - fn test() -> u64 { - let a = S(|i| 2*i); - let b = a.0(4); - a.0(2) - } - "#, - expect![[r#" - 43..101 '{ ...0(2) }': u64 - 53..54 'a': S - 57..58 'S': S(fn(u32) -> u64) -> S - 57..67 'S(|i| 2*i)': S - 59..66 '|i| 2*i': |u32| -> u64 - 60..61 'i': u32 - 63..64 '2': u32 - 63..66 '2*i': u32 - 65..66 'i': u32 - 77..78 'b': u64 - 81..82 'a': S - 81..84 'a.0': fn(u32) -> u64 - 81..87 'a.0(4)': u64 - 85..86 '4': u32 - 93..94 'a': S - 93..96 'a.0': fn(u32) -> u64 - 93..99 'a.0(2)': u64 - 97..98 '2': u32 - "#]], - ); -} - -#[test] -fn indexing_arrays() { - check_infer( - "fn main() { &mut [9][2]; }", - expect![[r#" - 10..26 '{ &mut...[2]; }': () - 12..23 '&mut [9][2]': &mut {unknown} - 17..20 '[9]': [i32; _] - 17..23 '[9][2]': {unknown} - 18..19 '9': i32 - 21..22 '2': i32 - "#]], - ) -} - -#[test] -fn infer_ops_index() { - check_types( - r#" -//- /main.rs crate:main deps:std -struct Bar; -struct Foo; - -impl std::ops::Index for Bar { - type Output = Foo; -} - -fn test() { - let a = Bar; - let b = a[1u32]; - b; -} //^ Foo - -//- /std.rs crate:std -#[prelude_import] use ops::*; -mod ops { - #[lang = "index"] - pub trait Index { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_ops_index_int() { - check_types( - r#" -//- /main.rs crate:main deps:std -struct Bar; -struct Foo; - -impl std::ops::Index for Bar { - type Output = Foo; -} - -struct Range; -impl std::ops::Index for Bar { - type Output = Bar; -} - -fn test() { - let a = Bar; - let b = a[1]; - b; - //^ Foo -} - -//- /std.rs crate:std -#[prelude_import] use ops::*; -mod ops { - #[lang = "index"] - pub trait Index { - type Output; - } -} -"#, - ); -} - -#[test] -fn infer_ops_index_autoderef() { - check_types( - r#" -//- /main.rs crate:main deps:std -fn test() { - let a = &[1u32, 2, 3]; - let b = a[1u32]; - b; -} //^ u32 - -//- /std.rs crate:std -impl ops::Index for [T] { - type Output = T; -} - -#[prelude_import] use ops::*; -mod ops { - #[lang = "index"] - pub trait Index { - type Output; - } -} -"#, - ); -} - -#[test] -fn deref_trait() { - check_types( - r#" -#[lang = "deref"] -trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} - -struct Arc; -impl Deref for Arc { - type Target = T; -} - -struct S; -impl S { - fn foo(&self) -> u128 {} -} - -fn test(s: Arc) { - (*s, s.foo()); -} //^ (S, u128) -"#, - ); -} - -#[test] -fn deref_trait_with_inference_var() { - check_types( - r#" -//- /main.rs -#[lang = "deref"] -trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} - -struct Arc; -fn new_arc() -> Arc {} -impl Deref for Arc { - type Target = T; -} - -struct S; -fn foo(a: Arc) {} - -fn test() { - let a = new_arc(); - let b = (*a); - //^ S - foo(a); -} -"#, - ); -} - -#[test] -fn deref_trait_infinite_recursion() { - check_types( - r#" -#[lang = "deref"] -trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} - -struct S; - -impl Deref for S { - type Target = S; -} - -fn test(s: S) { - s.foo(); -} //^ {unknown} -"#, - ); -} - -#[test] -fn deref_trait_with_question_mark_size() { - check_types( - r#" -#[lang = "deref"] -trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} - -struct Arc; -impl Deref for Arc { - type Target = T; -} - -struct S; -impl S { - fn foo(&self) -> u128 {} -} - -fn test(s: Arc) { - (*s, s.foo()); -} //^ (S, u128) -"#, - ); -} - -#[test] -fn obligation_from_function_clause() { - check_types( - r#" -struct S; - -trait Trait {} -impl Trait for S {} - -fn foo, U>(t: T) -> U {} - -fn test(s: S) { - (foo(s)); -} //^ u32 -"#, - ); -} - -#[test] -fn obligation_from_method_clause() { - check_types( - r#" -//- /main.rs -struct S; - -trait Trait {} -impl Trait for S {} - -struct O; -impl O { - fn foo, U>(&self, t: T) -> U {} -} - -fn test() { - O.foo(S); -} //^ isize -"#, - ); -} - -#[test] -fn obligation_from_self_method_clause() { - check_types( - r#" -struct S; - -trait Trait {} -impl Trait for S {} - -impl S { - fn foo(&self) -> U where Self: Trait {} -} - -fn test() { - S.foo(); -} //^ i64 -"#, - ); -} - -#[test] -fn obligation_from_impl_clause() { - check_types( - r#" -struct S; - -trait Trait {} -impl Trait<&str> for S {} - -struct O; -impl> O { - fn foo(&self) -> U {} -} - -fn test(o: O) { - o.foo(); -} //^ &str -"#, - ); -} - -#[test] -fn generic_param_env_1() { - check_types( - r#" -trait Clone {} -trait Trait { fn foo(self) -> u128; } -struct S; -impl Clone for S {} -impl Trait for T where T: Clone {} -fn test(t: T) { t.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn generic_param_env_1_not_met() { - check_types( - r#" -//- /main.rs -trait Clone {} -trait Trait { fn foo(self) -> u128; } -struct S; -impl Clone for S {} -impl Trait for T where T: Clone {} -fn test(t: T) { t.foo(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn generic_param_env_2() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for S {} -fn test(t: T) { t.foo(); } - //^ u128 -"#, - ); -} - -#[test] -fn generic_param_env_2_not_met() { - check_types( - r#" -trait Trait { fn foo(self) -> u128; } -struct S; -impl Trait for S {} -fn test(t: T) { t.foo(); } - //^ {unknown} -"#, - ); -} - -#[test] -fn generic_param_env_deref() { - check_types( - r#" -#[lang = "deref"] -trait Deref { - type Target; -} -trait Trait {} -impl Deref for T where T: Trait { - type Target = i128; -} -fn test(t: T) { (*t); } - //^ i128 -"#, - ); -} - -#[test] -fn associated_type_placeholder() { - // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. - check_types( - r#" -pub trait ApplyL { - type Out; -} - -pub struct RefMutL; - -impl ApplyL for RefMutL { - type Out = ::Out; -} - -fn test() { - let y: as ApplyL>::Out = no_matter; - y; -} //^ ApplyL::Out -"#, - ); -} - -#[test] -fn associated_type_placeholder_2() { - check_types( - r#" -pub trait ApplyL { - type Out; -} -fn foo(t: T) -> ::Out; - -fn test(t: T) { - let y = foo(t); - y; -} //^ ApplyL::Out -"#, - ); -} - -#[test] -fn argument_impl_trait() { - check_infer_with_mismatches( - r#" - trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; - } - fn bar(x: impl Trait) {} - struct S(T); - impl Trait for S {} - - fn test(x: impl Trait, y: &impl Trait) { - x; - y; - let z = S(1); - bar(z); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); - } - "#, - expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 77..78 'x': impl Trait - 97..99 '{}': () - 154..155 'x': impl Trait - 174..175 'y': &impl Trait - 195..323 '{ ...2(); }': () - 201..202 'x': impl Trait - 208..209 'y': &impl Trait - 219..220 'z': S - 223..224 'S': S(u16) -> S - 223..227 'S(1)': S - 225..226 '1': u16 - 233..236 'bar': fn bar(S) - 233..239 'bar(z)': () - 237..238 'z': S - 245..246 'x': impl Trait - 245..252 'x.foo()': u64 - 258..259 'y': &impl Trait - 258..265 'y.foo()': u32 - 271..272 'z': S - 271..278 'z.foo()': u16 - 284..285 'x': impl Trait - 284..292 'x.foo2()': i64 - 298..299 'y': &impl Trait - 298..306 'y.foo2()': i64 - 312..313 'z': S - 312..320 'z.foo2()': i64 - "#]], - ); -} - -#[test] -fn argument_impl_trait_type_args_1() { - check_infer_with_mismatches( - r#" - trait Trait {} - trait Foo { - // this function has an implicit Self param, an explicit type param, - // and an implicit impl Trait param! - fn bar(x: impl Trait) -> T { loop {} } - } - fn foo(x: impl Trait) -> T { loop {} } - struct S; - impl Trait for S {} - struct F; - impl Foo for F {} - - fn test() { - Foo::bar(S); - ::bar(S); - F::bar(S); - Foo::bar::(S); - ::bar::(S); - - foo(S); - foo::(S); - foo::(S); // we should ignore the extraneous i32 - } - "#, - expect![[r#" - 155..156 'x': impl Trait - 175..186 '{ loop {} }': T - 177..184 'loop {}': ! - 182..184 '{}': () - 199..200 'x': impl Trait - 219..230 '{ loop {} }': T - 221..228 'loop {}': ! - 226..228 '{}': () - 300..509 '{ ... i32 }': () - 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} - 306..317 'Foo::bar(S)': {unknown} - 315..316 'S': S - 323..338 '::bar': fn bar(S) -> {unknown} - 323..341 '(S) -> {unknown} - 347..356 'F::bar(S)': {unknown} - 354..355 'S': S - 362..377 'Foo::bar::': fn bar<{unknown}, u32>(S) -> u32 - 362..380 'Foo::b...32>(S)': u32 - 378..379 'S': S - 386..408 '': fn bar(S) -> u32 - 386..411 '(S)': u32 - 409..410 'S': S - 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} - 418..424 'foo(S)': {unknown} - 422..423 'S': S - 430..440 'foo::': fn foo(S) -> u32 - 430..443 'foo::(S)': u32 - 441..442 'S': S - 449..464 'foo::': fn foo(S) -> u32 - 449..467 'foo::<...32>(S)': u32 - 465..466 'S': S - "#]], - ); -} - -#[test] -fn argument_impl_trait_type_args_2() { - check_infer_with_mismatches( - r#" - trait Trait {} - struct S; - impl Trait for S {} - struct F; - impl F { - fn foo(self, x: impl Trait) -> (T, U) { loop {} } - } - - fn test() { - F.foo(S); - F::.foo(S); - F::.foo::(S); - F::.foo::(S); // extraneous argument should be ignored - } - "#, - expect![[r#" - 87..91 'self': F - 93..94 'x': impl Trait - 118..129 '{ loop {} }': (T, U) - 120..127 'loop {}': ! - 125..127 '{}': () - 143..283 '{ ...ored }': () - 149..150 'F': F<{unknown}> - 149..157 'F.foo(S)': ({unknown}, {unknown}) - 155..156 'S': S - 163..171 'F::': F - 163..178 'F::.foo(S)': (u32, {unknown}) - 176..177 'S': S - 184..192 'F::': F - 184..206 'F::(S)': (u32, i32) - 204..205 'S': S - 212..220 'F::': F - 212..239 'F::(S)': (u32, i32) - 237..238 'S': S - "#]], - ); -} - -#[test] -fn argument_impl_trait_to_fn_pointer() { - check_infer_with_mismatches( - r#" - trait Trait {} - fn foo(x: impl Trait) { loop {} } - struct S; - impl Trait for S {} - - fn test() { - let f: fn(S) -> () = foo; - } - "#, - expect![[r#" - 22..23 'x': impl Trait - 37..48 '{ loop {} }': () - 39..46 'loop {}': ! - 44..46 '{}': () - 90..123 '{ ...foo; }': () - 100..101 'f': fn(S) - 117..120 'foo': fn foo(S) - "#]], - ); -} - -#[test] -fn impl_trait() { - check_infer( - r#" - trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; - } - fn bar() -> impl Trait {} - - fn test(x: impl Trait, y: &impl Trait) { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); - } - "#, - expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 98..100 '{}': () - 110..111 'x': impl Trait - 130..131 'y': &impl Trait - 151..268 '{ ...2(); }': () - 157..158 'x': impl Trait - 164..165 'y': &impl Trait - 175..176 'z': impl Trait - 179..182 'bar': fn bar() -> impl Trait - 179..184 'bar()': impl Trait - 190..191 'x': impl Trait - 190..197 'x.foo()': u64 - 203..204 'y': &impl Trait - 203..210 'y.foo()': u64 - 216..217 'z': impl Trait - 216..223 'z.foo()': u64 - 229..230 'x': impl Trait - 229..237 'x.foo2()': i64 - 243..244 'y': &impl Trait - 243..251 'y.foo2()': i64 - 257..258 'z': impl Trait - 257..265 'z.foo2()': i64 - "#]], - ); -} - -#[test] -fn simple_return_pos_impl_trait() { - mark::check!(lower_rpit); - check_infer( - r#" - trait Trait { - fn foo(&self) -> T; - } - fn bar() -> impl Trait { loop {} } - - fn test() { - let a = bar(); - a.foo(); - } - "#, - expect![[r#" - 29..33 'self': &Self - 71..82 '{ loop {} }': ! - 73..80 'loop {}': ! - 78..80 '{}': () - 94..129 '{ ...o(); }': () - 104..105 'a': impl Trait - 108..111 'bar': fn bar() -> impl Trait - 108..113 'bar()': impl Trait - 119..120 'a': impl Trait - 119..126 'a.foo()': u64 - "#]], - ); -} - -#[test] -fn more_return_pos_impl_trait() { - check_infer( - r#" - trait Iterator { - type Item; - fn next(&mut self) -> Self::Item; - } - trait Trait { - fn foo(&self) -> T; - } - fn bar() -> (impl Iterator>, impl Trait) { loop {} } - fn baz(t: T) -> (impl Iterator>, impl Trait) { loop {} } - - fn test() { - let (a, b) = bar(); - a.next().foo(); - b.foo(); - let (c, d) = baz(1u128); - c.next().foo(); - d.foo(); - } - "#, - expect![[r#" - 49..53 'self': &mut Self - 101..105 'self': &Self - 184..195 '{ loop {} }': ({unknown}, {unknown}) - 186..193 'loop {}': ! - 191..193 '{}': () - 206..207 't': T - 268..279 '{ loop {} }': ({unknown}, {unknown}) - 270..277 'loop {}': ! - 275..277 '{}': () - 291..413 '{ ...o(); }': () - 301..307 '(a, b)': (impl Iterator>, impl Trait) - 302..303 'a': impl Iterator> - 305..306 'b': impl Trait - 310..313 'bar': fn bar() -> (impl Iterator>, impl Trait) - 310..315 'bar()': (impl Iterator>, impl Trait) - 321..322 'a': impl Iterator> - 321..329 'a.next()': impl Trait - 321..335 'a.next().foo()': u32 - 341..342 'b': impl Trait - 341..348 'b.foo()': u64 - 358..364 '(c, d)': (impl Iterator>, impl Trait) - 359..360 'c': impl Iterator> - 362..363 'd': impl Trait - 367..370 'baz': fn baz(u128) -> (impl Iterator>, impl Trait) - 367..377 'baz(1u128)': (impl Iterator>, impl Trait) - 371..376 '1u128': u128 - 383..384 'c': impl Iterator> - 383..391 'c.next()': impl Trait - 383..397 'c.next().foo()': u128 - 403..404 'd': impl Trait - 403..410 'd.foo()': u128 - "#]], - ); -} - -#[test] -fn dyn_trait() { - check_infer( - r#" - trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; - } - fn bar() -> dyn Trait {} - - fn test(x: dyn Trait, y: &dyn Trait) { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); - } - "#, - expect![[r#" - 29..33 'self': &Self - 54..58 'self': &Self - 97..99 '{}': () - 109..110 'x': dyn Trait - 128..129 'y': &dyn Trait - 148..265 '{ ...2(); }': () - 154..155 'x': dyn Trait - 161..162 'y': &dyn Trait - 172..173 'z': dyn Trait - 176..179 'bar': fn bar() -> dyn Trait - 176..181 'bar()': dyn Trait - 187..188 'x': dyn Trait - 187..194 'x.foo()': u64 - 200..201 'y': &dyn Trait - 200..207 'y.foo()': u64 - 213..214 'z': dyn Trait - 213..220 'z.foo()': u64 - 226..227 'x': dyn Trait - 226..234 'x.foo2()': i64 - 240..241 'y': &dyn Trait - 240..248 'y.foo2()': i64 - 254..255 'z': dyn Trait - 254..262 'z.foo2()': i64 - "#]], - ); -} - -#[test] -fn dyn_trait_in_impl() { - check_infer( - r#" - trait Trait { - fn foo(&self) -> (T, U); - } - struct S {} - impl S { - fn bar(&self) -> &dyn Trait { loop {} } - } - trait Trait2 { - fn baz(&self) -> (T, U); - } - impl Trait2 for dyn Trait { } - - fn test(s: S) { - s.bar().baz(); - } - "#, - expect![[r#" - 32..36 'self': &Self - 102..106 'self': &S - 128..139 '{ loop {} }': &dyn Trait - 130..137 'loop {}': ! - 135..137 '{}': () - 175..179 'self': &Self - 251..252 's': S - 267..289 '{ ...z(); }': () - 273..274 's': S - 273..280 's.bar()': &dyn Trait - 273..286 's.bar().baz()': (u32, i32) - "#]], - ); -} - -#[test] -fn dyn_trait_bare() { - check_infer( - r#" - trait Trait { - fn foo(&self) -> u64; - } - fn bar() -> Trait {} - - fn test(x: Trait, y: &Trait) -> u64 { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); - } - "#, - expect![[r#" - 26..30 'self': &Self - 60..62 '{}': () - 72..73 'x': dyn Trait - 82..83 'y': &dyn Trait - 100..175 '{ ...o(); }': () - 106..107 'x': dyn Trait - 113..114 'y': &dyn Trait - 124..125 'z': dyn Trait - 128..131 'bar': fn bar() -> dyn Trait - 128..133 'bar()': dyn Trait - 139..140 'x': dyn Trait - 139..146 'x.foo()': u64 - 152..153 'y': &dyn Trait - 152..159 'y.foo()': u64 - 165..166 'z': dyn Trait - 165..172 'z.foo()': u64 - "#]], - ); -} - -#[test] -fn weird_bounds() { - check_infer( - r#" - trait Trait {} - fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} - "#, - expect![[r#" - 23..24 'a': impl Trait + {error} - 50..51 'b': impl {error} - 69..70 'c': impl Trait - 86..87 'd': impl {error} - 107..108 'e': impl {error} - 123..124 'f': impl Trait + {error} - 147..149 '{}': () - "#]], - ); -} - -#[test] -#[ignore] -fn error_bound_chalk() { - check_types( - r#" -trait Trait { - fn foo(&self) -> u32 {} -} - -fn test(x: (impl Trait + UnknownTrait)) { - x.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn assoc_type_bindings() { - check_infer( - r#" - trait Trait { - type Type; - } - - fn get(t: T) -> ::Type {} - fn get2>(t: T) -> U {} - fn set>(t: T) -> T {t} - - struct S; - impl Trait for S { type Type = T; } - - fn test>(x: T, y: impl Trait) { - get(x); - get2(x); - get(y); - get2(y); - get(set(S)); - get2(set(S)); - get2(S::); - } - "#, - expect![[r#" - 49..50 't': T - 77..79 '{}': () - 111..112 't': T - 122..124 '{}': () - 154..155 't': T - 165..168 '{t}': T - 166..167 't': T - 256..257 'x': T - 262..263 'y': impl Trait - 289..397 '{ ...r>); }': () - 295..298 'get': fn get(T) -> ::Type - 295..301 'get(x)': u32 - 299..300 'x': T - 307..311 'get2': fn get2(T) -> u32 - 307..314 'get2(x)': u32 - 312..313 'x': T - 320..323 'get': fn get>(impl Trait) -> as Trait>::Type - 320..326 'get(y)': i64 - 324..325 'y': impl Trait - 332..336 'get2': fn get2>(impl Trait) -> i64 - 332..339 'get2(y)': i64 - 337..338 'y': impl Trait - 345..348 'get': fn get>(S) -> as Trait>::Type - 345..356 'get(set(S))': u64 - 349..352 'set': fn set>(S) -> S - 349..355 'set(S)': S - 353..354 'S': S - 362..366 'get2': fn get2>(S) -> u64 - 362..374 'get2(set(S))': u64 - 367..370 'set': fn set>(S) -> S - 367..373 'set(S)': S - 371..372 'S': S - 380..384 'get2': fn get2>(S) -> str - 380..394 'get2(S::)': str - 385..393 'S::': S - "#]], - ); -} - -#[test] -fn impl_trait_assoc_binding_projection_bug() { - check_types( - r#" -//- /main.rs crate:main deps:std -pub trait Language { - type Kind; -} -pub enum RustLanguage {} -impl Language for RustLanguage { - type Kind = SyntaxKind; -} -struct SyntaxNode {} -fn foo() -> impl Iterator> {} - -trait Clone { - fn clone(&self) -> Self; -} - -fn api_walkthrough() { - for node in foo() { - node.clone(); - } //^ {unknown} -} - -//- /std.rs crate:std -#[prelude_import] use iter::*; -mod iter { - trait IntoIterator { - type Item; - } - trait Iterator { - type Item; - } - impl IntoIterator for T { - type Item = ::Item; - } -} -"#, - ); -} - -#[test] -fn projection_eq_within_chalk() { - check_infer( - r#" - trait Trait1 { - type Type; - } - trait Trait2 { - fn foo(self) -> T; - } - impl Trait2 for U where U: Trait1 {} - - fn test>(x: T) { - x.foo(); - } - "#, - expect![[r#" - 61..65 'self': Self - 163..164 'x': T - 169..185 '{ ...o(); }': () - 175..176 'x': T - 175..182 'x.foo()': u32 - "#]], - ); -} - -#[test] -fn where_clause_trait_in_scope_for_method_resolution() { - check_types( - r#" -mod foo { - trait Trait { - fn foo(&self) -> u32 {} - } -} - -fn test(x: T) { - x.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn super_trait_method_resolution() { - check_infer( - r#" - mod foo { - trait SuperTrait { - fn foo(&self) -> u32 {} - } - } - trait Trait1: foo::SuperTrait {} - trait Trait2 where Self: foo::SuperTrait {} - - fn test(x: T, y: U) { - x.foo(); - y.foo(); - } - "#, - expect![[r#" - 49..53 'self': &Self - 62..64 '{}': () - 181..182 'x': T - 187..188 'y': U - 193..222 '{ ...o(); }': () - 199..200 'x': T - 199..206 'x.foo()': u32 - 212..213 'y': U - 212..219 'y.foo()': u32 - "#]], - ); -} - -#[test] -fn super_trait_impl_trait_method_resolution() { - check_infer( - r#" - mod foo { - trait SuperTrait { - fn foo(&self) -> u32 {} - } - } - trait Trait1: foo::SuperTrait {} - - fn test(x: &impl Trait1) { - x.foo(); - } - "#, - expect![[r#" - 49..53 'self': &Self - 62..64 '{}': () - 115..116 'x': &impl Trait1 - 132..148 '{ ...o(); }': () - 138..139 'x': &impl Trait1 - 138..145 'x.foo()': u32 - "#]], - ); -} - -#[test] -fn super_trait_cycle() { - // This just needs to not crash - check_infer( - r#" - trait A: B {} - trait B: A {} - - fn test(x: T) { - x.foo(); - } - "#, - expect![[r#" - 43..44 'x': T - 49..65 '{ ...o(); }': () - 55..56 'x': T - 55..62 'x.foo()': {unknown} - "#]], - ); -} - -#[test] -fn super_trait_assoc_type_bounds() { - check_infer( - r#" - trait SuperTrait { type Type; } - trait Trait where Self: SuperTrait {} - - fn get2>(t: T) -> U {} - fn set>(t: T) -> T {t} - - struct S; - impl SuperTrait for S { type Type = T; } - impl Trait for S {} - - fn test() { - get2(set(S)); - } - "#, - expect![[r#" - 102..103 't': T - 113..115 '{}': () - 145..146 't': T - 156..159 '{t}': T - 157..158 't': T - 258..279 '{ ...S)); }': () - 264..268 'get2': fn get2>(S) -> u64 - 264..276 'get2(set(S))': u64 - 269..272 'set': fn set>(S) -> S - 269..275 'set(S)': S - 273..274 'S': S - "#]], - ); -} - -#[test] -fn fn_trait() { - check_infer( - r#" - trait FnOnce { - type Output; - - fn call_once(self, args: Args) -> >::Output; - } - - fn test u128>(f: F) { - f.call_once((1, 2)); - } - "#, - expect![[r#" - 56..60 'self': Self - 62..66 'args': Args - 149..150 'f': F - 155..183 '{ ...2)); }': () - 161..162 'f': F - 161..180 'f.call...1, 2))': u128 - 173..179 '(1, 2)': (u32, u64) - 174..175 '1': u32 - 177..178 '2': u64 - "#]], - ); -} - -#[test] -fn fn_ptr_and_item() { - check_infer( - r#" - #[lang="fn_once"] - trait FnOnce { - type Output; - - fn call_once(self, args: Args) -> Self::Output; - } - - trait Foo { - fn foo(&self) -> T; - } - - struct Bar(T); - - impl R> Foo<(A1, R)> for Bar { - fn foo(&self) -> (A1, R) {} - } - - enum Opt { None, Some(T) } - impl Opt { - fn map U>(self, f: F) -> Opt {} - } - - fn test() { - let bar: Bar u32>; - bar.foo(); - - let opt: Opt; - let f: fn(u8) -> u32; - opt.map(f); - } - "#, - expect![[r#" - 74..78 'self': Self - 80..84 'args': Args - 139..143 'self': &Self - 243..247 'self': &Bar - 260..262 '{}': () - 346..350 'self': Opt - 352..353 'f': F - 368..370 '{}': () - 384..500 '{ ...(f); }': () - 394..397 'bar': Bar u32> - 423..426 'bar': Bar u32> - 423..432 'bar.foo()': (u8, u32) - 443..446 'opt': Opt - 465..466 'f': fn(u8) -> u32 - 487..490 'opt': Opt - 487..497 'opt.map(f)': Opt - 495..496 'f': fn(u8) -> u32 - "#]], - ); -} - -#[test] -fn fn_trait_deref_with_ty_default() { - check_infer( - r#" - #[lang = "deref"] - trait Deref { - type Target; - - fn deref(&self) -> &Self::Target; - } - - #[lang="fn_once"] - trait FnOnce { - type Output; - - fn call_once(self, args: Args) -> Self::Output; - } - - struct Foo; - - impl Foo { - fn foo(&self) -> usize {} - } - - struct Lazy T>(F); - - impl Lazy { - pub fn new(f: F) -> Lazy {} - } - - impl T> Deref for Lazy { - type Target = T; - } - - fn test() { - let lazy1: Lazy = Lazy::new(|| Foo); - let r1 = lazy1.foo(); - - fn make_foo_fn() -> Foo {} - let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; - let lazy2: Lazy = Lazy::new(make_foo_fn_ptr); - let r2 = lazy2.foo(); - } - "#, - expect![[r#" - 64..68 'self': &Self - 165..169 'self': Self - 171..175 'args': Args - 239..243 'self': &Foo - 254..256 '{}': () - 334..335 'f': F - 354..356 '{}': () - 443..689 '{ ...o(); }': () - 453..458 'lazy1': Lazy Foo> - 475..484 'Lazy::new': fn new Foo>(|| -> Foo) -> Lazy Foo> - 475..492 'Lazy::...| Foo)': Lazy Foo> - 485..491 '|| Foo': || -> Foo - 488..491 'Foo': Foo - 502..504 'r1': usize - 507..512 'lazy1': Lazy Foo> - 507..518 'lazy1.foo()': usize - 560..575 'make_foo_fn_ptr': fn() -> Foo - 591..602 'make_foo_fn': fn make_foo_fn() -> Foo - 612..617 'lazy2': Lazy Foo> - 634..643 'Lazy::new': fn new Foo>(fn() -> Foo) -> Lazy Foo> - 634..660 'Lazy::...n_ptr)': Lazy Foo> - 644..659 'make_foo_fn_ptr': fn() -> Foo - 670..672 'r2': usize - 675..680 'lazy2': Lazy Foo> - 675..686 'lazy2.foo()': usize - 549..551 '{}': () - "#]], - ); -} - -#[test] -fn closure_1() { - check_infer( - r#" - #[lang = "fn_once"] - trait FnOnce { - type Output; - } - - enum Option { Some(T), None } - impl Option { - fn map U>(self, f: F) -> Option {} - } - - fn test() { - let x = Option::Some(1u32); - x.map(|v| v + 1); - x.map(|_v| 1u64); - let y: Option = x.map(|_v| 1); - } - "#, - expect![[r#" - 147..151 'self': Option - 153..154 'f': F - 172..174 '{}': () - 188..307 '{ ... 1); }': () - 198..199 'x': Option - 202..214 'Option::Some': Some(u32) -> Option - 202..220 'Option...(1u32)': Option - 215..219 '1u32': u32 - 226..227 'x': Option - 226..242 'x.map(...v + 1)': Option - 232..241 '|v| v + 1': |u32| -> u32 - 233..234 'v': u32 - 236..237 'v': u32 - 236..241 'v + 1': u32 - 240..241 '1': u32 - 248..249 'x': Option - 248..264 'x.map(... 1u64)': Option - 254..263 '|_v| 1u64': |u32| -> u64 - 255..257 '_v': u32 - 259..263 '1u64': u64 - 274..275 'y': Option - 291..292 'x': Option - 291..304 'x.map(|_v| 1)': Option - 297..303 '|_v| 1': |u32| -> i64 - 298..300 '_v': u32 - 302..303 '1': i64 - "#]], - ); -} - -#[test] -fn closure_2() { - check_infer( - r#" - trait FnOnce { - type Output; - } - - fn test u64>(f: F) { - f(1); - let g = |v| v + 1; - g(1u64); - let h = |v| 1u128 + v; - } - "#, - expect![[r#" - 72..73 'f': F - 78..154 '{ ...+ v; }': () - 84..85 'f': F - 84..88 'f(1)': {unknown} - 86..87 '1': i32 - 98..99 'g': |u64| -> i32 - 102..111 '|v| v + 1': |u64| -> i32 - 103..104 'v': u64 - 106..107 'v': u64 - 106..111 'v + 1': i32 - 110..111 '1': i32 - 117..118 'g': |u64| -> i32 - 117..124 'g(1u64)': i32 - 119..123 '1u64': u64 - 134..135 'h': |u128| -> u128 - 138..151 '|v| 1u128 + v': |u128| -> u128 - 139..140 'v': u128 - 142..147 '1u128': u128 - 142..151 '1u128 + v': u128 - 150..151 'v': u128 - "#]], - ); -} - -#[test] -fn closure_as_argument_inference_order() { - check_infer( - r#" - #[lang = "fn_once"] - trait FnOnce { - type Output; - } - - fn foo1 U>(x: T, f: F) -> U {} - fn foo2 U>(f: F, x: T) -> U {} - - struct S; - impl S { - fn method(self) -> u64; - - fn foo1 U>(self, x: T, f: F) -> U {} - fn foo2 U>(self, f: F, x: T) -> U {} - } - - fn test() { - let x1 = foo1(S, |s| s.method()); - let x2 = foo2(|s| s.method(), S); - let x3 = S.foo1(S, |s| s.method()); - let x4 = S.foo2(|s| s.method(), S); - } - "#, - expect![[r#" - 94..95 'x': T - 100..101 'f': F - 111..113 '{}': () - 147..148 'f': F - 153..154 'x': T - 164..166 '{}': () - 201..205 'self': S - 253..257 'self': S - 259..260 'x': T - 265..266 'f': F - 276..278 '{}': () - 316..320 'self': S - 322..323 'f': F - 328..329 'x': T - 339..341 '{}': () - 355..514 '{ ... S); }': () - 365..367 'x1': u64 - 370..374 'foo1': fn foo1 u64>(S, |S| -> u64) -> u64 - 370..393 'foo1(S...hod())': u64 - 375..376 'S': S - 378..392 '|s| s.method()': |S| -> u64 - 379..380 's': S - 382..383 's': S - 382..392 's.method()': u64 - 403..405 'x2': u64 - 408..412 'foo2': fn foo2 u64>(|S| -> u64, S) -> u64 - 408..431 'foo2(|...(), S)': u64 - 413..427 '|s| s.method()': |S| -> u64 - 414..415 's': S - 417..418 's': S - 417..427 's.method()': u64 - 429..430 'S': S - 441..443 'x3': u64 - 446..447 'S': S - 446..471 'S.foo1...hod())': u64 - 453..454 'S': S - 456..470 '|s| s.method()': |S| -> u64 - 457..458 's': S - 460..461 's': S - 460..470 's.method()': u64 - 481..483 'x4': u64 - 486..487 'S': S - 486..511 'S.foo2...(), S)': u64 - 493..507 '|s| s.method()': |S| -> u64 - 494..495 's': S - 497..498 's': S - 497..507 's.method()': u64 - 509..510 'S': S - "#]], - ); -} - -#[test] -fn fn_item_fn_trait() { - check_types( - r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} - -struct S; - -fn foo() -> S {} - -fn takes_closure U>(f: F) -> U { f() } - -fn test() { - takes_closure(foo); -} //^^^^^^^^^^^^^^^^^^ S -"#, - ); -} - -#[test] -fn unselected_projection_in_trait_env_1() { - check_types( - r#" -//- /main.rs -trait Trait { - type Item; -} - -trait Trait2 { - fn foo(&self) -> u32; -} - -fn test() where T::Item: Trait2 { - let x: T::Item = no_matter; - x.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn unselected_projection_in_trait_env_2() { - check_types( - r#" -trait Trait { - type Item; -} - -trait Trait2 { - fn foo(&self) -> u32; -} - -fn test() where T::Item: Trait2, T: Trait, U: Trait<()> { - let x: T::Item = no_matter; - x.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn unselected_projection_on_impl_self() { - check_infer( - r#" - //- /main.rs - trait Trait { - type Item; - - fn f(&self, x: Self::Item); - } - - struct S; - - impl Trait for S { - type Item = u32; - fn f(&self, x: Self::Item) { let y = x; } - } - - struct S2; - - impl Trait for S2 { - type Item = i32; - fn f(&self, x: ::Item) { let y = x; } - } - "#, - expect![[r#" - 40..44 'self': &Self - 46..47 'x': Trait::Item - 126..130 'self': &S - 132..133 'x': u32 - 147..161 '{ let y = x; }': () - 153..154 'y': u32 - 157..158 'x': u32 - 228..232 'self': &S2 - 234..235 'x': i32 - 251..265 '{ let y = x; }': () - 257..258 'y': i32 - 261..262 'x': i32 - "#]], - ); -} - -#[test] -fn unselected_projection_on_trait_self() { - check_types( - r#" -trait Trait { - type Item; - - fn f(&self) -> Self::Item { loop {} } -} - -struct S; -impl Trait for S { - type Item = u32; -} - -fn test() { - S.f(); -} //^ u32 -"#, - ); -} - -#[test] -fn unselected_projection_chalk_fold() { - check_types( - r#" -trait Interner {} -trait Fold { - type Result; -} - -struct Ty {} -impl Fold for Ty { - type Result = Ty; -} - -fn fold(interner: &I, t: T) -> T::Result -where - T: Fold, -{ - loop {} -} - -fn foo(interner: &I, t: Ty) { - fold(interner, t); -} //^ Ty -"#, - ); -} - -#[test] -fn trait_impl_self_ty() { - check_types( - r#" -trait Trait { - fn foo(&self); -} - -struct S; - -impl Trait for S {} - -fn test() { - S.foo(); -} //^ () -"#, - ); -} - -#[test] -fn trait_impl_self_ty_cycle() { - check_types( - r#" -trait Trait { - fn foo(&self); -} - -struct S; - -impl Trait for S {} - -fn test() { - S.foo(); -} //^ {unknown} -"#, - ); -} - -#[test] -fn unselected_projection_in_trait_env_cycle_1() { - // this is a legitimate cycle - check_types( - r#" -trait Trait { - type Item; -} - -trait Trait2 {} - -fn test() where T: Trait2 { - let x: T::Item = no_matter; -} //^ {unknown} -"#, - ); -} - -#[test] -fn unselected_projection_in_trait_env_cycle_2() { - // this is a legitimate cycle - check_types( - r#" -//- /main.rs -trait Trait { - type Item; -} - -fn test() where T: Trait, U: Trait { - let x: T::Item = no_matter; -} //^ {unknown} -"#, - ); -} - -#[test] -fn inline_assoc_type_bounds_1() { - check_types( - r#" -trait Iterator { - type Item; -} -trait OtherTrait { - fn foo(&self) -> T; -} - -// workaround for Chalk assoc type normalization problems -pub struct S; -impl Iterator for S { - type Item = ::Item; -} - -fn test>>() { - let x: as Iterator>::Item; - x.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn inline_assoc_type_bounds_2() { - check_types( - r#" -trait Iterator { - type Item; -} - -fn test>>() { - let x: <::Item as Iterator>::Item; - x; -} //^ u32 -"#, - ); -} - -#[test] -fn proc_macro_server_types() { - check_infer( - r#" - macro_rules! with_api { - ($S:ident, $self:ident, $m:ident) => { - $m! { - TokenStream { - fn new() -> $S::TokenStream; - }, - Group { - }, - } - }; - } - macro_rules! associated_item { - (type TokenStream) => - (type TokenStream: 'static;); - (type Group) => - (type Group: 'static;); - ($($item:tt)*) => ($($item)*;) - } - macro_rules! declare_server_traits { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { - pub trait Types { - $(associated_item!(type $name);)* - } - - $(pub trait $name: Types { - $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* - })* - - pub trait Server: Types $(+ $name)* {} - impl Server for S {} - } - } - - with_api!(Self, self_, declare_server_traits); - struct G {} - struct T {} - struct Rustc; - impl Types for Rustc { - type TokenStream = T; - type Group = G; - } - - fn make() -> T { loop {} } - impl TokenStream for Rustc { - fn new() -> Self::TokenStream { - let group: Self::Group = make(); - make() - } - } - "#, - expect![[r#" - 1061..1072 '{ loop {} }': T - 1063..1070 'loop {}': ! - 1068..1070 '{}': () - 1136..1199 '{ ... }': T - 1150..1155 'group': G - 1171..1175 'make': fn make() -> G - 1171..1177 'make()': G - 1187..1191 'make': fn make() -> T - 1187..1193 'make()': T - "#]], - ); -} - -#[test] -fn unify_impl_trait() { - check_infer_with_mismatches( - r#" - trait Trait {} - - fn foo(x: impl Trait) { loop {} } - fn bar(x: impl Trait) -> T { loop {} } - - struct S(T); - impl Trait for S {} - - fn default() -> T { loop {} } - - fn test() -> impl Trait { - let s1 = S(default()); - foo(s1); - let x: i32 = bar(S(default())); - S(default()) - } - "#, - expect![[r#" - 26..27 'x': impl Trait - 46..57 '{ loop {} }': () - 48..55 'loop {}': ! - 53..55 '{}': () - 68..69 'x': impl Trait - 91..102 '{ loop {} }': T - 93..100 'loop {}': ! - 98..100 '{}': () - 171..182 '{ loop {} }': T - 173..180 'loop {}': ! - 178..180 '{}': () - 213..309 '{ ...t()) }': S<{unknown}> - 223..225 's1': S - 228..229 'S': S(u32) -> S - 228..240 'S(default())': S - 230..237 'default': fn default() -> u32 - 230..239 'default()': u32 - 246..249 'foo': fn foo(S) - 246..253 'foo(s1)': () - 250..252 's1': S - 263..264 'x': i32 - 272..275 'bar': fn bar(S) -> i32 - 272..289 'bar(S(...lt()))': i32 - 276..277 'S': S(i32) -> S - 276..288 'S(default())': S - 278..285 'default': fn default() -> i32 - 278..287 'default()': i32 - 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> - 295..307 'S(default())': S<{unknown}> - 297..304 'default': fn default<{unknown}>() -> {unknown} - 297..306 'default()': {unknown} - "#]], - ); -} - -#[test] -fn assoc_types_from_bounds() { - check_infer( - r#" - //- /main.rs - #[lang = "fn_once"] - trait FnOnce { - type Output; - } - - trait T { - type O; - } - - impl T for () { - type O = (); - } - - fn f(_v: F) - where - X: T, - F: FnOnce(&X::O), - { } - - fn main() { - f::<(), _>(|z| { z; }); - } - "#, - expect![[r#" - 133..135 '_v': F - 178..181 '{ }': () - 193..224 '{ ... }); }': () - 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) - 199..221 'f::<()... z; })': () - 210..220 '|z| { z; }': |&()| -> () - 211..212 'z': &() - 214..220 '{ z; }': () - 216..217 'z': &() - "#]], - ); -} - -#[test] -fn associated_type_bound() { - check_types( - r#" -pub trait Trait { - type Item: OtherTrait; -} -pub trait OtherTrait { - fn foo(&self) -> T; -} - -// this is just a workaround for chalk#234 -pub struct S; -impl Trait for S { - type Item = ::Item; -} - -fn test() { - let y: as Trait>::Item = no_matter; - y.foo(); -} //^ u32 -"#, - ); -} - -#[test] -fn dyn_trait_through_chalk() { - check_types( - r#" -struct Box {} -#[lang = "deref"] -trait Deref { - type Target; -} -impl Deref for Box { - type Target = T; -} -trait Trait { - fn foo(&self); -} - -fn test(x: Box) { - x.foo(); -} //^ () -"#, - ); -} - -#[test] -fn string_to_owned() { - check_types( - r#" -struct String {} -pub trait ToOwned { - type Owned; - fn to_owned(&self) -> Self::Owned; -} -impl ToOwned for str { - type Owned = String; -} -fn test() { - "foo".to_owned(); -} //^ String -"#, - ); -} - -#[test] -fn iterator_chain() { - check_infer( - r#" - //- /main.rs - #[lang = "fn_once"] - trait FnOnce { - type Output; - } - #[lang = "fn_mut"] - trait FnMut: FnOnce { } - - enum Option { Some(T), None } - use Option::*; - - pub trait Iterator { - type Item; - - fn filter_map(self, f: F) -> FilterMap - where - F: FnMut(Self::Item) -> Option, - { loop {} } - - fn for_each(self, f: F) - where - F: FnMut(Self::Item), - { loop {} } - } - - pub trait IntoIterator { - type Item; - type IntoIter: Iterator; - fn into_iter(self) -> Self::IntoIter; - } - - pub struct FilterMap { } - impl Iterator for FilterMap - where - F: FnMut(I::Item) -> Option, - { - type Item = B; - } - - #[stable(feature = "rust1", since = "1.0.0")] - impl IntoIterator for I { - type Item = I::Item; - type IntoIter = I; - - fn into_iter(self) -> I { - self - } - } - - struct Vec {} - impl Vec { - fn new() -> Self { loop {} } - } - - impl IntoIterator for Vec { - type Item = T; - type IntoIter = IntoIter; - } - - pub struct IntoIter { } - impl Iterator for IntoIter { - type Item = T; - } - - fn main() { - Vec::::new().into_iter() - .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) - .for_each(|y| { y; }); - } - "#, - expect![[r#" - 226..230 'self': Self - 232..233 'f': F - 317..328 '{ loop {} }': FilterMap - 319..326 'loop {}': ! - 324..326 '{}': () - 349..353 'self': Self - 355..356 'f': F - 405..416 '{ loop {} }': () - 407..414 'loop {}': ! - 412..414 '{}': () - 525..529 'self': Self - 854..858 'self': I - 865..885 '{ ... }': I - 875..879 'self': I - 944..955 '{ loop {} }': Vec - 946..953 'loop {}': ! - 951..953 '{}': () - 1142..1269 '{ ... }); }': () - 1148..1163 'Vec::::new': fn new() -> Vec - 1148..1165 'Vec::<...:new()': Vec - 1148..1177 'Vec::<...iter()': IntoIter - 1148..1240 'Vec::<...one })': FilterMap, |i32| -> Option> - 1148..1266 'Vec::<... y; })': () - 1194..1239 '|x| if...None }': |i32| -> Option - 1195..1196 'x': i32 - 1198..1239 'if x >...None }': Option - 1201..1202 'x': i32 - 1201..1206 'x > 0': bool - 1205..1206 '0': i32 - 1207..1225 '{ Some...u32) }': Option - 1209..1213 'Some': Some(u32) -> Option - 1209..1223 'Some(x as u32)': Option - 1214..1215 'x': i32 - 1214..1222 'x as u32': u32 - 1231..1239 '{ None }': Option - 1233..1237 'None': Option - 1255..1265 '|y| { y; }': |u32| -> () - 1256..1257 'y': u32 - 1259..1265 '{ y; }': () - 1261..1262 'y': u32 - "#]], - ); -} - -#[test] -fn nested_assoc() { - check_types( - r#" -struct Bar; -struct Foo; - -trait A { - type OutputA; -} - -impl A for Bar { - type OutputA = Foo; -} - -trait B { - type Output; - fn foo() -> Self::Output; -} - -impl B for T { - type Output = T::OutputA; - fn foo() -> Self::Output { loop {} } -} - -fn main() { - Bar::foo(); -} //^ Foo -"#, - ); -} - -#[test] -fn trait_object_no_coercion() { - check_infer_with_mismatches( - r#" - trait Foo {} - - fn foo(x: &dyn Foo) {} - - fn test(x: &dyn Foo) { - foo(x); - } - "#, - expect![[r#" - 21..22 'x': &dyn Foo - 34..36 '{}': () - 46..47 'x': &dyn Foo - 59..74 '{ foo(x); }': () - 65..68 'foo': fn foo(&dyn Foo) - 65..71 'foo(x)': () - 69..70 'x': &dyn Foo - "#]], - ); -} - -#[test] -fn builtin_copy() { - check_infer_with_mismatches( - r#" - #[lang = "copy"] - trait Copy {} - - struct IsCopy; - impl Copy for IsCopy {} - struct NotCopy; - - trait Test { fn test(&self) -> bool; } - impl Test for T {} - - fn test() { - IsCopy.test(); - NotCopy.test(); - (IsCopy, IsCopy).test(); - (IsCopy, NotCopy).test(); - } - "#, - expect![[r#" - 110..114 'self': &Self - 166..267 '{ ...t(); }': () - 172..178 'IsCopy': IsCopy - 172..185 'IsCopy.test()': bool - 191..198 'NotCopy': NotCopy - 191..205 'NotCopy.test()': {unknown} - 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) - 211..234 '(IsCop...test()': bool - 212..218 'IsCopy': IsCopy - 220..226 'IsCopy': IsCopy - 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) - 240..264 '(IsCop...test()': {unknown} - 241..247 'IsCopy': IsCopy - 249..256 'NotCopy': NotCopy - "#]], - ); -} - -#[test] -fn builtin_fn_def_copy() { - check_infer_with_mismatches( - r#" - #[lang = "copy"] - trait Copy {} - - fn foo() {} - fn bar(T) -> T {} - struct Struct(usize); - enum Enum { Variant(usize) } - - trait Test { fn test(&self) -> bool; } - impl Test for T {} - - fn test() { - foo.test(); - bar.test(); - Struct.test(); - Enum::Variant.test(); - } - "#, - expect![[r#" - 41..43 '{}': () - 60..61 'T': {unknown} - 68..70 '{}': () - 68..70: expected T, got () - 145..149 'self': &Self - 201..281 '{ ...t(); }': () - 207..210 'foo': fn foo() - 207..217 'foo.test()': bool - 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} - 223..233 'bar.test()': bool - 239..245 'Struct': Struct(usize) -> Struct - 239..252 'Struct.test()': bool - 258..271 'Enum::Variant': Variant(usize) -> Enum - 258..278 'Enum::...test()': bool - "#]], - ); -} - -#[test] -fn builtin_fn_ptr_copy() { - check_infer_with_mismatches( - r#" - #[lang = "copy"] - trait Copy {} - - trait Test { fn test(&self) -> bool; } - impl Test for T {} - - fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { - f1.test(); - f2.test(); - f3.test(); - } - "#, - expect![[r#" - 54..58 'self': &Self - 108..110 'f1': fn() - 118..120 'f2': fn(usize) -> u8 - 139..141 'f3': fn(u8, u8) -> &u8 - 162..210 '{ ...t(); }': () - 168..170 'f1': fn() - 168..177 'f1.test()': bool - 183..185 'f2': fn(usize) -> u8 - 183..192 'f2.test()': bool - 198..200 'f3': fn(u8, u8) -> &u8 - 198..207 'f3.test()': bool - "#]], - ); -} - -#[test] -fn builtin_sized() { - check_infer_with_mismatches( - r#" - #[lang = "sized"] - trait Sized {} - - trait Test { fn test(&self) -> bool; } - impl Test for T {} - - fn test() { - 1u8.test(); - (*"foo").test(); // not Sized - (1u8, 1u8).test(); - (1u8, *"foo").test(); // not Sized - } - "#, - expect![[r#" - 56..60 'self': &Self - 113..228 '{ ...ized }': () - 119..122 '1u8': u8 - 119..129 '1u8.test()': bool - 135..150 '(*"foo").test()': {unknown} - 136..142 '*"foo"': str - 137..142 '"foo"': &str - 169..179 '(1u8, 1u8)': (u8, u8) - 169..186 '(1u8, ...test()': bool - 170..173 '1u8': u8 - 175..178 '1u8': u8 - 192..205 '(1u8, *"foo")': (u8, str) - 192..212 '(1u8, ...test()': {unknown} - 193..196 '1u8': u8 - 198..204 '*"foo"': str - 199..204 '"foo"': &str - "#]], - ); -} - -#[test] -fn integer_range_iterate() { - check_types( - r#" -//- /main.rs crate:main deps:core -fn test() { - for x in 0..100 { x; } -} //^ i32 - -//- /core.rs crate:core -pub mod ops { - pub struct Range { - pub start: Idx, - pub end: Idx, - } -} - -pub mod iter { - pub trait Iterator { - type Item; - } - - pub trait IntoIterator { - type Item; - type IntoIter: Iterator; - } - - impl IntoIterator for T where T: Iterator { - type Item = ::Item; - type IntoIter = Self; - } -} - -trait Step {} -impl Step for i32 {} -impl Step for i64 {} - -impl iter::Iterator for ops::Range { - type Item = A; -} -"#, - ); -} - -#[test] -fn infer_closure_arg() { - check_infer( - r#" - //- /lib.rs - - enum Option { - None, - Some(T) - } - - fn foo() { - let s = Option::None; - let f = |x: Option| {}; - (&f)(s) - } - "#, - expect![[r#" - 52..126 '{ ...)(s) }': () - 62..63 's': Option - 66..78 'Option::None': Option - 88..89 'f': |Option| -> () - 92..111 '|x: Op...2>| {}': |Option| -> () - 93..94 'x': Option - 109..111 '{}': () - 117..124 '(&f)(s)': () - 118..120 '&f': &|Option| -> () - 119..120 'f': |Option| -> () - 122..123 's': Option - "#]], - ); -} - -#[test] -fn infer_fn_trait_arg() { - check_infer( - r#" - //- /lib.rs deps:std - - #[lang = "fn_once"] - pub trait FnOnce { - type Output; - - extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; - } - - #[lang = "fn"] - pub trait Fn:FnOnce { - extern "rust-call" fn call(&self, args: Args) -> Self::Output; - } - - enum Option { - None, - Some(T) - } - - fn foo(f: F) -> T - where - F: Fn(Option) -> T, - { - let s = None; - f(s) - } - "#, - expect![[r#" - 101..105 'self': &Self - 107..111 'args': Args - 220..224 'self': &Self - 226..230 'args': Args - 313..314 'f': F - 359..389 '{ ...f(s) }': T - 369..370 's': Option - 373..377 'None': Option - 383..384 'f': F - 383..387 'f(s)': T - 385..386 's': Option - "#]], - ); -} - -#[test] -fn infer_box_fn_arg() { - check_infer( - r#" - //- /lib.rs deps:std - - #[lang = "fn_once"] - pub trait FnOnce { - type Output; - - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; - } - - #[lang = "deref"] - pub trait Deref { - type Target: ?Sized; - - fn deref(&self) -> &Self::Target; - } - - #[lang = "owned_box"] - pub struct Box { - inner: *mut T, - } - - impl Deref for Box { - type Target = T; - - fn deref(&self) -> &T { - &self.inner - } - } - - enum Option { - None, - Some(T) - } - - fn foo() { - let s = Option::None; - let f: Box)> = box (|ps| {}); - f(&s) - } - "#, - expect![[r#" - 100..104 'self': Self - 106..110 'args': Args - 214..218 'self': &Self - 384..388 'self': &Box - 396..423 '{ ... }': &T - 406..417 '&self.inner': &*mut T - 407..411 'self': &Box - 407..417 'self.inner': *mut T - 478..575 '{ ...(&s) }': FnOnce::Output,)>, (&Option,)> - 488..489 's': Option - 492..504 'Option::None': Option - 514..515 'f': Box,)>> - 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> - 554..561 '|ps| {}': |{unknown}| -> () - 555..557 'ps': {unknown} - 559..561 '{}': () - 568..569 'f': Box,)>> - 568..573 'f(&s)': FnOnce::Output,)>, (&Option,)> - 570..572 '&s': &Option - 571..572 's': Option - "#]], - ); -} - -#[test] -fn infer_dyn_fn_output() { - check_types( - r#" -#[lang = "fn_once"] -pub trait FnOnce { - type Output; - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - -#[lang = "fn"] -pub trait Fn: FnOnce { - extern "rust-call" fn call(&self, args: Args) -> Self::Output; -} - -fn foo() { - let f: &dyn Fn() -> i32; - f(); - //^^^ i32 -}"#, - ); -} - -#[test] -fn infer_dyn_fn_once_output() { - check_types( - r#" -#[lang = "fn_once"] -pub trait FnOnce { - type Output; - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - -fn foo() { - let f: dyn FnOnce() -> i32; - f(); - //^^^ i32 -}"#, - ); -} - -#[test] -fn variable_kinds_1() { - check_types( - r#" -trait Trait { fn get(self, t: T) -> T; } -struct S; -impl Trait for S {} -impl Trait for S {} -fn test() { - S.get(1); - //^^^^^^^^ u128 - S.get(1.); - //^^^^^^^^ f32 -} - "#, - ); -} - -#[test] -fn variable_kinds_2() { - check_types( - r#" -trait Trait { fn get(self) -> Self; } -impl Trait for u128 {} -impl Trait for f32 {} -fn test() { - 1.get(); - //^^^^^^^ u128 - (1.).get(); - //^^^^^^^^^^ f32 -} - "#, - ); -} - -#[test] -fn underscore_import() { - check_types( - r#" -mod tr { - pub trait Tr { - fn method(&self) -> u8 { 0 } - } -} - -struct Tr; -impl crate::tr::Tr for Tr {} - -use crate::tr::Tr as _; -fn test() { - Tr.method(); - //^^^^^^^^^^^ u8 -} - "#, - ); -} -- cgit v1.2.3