mod new_solver; use expect_test::expect; use super::{check_infer, check_no_mismatches, 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() { // FIXME: This isn't nice, but I guess as long as we don't hang/crash that's fine? 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}; 2] 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}); 2] 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 array_elements_expected_type() { check_no_mismatches( r#" fn test() { let x: [[u32; 2]; 2] = [[1, 2], [3, 4]]; } "#, ); } #[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() { // 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; 4] 29..49 '[0, b'...b'\n']': [u8; 4] 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#" //- minicore: iterator 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... }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter 32..320 'for co... }': <{unknown} as IntoIterator>::IntoIter 32..320 'for co... }': ! 32..320 'for co... }': {unknown} 32..320 'for co... }': &'? mut {unknown} 32..320 'for co... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 32..320 'for co... }': Option<<{unknown} as Iterator>::Item> 32..320 'for co... }': () 32..320 'for co... }': () 32..320 'for co... }': () 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 infer_array_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; 1] 58..66 '[bar!()]': [u32; 1] "#]], ); } #[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 '{}': HashSet 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(T); trait D { fn foo(); } impl D for Response { fn foo() { end(); fn end() { let _x: T = loop {}; } } } "#, expect![[r#" 120..215 '{ ... }': () 130..133 'end': fn end<{unknown}>() 130..135 'end()': () 164..209 '{ ... }': () 182..184 '_x': ! 191..198 'loop {}': ! 196..198 '{}': () "#]], ) } #[test] fn issue_2705() { check_infer( r#" trait Trait {} fn test() { >::foo() } "#, expect![[r#" 25..52 '{ ...oo() }': () 31..48 '::foo': {unknown} 31..50 ' {} impl<'a> Iterator for Chars<'a> { type Item = char; fn next(&mut self) -> Option { loop {} } } fn test() { let chars: Chars<'_>; (chars.next(), chars.nth(1)); } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (Option, Option) "#, ); } #[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_6811() { check_infer( r#" macro_rules! profile_function { () => { let _a = 1; let _b = 1; }; } fn main() { profile_function!(); } "#, expect![[r#" !3..5 '_a': i32 !6..7 '1': i32 !11..13 '_b': i32 !14..15 '1': i32 103..131 '{ ...!(); }': () "#]], ); } #[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 '{ ... }': {unknown} 498..502 'self': SelectStatement 498..508 'self.order': O 498..515 'self.o...into()': dyn QueryFragment + 'static "#]], ); } #[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': fn 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': fn 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#" //- minicore: coerce_unsized, future use core::future::Future; 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#" 70..73 'key': &'? K 132..148 '{ ...key) }': impl Future>::Bar> 138..141 'bar': fn bar(&'? K) -> impl Future>::Bar> 138..146 'bar(key)': impl Future>::Bar> 142..145 'key': &'? K 162..165 'key': &'? K 224..227 '{ }': () "#]], ); } #[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 + 'static 411..418 'loop {}': ! 416..418 '{}': () 575..579 'self': &'? mut Self "#]], ); } // FIXME(next-solver): Though `Repeat: IntoIterator` does not hold here, we // should be able to do better at given type hints (with Chalk, we did `IntoIterator::Item>`) // From what I can tell, the point of this test is to not panic though. #[test] fn issue_4966() { check_infer( r#" //- minicore: deref pub trait IntoIterator { type Item; } struct Repeat { element: A } struct Map { f: F } struct Vec { p: *mut T } impl core::ops::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#" 236..240 'iter': T 255..257 '{}': Vec 269..413 '{ ...r(); }': () 279..284 'inner': Map f64> 287..311 'Map { ... 0.0 }': Map f64> 296..309 '|_: &f64| 0.0': impl Fn(&'? f64) -> f64 297..298 '_': &'? f64 306..309 '0.0': f64 322..328 'repeat': Repeat f64>> 331..356 'Repeat...nner }': Repeat f64>> 349..354 'inner': Map f64> 367..370 'vec': Vec<{unknown}> 373..382 'from_iter': fn from_iter<{unknown}, Repeat f64>>>(Repeat f64>>) -> Vec<{unknown}> 373..390 'from_i...epeat)': Vec<{unknown}> 383..389 'repeat': Repeat f64>> 397..400 'vec': Vec<{unknown}> 397..410 'vec.foo_bar()': {unknown} "#]], ); } #[test] fn issue_6628() { check_infer( r#" //- minicore: fn, phantom_data use core::marker::PhantomData; struct S(PhantomData); impl S { fn f(&self, _t: T) {} fn g(&self, _f: F) {} } fn main() { let s = S(PhantomData); s.g(|_x| {}); s.f(10); } "#, expect![[r#" 86..90 'self': &'? S 92..94 '_t': T 99..101 '{}': () 127..131 'self': &'? S 133..135 '_f': F 140..142 '{}': () 155..217 '{ ...10); }': () 165..166 's': S 169..170 'S': fn S(PhantomData) -> S 169..183 'S(PhantomData)': S 171..182 'PhantomData': PhantomData 189..190 's': S 189..201 's.g(|_x| {})': () 193..200 '|_x| {}': impl FnOnce(&'? i32) 194..196 '_x': &'? i32 198..200 '{}': () 207..208 's': S 207..214 's.f(10)': () 211..213 '10': i32 "#]], ); } #[test] fn issue_6852() { check_infer( r#" //- minicore: deref use core::ops::Deref; struct BufWriter {} struct Mutex(T); struct MutexGuard<'a, T>(&'a T); impl Mutex { fn lock(&self) -> MutexGuard<'_, T> {} } impl<'a, T: 'a> Deref for MutexGuard<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { loop {} } } fn flush(&self) { let w: &Mutex; *(w.lock()); } "#, expect![[r#" 129..133 'self': &'? Mutex 156..158 '{}': MutexGuard<'?, T> 242..246 'self': &'? MutexGuard<'a, T> 265..276 '{ loop {} }': &'? T 267..274 'loop {}': ! 272..274 '{}': () 289..293 'self': &'? {unknown} 295..345 '{ ...()); }': () 305..306 'w': &'? Mutex 331..342 '*(w.lock())': BufWriter 333..334 'w': &'? Mutex 333..341 'w.lock()': MutexGuard<'?, BufWriter> "#]], ); } #[test] fn param_overrides_fn() { check_types( r#" fn example(example: i32) { fn f() {} example; //^^^^^^^ i32 } "#, ) } #[test] fn lifetime_from_chalk_during_deref() { check_types( r#" //- minicore: deref struct Box(T); impl core::ops::Deref for Box { type Target = T; fn deref(&self) -> &Self::Target { loop {} } } trait Iterator { type Item; } pub struct Iter<'a, T: 'a> { inner: Box + 'a>, } trait IterTrait<'a, T: 'a>: Iterator { fn clone_box(&self); } fn clone_iter(s: Iter) { s.inner.clone_box(); //^^^^^^^^^^^^^^^^^^^ () } "#, ) } #[test] fn issue_8686() { check_infer( r#" //- minicore: phantom_data use core::marker::PhantomData; pub trait Try: FromResidual { type Output; type Residual; } pub trait FromResidual::Residual> { fn from_residual(residual: R) -> Self; } struct ControlFlow(PhantomData<(B, C)>); impl Try for ControlFlow { type Output = C; type Residual = ControlFlow; } impl FromResidual for ControlFlow { fn from_residual(r: ControlFlow) -> Self { ControlFlow(PhantomData) } } fn test() { ControlFlow::from_residual(ControlFlow::(PhantomData)); } "#, expect![[r#" 176..184 'residual': R 418..419 'r': ControlFlow 448..476 '{ Cont...ata) }': ControlFlow 450..461 'ControlFlow': fn ControlFlow(PhantomData<(B, C)>) -> ControlFlow 450..474 'Contro...mData)': ControlFlow 462..473 'PhantomData': PhantomData<(B, C)> 490..561 '{ ...a)); }': () 496..522 'Contro...sidual': fn from_residual, ControlFlow>(ControlFlow) -> ControlFlow 496..558 'Contro...Data))': ControlFlow 523..544 'Contro...32, !>': fn ControlFlow(PhantomData<(u32, !)>) -> ControlFlow 523..557 'Contro...mData)': ControlFlow 545..556 'PhantomData': PhantomData<(u32, !)> "#]], ); } #[test] fn cfg_tail() { // https://github.com/rust-lang/rust-analyzer/issues/8378 check_infer( r#" fn fake_tail(){ { "first" } #[cfg(never)] 9 } fn multiple_fake(){ { "fake" } { "fake" } { "second" } #[cfg(never)] { 11 } #[cfg(never)] 12; #[cfg(never)] 13 } fn no_normal_tail(){ { "third" } #[cfg(never)] 14; #[cfg(never)] 15; } fn no_actual_tail(){ { "fourth" }; #[cfg(never)] 14; #[cfg(never)] 15 } "#, expect![[r#" 14..53 '{ ...)] 9 }': () 20..31 '{ "first" }': () 22..29 '"first"': &'static str 72..190 '{ ...] 13 }': () 78..88 '{ "fake" }': () 80..86 '"fake"': &'static str 93..103 '{ "fake" }': () 95..101 '"fake"': &'static str 108..120 '{ "second" }': () 110..118 '"second"': &'static str 210..273 '{ ... 15; }': () 216..227 '{ "third" }': () 218..225 '"third"': &'static str 293..357 '{ ...] 15 }': () 299..311 '{ "fourth" }': &'static str 301..309 '"fourth"': &'static str "#]], ) } #[test] fn impl_trait_in_option_9530() { check_types( r#" //- minicore: sized struct Option(T); impl Option { fn unwrap(self) -> T { loop {} } } fn make() -> Option { Option(()) } trait Copy {} impl Copy for () {} fn test() { let o = make(); o.unwrap(); //^^^^^^^^^^ impl Copy } "#, ) } #[test] fn bare_dyn_trait_binders_9639() { check_no_mismatches( r#" //- minicore: fn, coerce_unsized, dispatch_from_dyn fn infix_parse(_state: S, _level_code: &Fn(S)) -> T { loop {} } fn parse_a_rule() { infix_parse((), &(|_recurse| ())) } "#, ) } #[test] fn nested_closure() { check_types( r#" //- minicore: fn, option fn map(o: Option, f: impl FnOnce(T) -> U) -> Option { loop {} } fn test() { let o = Some(Some(2)); map(o, |s| map(s, |x| x)); // ^ i32 } "#, ); } #[test] fn call_expected_type_closure() { check_types( r#" //- minicore: fn, option fn map(o: Option, f: impl FnOnce(T) -> U) -> Option { loop {} } struct S { field: u32 } fn test() { let o = Some(S { field: 2 }); let _: Option<()> = map(o, |s| { s.field; }); // ^^^^^^^ u32 } "#, ); } #[test] fn coerce_diesel_panic() { check_no_mismatches( r#" //- minicore: option trait TypeMetadata { type MetadataLookup; } pub struct Output<'a, T, DB> where DB: TypeMetadata, DB::MetadataLookup: 'a, { out: T, metadata_lookup: Option<&'a DB::MetadataLookup>, } impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> { pub fn new(out: T, metadata_lookup: &'a DB::MetadataLookup) -> Self { Output { out, metadata_lookup: Some(metadata_lookup), } } } "#, ); } #[test] fn bitslice_panic() { check_no_mismatches( r#" //- minicore: option, deref pub trait BitView { type Store; } pub struct Lsb0; pub struct BitArray(V); pub struct BitSlice(T); impl core::ops::Deref for BitArray { type Target = BitSlice; } impl BitSlice { pub fn split_first(&self) -> Option<(T, &Self)> { loop {} } } fn multiexp_inner() { let exp: &BitArray; exp.split_first(); } "#, ); } #[test] fn macro_expands_to_impl_trait() { check_no_mismatches( r#" trait Foo {} macro_rules! ty { () => { impl Foo } } fn foo(_: ty!()) {} fn bar() { foo(()); } "#, ) } #[test] fn nested_macro_in_fn_params() { check_no_mismatches( r#" macro_rules! U32Inner { () => { u32 }; } macro_rules! U32 { () => { U32Inner!() }; } fn mamba(a: U32!(), p: u32) -> u32 { a } "#, ) } #[test] fn for_loop_block_expr_iterable() { // FIXME(next-solver): it would be nice to be able to hint `IntoIterator::IntoIter<()>` instead of just `{unknown}` // (even though `(): IntoIterator` does not hold) check_infer( r#" //- minicore: iterator fn test() { for _ in { let x = 0; } { let y = 0; } } "#, expect![[r#" 10..68 '{ ... } }': () 16..66 'for _ ... }': fn into_iter<()>(()) -> <() as IntoIterator>::IntoIter 16..66 'for _ ... }': <() as IntoIterator>::IntoIter 16..66 'for _ ... }': ! 16..66 'for _ ... }': {unknown} 16..66 'for _ ... }': &'? mut {unknown} 16..66 'for _ ... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 16..66 'for _ ... }': Option<<{unknown} as Iterator>::Item> 16..66 'for _ ... }': () 16..66 'for _ ... }': () 16..66 'for _ ... }': () 16..66 'for _ ... }': () 20..21 '_': {unknown} 25..39 '{ let x = 0; }': () 31..32 'x': i32 35..36 '0': i32 40..66 '{ ... }': () 54..55 'y': i32 58..59 '0': i32 "#]], ); } #[test] fn while_loop_block_expr_iterable() { check_infer( r#" fn test() { while { true } { let y = 0; } } "#, expect![[r#" 10..59 '{ ... } }': () 16..57 'while ... }': ! 16..57 'while ... }': () 16..57 'while ... }': () 22..30 '{ true }': bool 24..28 'true': bool 31..57 '{ ... }': () 45..46 'y': i32 49..50 '0': i32 "#]], ); } #[test] fn bug_11242() { check_types( r#" fn foo() where A: IntoIterator, B: IntoIterator, { let _x: ::Item; // ^^ u32 } pub trait Iterator { type Item; } pub trait IntoIterator { type Item; type IntoIter: Iterator; } impl IntoIterator for I { type Item = I::Item; type IntoIter = I; } "#, ); } #[test] fn bug_11659() { check_no_mismatches( r#" struct LinkArray(LD); fn f(x: LD) -> LinkArray { let r = LinkArray::(x); r } fn test() { let x = f::<2, i32>(5); let y = LinkArray::<52, LinkArray<2, i32>>(x); } "#, ); check_no_mismatches( r#" struct LinkArray(LD); fn f(x: LD) -> LinkArray { let r = LinkArray::(x); r } fn test() { let x = f::(5); let y = LinkArray::, 52>(x); } "#, ); } #[test] fn const_generic_error_tolerance() { check_no_mismatches( r#" #[lang = "sized"] pub trait Sized {} struct CT(T); struct TC(T); fn f(x: T) -> (CT, TC) { let l = CT::(x); let r = TC::(x); (l, r) } trait TR1; trait TR2; impl TR1 for CT; impl TR1<5> for TC; impl TR2 for CT; trait TR3 { fn tr3(&self) -> &Self; } impl TR3<5> for TC { fn tr3(&self) -> &Self { self } } impl TR3 for TC {} impl TR3 for TC {} fn impl_trait(inp: impl TR1) {} fn dyn_trait(inp: &dyn TR2) {} fn impl_trait_bad<'a, const N: usize>(inp: impl TR1) -> impl TR1<'a, i32> {} fn impl_trait_very_bad(inp: impl TR1) -> impl TR1<'a, Item = i32, 5, Foo = N> {} fn test() { f::<2, i32>(5); f::<2, 2>(5); f(5); f::(5); CT::<52, CT<2, i32>>(x); CT::>(x); impl_trait_bad(5); impl_trait_bad(12); TR3<5>::tr3(); TR3<{ 2+3 }>::tr3(); TC::(5).tr3(); TC::(5).tr3(); TC::(5).tr3(); TC::(5).tr3(); } "#, ); } #[test] fn const_generic_impl_trait() { check_no_mismatches( r#" //- minicore: from struct Foo; trait Tr { fn f(T) -> Self; } impl Tr<[T; M]> for Foo { fn f(_: [T; M]) -> Self { Self } } fn test() { Foo::f([1, 2, 7, 10]); } "#, ); } #[test] fn nalgebra_factorial() { check_no_mismatches( r#" const FACTORIAL: [u128; 4] = [1, 1, 2, 6]; fn factorial(n: usize) -> u128 { match FACTORIAL.get(n) { Some(f) => *f, None => panic!("{}! is greater than u128::MAX", n), } } "#, ) } #[test] fn regression_11688_1() { check_no_mismatches( r#" pub struct Buffer(T); type Writer = Buffer; impl Buffer { fn extend_from_array(&mut self, xs: &[T; N]) { loop {} } } trait Encode { fn encode(self, w: &mut Writer, s: &mut S); } impl Encode for u8 { fn encode(self, w: &mut Writer, _: &mut S) { w.extend_from_array(&self.to_le_bytes()); } } "#, ); } #[test] fn regression_11688_2() { check_types( r#" union MaybeUninit { uninit: (), value: T, } impl MaybeUninit { fn uninit_array() -> [Self; LEN] { loop {} } } fn main() { let x = MaybeUninit::::uninit_array::<1>(); //^ [MaybeUninit; 1] } "#, ); } #[test] fn regression_11688_3() { check_types( r#" //- minicore: iterator, dispatch_from_dyn struct Ar(T); fn f( num_zeros: usize, ) -> &dyn Iterator; LEN]> { loop {} } fn dynamic_programming() { let board = f::<9, u8, 7>(1).next(); //^^^^^ Option<[Ar; 9]> } "#, ); } #[test] fn regression_11688_4() { check_types( r#" //- minicore: dispatch_from_dyn trait Bar { fn baz(&self) -> [i32; C]; } fn foo(x: &dyn Bar<2>) { x.baz(); //^^^^^^^ [i32; 2] } "#, ) } #[test] fn gat_crash_1() { check_no_mismatches( r#" trait ATrait {} trait Crash { type Member: ATrait; fn new() -> Self::Member; } fn test() { T::new(); } "#, ); } #[test] fn gat_crash_2() { check_no_mismatches( r#" pub struct InlineStorage {} pub struct InlineStorageHandle {} pub unsafe trait Storage { type Handle; fn create() -> Self::Handle; } unsafe impl Storage for InlineStorage { type Handle = InlineStorageHandle; } "#, ); } #[test] fn gat_crash_3() { check_no_mismatches( r#" trait Collection { type Item; type Member: Collection; fn add(&mut self, value: Self::Item) -> Result<(), Self::Error>; } struct ConstGen { data: [T; N], } impl Collection for ConstGen { type Item = T; type Member = ConstGen; } "#, ); } #[test] fn tuple_struct_pattern_with_unmatched_args_crash() { check_infer( r#" struct S(usize); fn main() { let S(.., a, b) = S(1); let (.., a, b) = (1,); } "#, expect![[r#" 27..85 '{ ...1,); }': () 37..48 'S(.., a, b)': S 43..44 'a': usize 46..47 'b': {unknown} 51..52 'S': fn S(usize) -> S 51..55 'S(1)': S 53..54 '1': usize 65..75 '(.., a, b)': (i32, {unknown}) 70..71 'a': i32 73..74 'b': {unknown} 78..82 '(1,)': (i32,) 79..80 '1': i32 "#]], ); } #[test] fn trailing_empty_macro() { check_no_mismatches( r#" macro_rules! m2 { ($($t:tt)*) => {$($t)*}; } fn macrostmts() -> u8 { m2! { 0 } m2! {} } "#, ); } #[test] fn dyn_with_unresolved_trait() { check_types( r#" fn foo(a: &dyn DoesNotExist) { a.bar(); //^&'? {unknown} } "#, ); } #[test] fn self_assoc_with_const_generics_crash() { check_no_mismatches( r#" trait Trait { type Item; } impl Trait for [T; N] { type Item = (); fn f(_: Self::Item) {} } "#, ); } #[test] fn unsize_array_with_inference_variable() { check_types( r#" //- minicore: try, slice use core::ops::ControlFlow; fn foo() -> ControlFlow<(), [usize; 1]> { loop {} } fn bar() -> ControlFlow<(), ()> { let a = foo()?.len(); //^ usize ControlFlow::Continue(()) } "#, ); } #[test] fn assoc_type_shorthand_with_gats_in_binders() { // c.f. test `issue_4885()` check_no_mismatches( r#" trait Gats { type Assoc; } trait Foo {} struct Bar<'a, B: Gats, A> { field: &'a dyn Foo>, } fn foo(b: Bar) { let _ = b.field; } "#, ); } #[test] fn regression_14305() { check_no_mismatches( r#" //- minicore: add trait Tr {} impl Tr for [u8; C] {} const C: usize = 2 + 2; "#, ); } #[test] fn regression_14456() { check_types( r#" //- minicore: future async fn x() {} fn f() { let fut = x(); let t = [0u8; { let a = 2 + 2; a }]; //^ [u8; 4] } "#, ); } #[test] fn regression_14164() { check_types( r#" trait Rec { type K; type Rebind: Rec; } trait Expr { type Part: Rec; fn foo(_: ::Rebind) {} } struct Head(K); impl Rec for Head { type K = K; type Rebind = Head; } fn test() where E: Expr>, { let head; //^^^^ Head E::foo(head); } "#, ); } #[test] fn match_ergonomics_with_binding_modes_interaction() { check_types( r" enum E { A } fn foo() { match &E::A { b @ (x @ E::A | x) => { b; //^ &'? E x; //^ &'? E } } }", ); } #[test] fn regression_14844() { check_no_mismatches( r#" pub type Ty = Unknown; pub struct Inner(T); pub struct Outer { pub inner: Inner, } fn main() { _ = Outer { inner: Inner::(0), }; } "#, ); check_no_mismatches( r#" pub const ONE: usize = 1; pub struct Inner(); pub struct Outer { pub inner: Inner, } fn main() { _ = Outer { inner: Inner::<1>(), }; } "#, ); check_no_mismatches( r#" pub const ONE: usize = unknown(); pub struct Inner(); pub struct Outer { pub inner: Inner, } fn main() { _ = Outer { inner: Inner::<1>(), }; } "#, ); check_no_mismatches( r#" pub const N: usize = 2 + 2; fn f(t: [u8; N]) {} fn main() { let a = [1, 2, 3, 4]; f(a); let b = [1; 4]; let c: [u8; N] = b; let d = [1; N]; let e: [u8; N] = d; let f = [1; N]; let g = match f { [a, b, c, d] => a + b + c + d, }; } "#, ); } #[test] fn regression_14844_2() { check_no_mismatches( r#" //- minicore: fn pub const ONE: usize = 1; pub type MyInner = Inner; pub struct Inner(); impl Inner<1> { fn map(&self, func: F) -> bool where F: Fn(&MyInner) -> bool, { func(self) } } "#, ); } #[test] fn dont_crash_on_slice_unsizing() { check_no_mismatches( r#" //- minicore: slice, unsize, coerce_unsized trait Tr { fn f(self); } impl Tr for [i32] { fn f(self) { let t; x(t); } } fn x(a: [i32; 4]) { let b = a.f(); } "#, ); } #[test] fn dont_unify_on_casts() { // #15246 check_types( r#" //- minicore: sized fn unify(_: [bool; 1]) {} fn casted(_: *const bool) {} fn default() -> T { loop {} } fn test() { let foo = default(); //^^^ [bool; 1] casted(&foo as *const _); unify(foo); } "#, ); } #[test] fn rustc_test_issue_52437() { check_types( r#" //- minicore: sized fn main() { let x = [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //^ [(); _] } "#, ); } #[test] fn incorrect_variant_form_through_alias_caught() { check_types( r#" enum Enum { Braced {}, Unit, Tuple() } type Alias = Enum; fn main() { Alias::Braced; //^^^^^^^^^^^^^ {unknown} let Alias::Braced = loop {}; //^^^^^^^^^^^^^ ! let Alias::Braced(..) = loop {}; //^^^^^^^^^^^^^^^^^ Enum Alias::Unit(); //^^^^^^^^^^^^^ {unknown} Alias::Unit{}; //^^^^^^^^^^^^^ Enum let Alias::Unit() = loop {}; //^^^^^^^^^^^^^ Enum let Alias::Unit{} = loop {}; //^^^^^^^^^^^^^ Enum } "#, ) } #[test] fn cfg_first_trait_param_16141() { check_no_mismatches( r#" //- minicore: sized, coerce_unsized trait Bar { fn bar(&self) {} } impl<#[cfg(feature = "a-feature")] A> Bar for (){} "#, ) } #[test] fn nested_anon_generics_and_where_bounds_17173() { check_types( r#" //- minicore: sized, fn pub trait Lookup { type Data; fn lookup(&self) -> Self::Data; } pub trait ItemTreeLoc { type Id; } fn id_to_generics(id: impl Lookup>, //^^ impl Lookup> enabled_params: impl Fn(), //^^^^^^^^^^^^^^ impl Fn() ) where (): Sized, {} "#, ); } #[test] fn tait_async_stack_overflow_17199() { check_types( r#" //- minicore: fmt, future type Foo = impl core::fmt::Debug; async fn foo() -> Foo { () } async fn test() { let t = foo().await; // ^ impl Debug } "#, ); } #[test] fn lifetime_params_move_param_defaults() { check_types( r#" pub struct Thing<'s, T = u32>(&'s T); impl <'s> Thing<'s> { pub fn new() -> Thing<'s> { Thing(&0) //^^^^^^^^^ Thing<'?, u32> } } fn main() { let scope = //^^^^^ &'? Thing<'?, u32> &Thing::new(); //^^^^^^^^^^^^ Thing<'?, u32> } "#, ); } #[test] fn issue_17734() { check_types( r#" fn test() { let x = S::foo::<'static, &()>(&S); // ^ Wrap<'?, ()> let x = S::foo::<&()>(&S); // ^ Wrap<'?, ()> let x = S.foo::<'static, &()>(); // ^ Wrap<'?, ()> let x = S.foo::<&()>(); // ^ Wrap<'?, ()> } struct S; impl S { pub fn foo<'a, T: Trait<'a>>(&'a self) -> T::Proj { loop {} } } struct Wrap<'a, T>(&'a T); trait Trait<'a> { type Proj; } impl<'a, T> Trait<'a> for &'a T { type Proj = Wrap<'a, T>; } "#, ) } #[test] fn issue_17738() { check_types( r#" //- minicore: index use core::ops::{Index, IndexMut}; struct Foo(K, V); struct Bar; impl Bar { fn bar(&mut self) {} } impl Foo { fn new(_v: V) -> Self { loop {} } } impl Index for Foo { type Output = V; fn index(&self, _index: B) -> &Self::Output { loop {} } } impl IndexMut for Foo { fn index_mut(&mut self, _index: K) -> &mut Self::Output { loop {} } } fn test() { let mut t1 = Foo::new(Bar); // ^^^^^^ Foo<&'? (), Bar> t1[&()] = Bar; let mut t2 = Foo::new(Bar); // ^^^^^^ Foo<&'? (), Bar> t2[&()].bar(); } "#, ) } #[test] fn issue_17191() { check_types( r#" trait A { type Item; } trait B {} fn foo>() {} fn test() { let f = foo; //^ fn foo<{unknown}>() }"#, ); } #[test] fn issue_17866() { check_infer( r#" trait T { type A; } type Foo = ::A; fn main() { Foo {}; } "#, expect![[r#" 60..75 '{ Foo {}; }': () 66..72 'Foo {}': {unknown} "#]], ); } #[test] fn issue_17711() { check_infer( r#" //- minicore: deref use core::ops::Deref; struct Struct<'a, T>(&'a T); trait Trait {} impl<'a, T: Deref> Struct<'a, T> { fn foo(&self) -> &Self { self } fn bar(&self) { let _ = self.foo(); } } "#, expect![[r#" 137..141 'self': &'? Struct<'a, T> 152..160 '{ self }': &'? Struct<'a, T> 154..158 'self': &'? Struct<'a, T> 174..178 'self': &'? Struct<'a, T> 180..215 '{ ... }': () 194..195 '_': &'? Struct<'?, T> 198..202 'self': &'? Struct<'a, T> 198..208 'self.foo()': &'? Struct<'?, T> "#]], ); } #[test] fn issue_17767() { check_infer( r#" extern "C" { type Foo; } fn f() -> Foo {} "#, expect![[r#" 47..49 '{}': Foo "#]], ); } #[test] fn issue_17921() { check_infer( r#" //- minicore: future trait Foo {} type Bar = impl Foo; async fn f() -> Bar {} "#, expect![[r#" 64..66 '{}': () "#]], ); } #[test] fn issue_18109() { check_infer( r#" //- minicore: option struct Map(T, U); impl Map { fn new() -> Self { loop {} } fn get(&self, _: &T) -> Option<&U> { loop {} } } fn test(x: bool) { let map = Map::new(); let _ = match x { true => { let Some(val) = map.get(&8) else { return }; *val } false => return, _ => 42, }; } "#, expect![[r#" 69..80 '{ loop {} }': Map 71..78 'loop {}': ! 76..78 '{}': () 93..97 'self': &'? Map 99..100 '_': &'? T 120..131 '{ loop {} }': Option<&'? U> 122..129 'loop {}': ! 127..129 '{}': () 143..144 'x': bool 152..354 '{ ... }; }': () 162..165 'map': Map 168..176 'Map::new': fn new() -> Map 168..178 'Map::new()': Map 188..189 '_': i32 192..351 'match ... }': i32 198..199 'x': bool 210..214 'true': bool 210..214 'true': bool 218..303 '{ ... }': i32 236..245 'Some(val)': Option<&'? i32> 241..244 'val': &'? i32 248..251 'map': Map 248..259 'map.get(&8)': Option<&'? i32> 256..258 '&8': &'? i32 257..258 '8': i32 265..275 '{ return }': ! 267..273 'return': ! 289..293 '*val': i32 290..293 'val': &'? i32 312..317 'false': bool 312..317 'false': bool 321..327 'return': ! 337..338 '_': bool 342..344 '42': i32 "#]], ); } #[test] fn issue_19730() { check_infer( r#" trait Trait {} trait Foo { type Bar: Trait; fn foo(bar: Self::Bar) { let _ = bar; } } "#, expect![[r#" 83..86 'bar': ::Bar 105..133 '{ ... }': () 119..120 '_': ::Bar 123..126 'bar': ::Bar "#]], ); } #[test] fn no_panic_on_recursive_const() { check_infer( r#" struct Foo {} impl> Foo { fn foo(self) {} } fn test() { let _ = N; } "#, expect![[r#" 72..76 'self': Foo 78..80 '{}': () 94..112 '{ ...= N; }': () 104..105 '_': {unknown} 108..109 'N': {unknown} "#]], ); check_infer( r#" struct Foo; const N: Foo = Foo; impl Foo { fn foo(self) -> usize { N } } fn test() { let _ = N; } "#, expect![[r#" 93..97 'self': Foo 108..125 '{ ... }': usize 118..119 'N': usize 139..157 '{ ...= N; }': () 149..150 '_': Foo 153..154 'N': Foo "#]], ); } #[test] fn rust_destruct_option_clone() { check_types( r#" //- minicore: option, drop #![feature(lang_items)] fn test(o: &Option) { o.my_clone(); //^^^^^^^^^^^^ Option } pub trait MyClone: Sized { fn my_clone(&self) -> Self; } impl const MyClone for Option where T: ~const MyClone + ~const Destruct, { fn my_clone(&self) -> Self { match self { Some(x) => Some(x.my_clone()), None => None, } } } impl const MyClone for i32 { fn my_clone(&self) -> Self { *self } } #[lang = "destruct"] pub trait Destruct {} "#, ); } #[test] fn no_duplicated_lang_item_metadata() { check_types( r#" //- minicore: pointee //- /main.rs crate:main deps:std,core use std::AtomicPtr; use std::null_mut; fn main() { let x: AtomicPtr<()> = AtomicPtr::new(null_mut()); //^ AtomicPtr<()> } //- /lib.rs crate:r#std deps:core #![no_std] pub use core::*; //- /lib.rs crate:r#core #![no_core] #[lang = "pointee_trait"] pub trait Pointee { #[lang = "metadata_type"] type Metadata; } pub struct AtomicPtr(T); impl AtomicPtr { pub fn new(p: *mut T) -> AtomicPtr { loop {} } } #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] pub trait MetaSized: PointeeSized {} #[lang = "sized"] pub trait Sized: MetaSized {} pub trait Thin = Pointee + PointeeSized; pub fn null_mut() -> *mut T { loop {} } "#, ); } #[test] fn issue_20484() { check_no_mismatches( r#" struct Eth; trait FullBlockBody { type Transaction; } impl FullBlockBody for () { type Transaction = (); } trait NodePrimitives { type BlockBody; type SignedTx; } impl NodePrimitives for () { type BlockBody = (); type SignedTx = (); } impl NodePrimitives for Eth { type BlockBody = (); type SignedTx = (); } trait FullNodePrimitives where Self: NodePrimitives>, { } impl FullNodePrimitives for T where T: NodePrimitives>, { } fn node(_: N) where N: FullNodePrimitives, { } fn main() { node(Eth); } "#, ); } #[test] fn module_inside_block() { check_types( r#" fn foo() { mod my_mod { pub type Bool = bool; } let _: my_mod::Bool; // ^ bool } "#, ); } #[test] fn issue_9881_super_trait_blanket_impl() { check_types( r#" pub trait TryStream: Stream { fn try_poll_next(&self) {} } pub trait Stream { type Item; fn poll_next(&self) {} } trait StreamAlias: Stream {} impl> TryStream for S {} impl> StreamAlias for S {} struct StreamImpl; impl Stream for StreamImpl { type Item = (); } fn foo() -> impl StreamAlias { StreamImpl } fn main() { let alias = foo(); let _: () = alias.try_poll_next(); // ^ () let _: () = alias.poll_next(); // ^ () } "#, ); } #[test] fn regression_21429() { check_no_mismatches( r#" trait DatabaseLike { type ForeignKey: ForeignKeyLike; } trait ForeignKeyLike { type DB: DatabaseLike; fn host_columns(&self, database: &Self::DB); } trait ColumnLike { type DB: DatabaseLike; fn foo() -> &&<::DB as DatabaseLike>::ForeignKey { loop {} } fn foreign_keys(&self, database: &Self::DB) { let fk = Self::foo(); fk.host_columns(database); } } "#, ); } #[test] fn issue_21006_generic_predicates_for_param_supertrait_cycle() { check_no_mismatches( r#" trait VCipherSuite {} trait CipherSuite where OprfHash: Hash, { } type Bar = ::Hash; type OprfHash = ::Hash; impl Foo { fn seal() {} } "#, ); } #[test] fn issue_21006_self_assoc_trait() { check_types( r#" trait Baz { fn baz(&self); } trait Foo { type Assoc; } trait Bar: Foo where Self::Assoc: Baz, { fn bar(v: Self::Assoc) { let _ = v.baz(); // ^ () } } "#, ); } #[test] fn issue_21560() { check_no_mismatches( r#" mod bindings { use super::*; pub type HRESULT = i32; } use bindings::*; mod error { use super::*; pub fn nonzero_hresult(hr: HRESULT) -> crate::HRESULT { hr } } pub use error::*; mod hresult { use super::*; pub struct HRESULT(pub i32); } pub use hresult::HRESULT; "#, ); } #[test] fn regression_21577() { check_no_mismatches( r#" pub trait FilterT = Self> { type V; fn foo() {} } "#, ); } #[test] fn regression_21605() { check_infer( r#" //- minicore: fn, coerce_unsized, dispatch_from_dyn, iterator, iterators pub struct Filter<'a, 'b, T> where T: 'b, 'a: 'b, { filter_fn: dyn Fn(&'a T) -> bool, t: Option, b: &'b (), } impl<'a, 'b, T> Filter<'a, 'b, T> where T: 'b, 'a: 'b, { pub fn new(filter_fn: dyn Fn(&T) -> bool) -> Self { Self { filter_fn: filter_fn, t: None, b: &(), } } } pub trait FilterExt { type Output; fn filter(&self, filter: &Filter) -> Self::Output; } impl FilterExt for [T; N] where T: IntoIterator, { type Output = T; fn filter(&self, filter: &Filter) -> Self::Output { let _ = self.into_iter().filter(filter.filter_fn); loop {} } } "#, expect![[r#" 214..223 'filter_fn': dyn Fn(&'? T) -> bool + 'static 253..360 '{ ... }': Filter<'a, 'b, T> 263..354 'Self {... }': Filter<'a, 'b, T> 293..302 'filter_fn': dyn Fn(&'? T) -> bool + 'static 319..323 'None': Option 340..343 '&()': &'? () 341..343 '()': () 421..425 'self': &'? Self 427..433 'filter': &'? Filter<'?, '?, T> 580..584 'self': &'? [T; N] 586..592 'filter': &'? Filter<'?, '?, T> 622..704 '{ ... }': T 636..637 '_': Filter, dyn Fn(&'? T) -> bool + '?> 640..644 'self': &'? [T; N] 640..656 'self.i...iter()': Iter<'?, T> 640..681 'self.i...er_fn)': Filter, dyn Fn(&'? T) -> bool + '?> 664..670 'filter': &'? Filter<'?, '?, T> 664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static 691..698 'loop {}': ! 696..698 '{}': () "#]], ); } #[test] fn extern_fns_cannot_have_param_patterns() { check_no_mismatches( r#" pub(crate) struct Builder<'a>(&'a ()); unsafe extern "C" { pub(crate) fn foo<'a>(Builder: &Builder<'a>); } "#, ); } #[test] fn infinitely_sized_type() { check_infer( r#" //- minicore: sized pub struct Recursive { pub content: Recursive, } fn is_sized() {} fn foo() { is_sized::(); } "#, expect![[r#" 79..81 '{}': () 92..124 '{ ...>(); }': () 98..119 'is_siz...rsive>': fn is_sized() 98..121 'is_siz...ive>()': () "#]], ); }