diff options
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f6a325033..291bc9ae5 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -4,15 +4,15 @@ use std::fmt::Write; | |||
4 | use insta::assert_snapshot_matches; | 4 | use insta::assert_snapshot_matches; |
5 | 5 | ||
6 | use ra_db::{SourceDatabase, salsa::Database, FilePosition}; | 6 | use ra_db::{SourceDatabase, salsa::Database, FilePosition}; |
7 | use ra_syntax::{algo, ast::{self, AstNode}}; | 7 | use ra_syntax::{algo, ast::{self, AstNode}, SyntaxKind::*}; |
8 | use test_utils::covers; | 8 | use test_utils::covers; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | source_binder, | ||
12 | mock::MockDatabase, | 11 | mock::MockDatabase, |
13 | ty::display::HirDisplay, | 12 | ty::display::HirDisplay, |
14 | ty::InferenceResult, | 13 | ty::InferenceResult, |
15 | expr::BodySourceMap | 14 | expr::BodySourceMap, |
15 | SourceAnalyzer, | ||
16 | }; | 16 | }; |
17 | 17 | ||
18 | // These tests compare the inference results for all expressions in a file | 18 | // These tests compare the inference results for all expressions in a file |
@@ -1862,14 +1862,14 @@ fn test() { | |||
1862 | @r###" | 1862 | @r###" |
1863 | [49; 50) '0': u32 | 1863 | [49; 50) '0': u32 |
1864 | [80; 83) '101': u32 | 1864 | [80; 83) '101': u32 |
1865 | [126; 128) '99': u32 | ||
1866 | [95; 213) '{ ...NST; }': () | 1865 | [95; 213) '{ ...NST; }': () |
1867 | [138; 139) 'x': {unknown} | 1866 | [138; 139) 'x': {unknown} |
1868 | [142; 153) 'LOCAL_CONST': {unknown} | 1867 | [142; 153) 'LOCAL_CONST': {unknown} |
1869 | [163; 164) 'z': u32 | 1868 | [163; 164) 'z': u32 |
1870 | [167; 179) 'GLOBAL_CONST': u32 | 1869 | [167; 179) 'GLOBAL_CONST': u32 |
1871 | [189; 191) 'id': u32 | 1870 | [189; 191) 'id': u32 |
1872 | [194; 210) 'Foo::A..._CONST': u32"### | 1871 | [194; 210) 'Foo::A..._CONST': u32 |
1872 | [126; 128) '99': u32"### | ||
1873 | ); | 1873 | ); |
1874 | } | 1874 | } |
1875 | 1875 | ||
@@ -1891,8 +1891,6 @@ fn test() { | |||
1891 | @r###" | 1891 | @r###" |
1892 | [29; 32) '101': u32 | 1892 | [29; 32) '101': u32 |
1893 | [70; 73) '101': u32 | 1893 | [70; 73) '101': u32 |
1894 | [118; 120) '99': u32 | ||
1895 | [161; 163) '99': u32 | ||
1896 | [85; 280) '{ ...MUT; }': () | 1894 | [85; 280) '{ ...MUT; }': () |
1897 | [173; 174) 'x': {unknown} | 1895 | [173; 174) 'x': {unknown} |
1898 | [177; 189) 'LOCAL_STATIC': {unknown} | 1896 | [177; 189) 'LOCAL_STATIC': {unknown} |
@@ -1901,7 +1899,9 @@ fn test() { | |||
1901 | [229; 230) 'z': u32 | 1899 | [229; 230) 'z': u32 |
1902 | [233; 246) 'GLOBAL_STATIC': u32 | 1900 | [233; 246) 'GLOBAL_STATIC': u32 |
1903 | [256; 257) 'w': u32 | 1901 | [256; 257) 'w': u32 |
1904 | [260; 277) 'GLOBAL...IC_MUT': u32"### | 1902 | [260; 277) 'GLOBAL...IC_MUT': u32 |
1903 | [118; 120) '99': u32 | ||
1904 | [161; 163) '99': u32"### | ||
1905 | ); | 1905 | ); |
1906 | } | 1906 | } |
1907 | 1907 | ||
@@ -1926,8 +1926,8 @@ fn test() { | |||
1926 | } | 1926 | } |
1927 | "#), | 1927 | "#), |
1928 | @r###" | 1928 | @r###" |
1929 | [31; 35) 'self': &{unknown} | 1929 | [31; 35) 'self': &Self |
1930 | [110; 114) 'self': &{unknown} | 1930 | [110; 114) 'self': &Self |
1931 | [170; 228) '{ ...i128 }': () | 1931 | [170; 228) '{ ...i128 }': () |
1932 | [176; 178) 'S1': S1 | 1932 | [176; 178) 'S1': S1 |
1933 | [176; 187) 'S1.method()': u32 | 1933 | [176; 187) 'S1.method()': u32 |
@@ -1972,8 +1972,8 @@ mod bar_test { | |||
1972 | } | 1972 | } |
1973 | "#), | 1973 | "#), |
1974 | @r###" | 1974 | @r###" |
1975 | [63; 67) 'self': &{unknown} | 1975 | [63; 67) 'self': &Self |
1976 | [169; 173) 'self': &{unknown} | 1976 | [169; 173) 'self': &Self |
1977 | [300; 337) '{ ... }': () | 1977 | [300; 337) '{ ... }': () |
1978 | [310; 311) 'S': S | 1978 | [310; 311) 'S': S |
1979 | [310; 320) 'S.method()': u32 | 1979 | [310; 320) 'S.method()': u32 |
@@ -1998,10 +1998,45 @@ fn test() { | |||
1998 | } | 1998 | } |
1999 | "#), | 1999 | "#), |
2000 | @r###" | 2000 | @r###" |
2001 | [33; 37) 'self': &{unknown} | 2001 | [33; 37) 'self': &Self |
2002 | [92; 111) '{ ...d(); }': () | 2002 | [92; 111) '{ ...d(); }': () |
2003 | [98; 99) 'S': S | 2003 | [98; 99) 'S': S |
2004 | [98; 108) 'S.method()': {unknown}"### | 2004 | [98; 108) 'S.method()': u32"### |
2005 | ); | ||
2006 | } | ||
2007 | |||
2008 | #[test] | ||
2009 | fn infer_trait_method_generic_more_params() { | ||
2010 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
2011 | assert_snapshot_matches!( | ||
2012 | infer(r#" | ||
2013 | trait Trait<T1, T2, T3> { | ||
2014 | fn method1(&self) -> (T1, T2, T3); | ||
2015 | fn method2(&self) -> (T3, T2, T1); | ||
2016 | } | ||
2017 | struct S1; | ||
2018 | impl Trait<u8, u16, u32> for S1 {} | ||
2019 | struct S2; | ||
2020 | impl<T> Trait<i8, i16, T> for S2 {} | ||
2021 | fn test() { | ||
2022 | S1.method1(); // u8, u16, u32 | ||
2023 | S1.method2(); // u32, u16, u8 | ||
2024 | S2.method1(); // i8, i16, {unknown} | ||
2025 | S2.method2(); // {unknown}, i16, i8 | ||
2026 | } | ||
2027 | "#), | ||
2028 | @r###" | ||
2029 | [43; 47) 'self': &Self | ||
2030 | [82; 86) 'self': &Self | ||
2031 | [210; 361) '{ ..., i8 }': () | ||
2032 | [216; 218) 'S1': S1 | ||
2033 | [216; 228) 'S1.method1()': (u8, u16, u32) | ||
2034 | [250; 252) 'S1': S1 | ||
2035 | [250; 262) 'S1.method2()': (u32, u16, u8) | ||
2036 | [284; 286) 'S2': S2 | ||
2037 | [284; 296) 'S2.method1()': (i8, i16, {unknown}) | ||
2038 | [324; 326) 'S2': S2 | ||
2039 | [324; 336) 'S2.method2()': ({unknown}, i16, i8)"### | ||
2005 | ); | 2040 | ); |
2006 | } | 2041 | } |
2007 | 2042 | ||
@@ -2020,7 +2055,7 @@ fn test() { | |||
2020 | } | 2055 | } |
2021 | "#), | 2056 | "#), |
2022 | @r###" | 2057 | @r###" |
2023 | [33; 37) 'self': &{unknown} | 2058 | [33; 37) 'self': &Self |
2024 | [102; 127) '{ ...d(); }': () | 2059 | [102; 127) '{ ...d(); }': () |
2025 | [108; 109) 'S': S<u32>(T) -> S<T> | 2060 | [108; 109) 'S': S<u32>(T) -> S<T> |
2026 | [108; 115) 'S(1u32)': S<u32> | 2061 | [108; 115) 'S(1u32)': S<u32> |
@@ -2168,7 +2203,7 @@ fn test() { | |||
2168 | } | 2203 | } |
2169 | "#), | 2204 | "#), |
2170 | @r###" | 2205 | @r###" |
2171 | [29; 33) 'self': {unknown} | 2206 | [29; 33) 'self': Self |
2172 | [107; 198) '{ ...(S); }': () | 2207 | [107; 198) '{ ...(S); }': () |
2173 | [117; 118) 'x': u32 | 2208 | [117; 118) 'x': u32 |
2174 | [126; 127) 'S': S | 2209 | [126; 127) 'S': S |
@@ -2302,13 +2337,10 @@ fn test() -> u64 { | |||
2302 | } | 2337 | } |
2303 | 2338 | ||
2304 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2339 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
2305 | let func = source_binder::function_from_position(db, pos).unwrap(); | 2340 | let file = db.parse(pos.file_id); |
2306 | let body_source_map = func.body_source_map(db); | 2341 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |
2307 | let inference_result = func.infer(db); | 2342 | let analyzer = SourceAnalyzer::new(db, pos.file_id, expr.syntax(), Some(pos.offset)); |
2308 | let (_, syntax) = func.source(db); | 2343 | let ty = analyzer.type_of(db, expr).unwrap(); |
2309 | let node = algo::find_node_at_offset::<ast::Expr>(syntax.syntax(), pos.offset).unwrap(); | ||
2310 | let expr = body_source_map.node_expr(node).unwrap(); | ||
2311 | let ty = &inference_result[expr]; | ||
2312 | ty.display(db).to_string() | 2344 | ty.display(db).to_string() |
2313 | } | 2345 | } |
2314 | 2346 | ||
@@ -2324,7 +2356,7 @@ fn infer(content: &str) -> String { | |||
2324 | 2356 | ||
2325 | for (pat, ty) in inference_result.type_of_pat.iter() { | 2357 | for (pat, ty) in inference_result.type_of_pat.iter() { |
2326 | let syntax_ptr = match body_source_map.pat_syntax(pat) { | 2358 | let syntax_ptr = match body_source_map.pat_syntax(pat) { |
2327 | Some(sp) => sp, | 2359 | Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()), |
2328 | None => continue, | 2360 | None => continue, |
2329 | }; | 2361 | }; |
2330 | types.push((syntax_ptr, ty)); | 2362 | types.push((syntax_ptr, ty)); |
@@ -2350,25 +2382,11 @@ fn infer(content: &str) -> String { | |||
2350 | } | 2382 | } |
2351 | }; | 2383 | }; |
2352 | 2384 | ||
2353 | for const_def in source_file.syntax().descendants().filter_map(ast::ConstDef::cast) { | 2385 | for node in source_file.syntax().descendants() { |
2354 | let konst = source_binder::const_from_source(&db, file_id, const_def).unwrap(); | 2386 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { |
2355 | let inference_result = konst.infer(&db); | 2387 | let analyzer = SourceAnalyzer::new(&db, file_id, node, None); |
2356 | let body_source_map = konst.body_source_map(&db); | 2388 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); |
2357 | infer_def(inference_result, body_source_map) | 2389 | } |
2358 | } | ||
2359 | |||
2360 | for static_def in source_file.syntax().descendants().filter_map(ast::StaticDef::cast) { | ||
2361 | let static_ = source_binder::static_from_source(&db, file_id, static_def).unwrap(); | ||
2362 | let inference_result = static_.infer(&db); | ||
2363 | let body_source_map = static_.body_source_map(&db); | ||
2364 | infer_def(inference_result, body_source_map) | ||
2365 | } | ||
2366 | |||
2367 | for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { | ||
2368 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); | ||
2369 | let inference_result = func.infer(&db); | ||
2370 | let body_source_map = func.body_source_map(&db); | ||
2371 | infer_def(inference_result, body_source_map) | ||
2372 | } | 2390 | } |
2373 | 2391 | ||
2374 | acc.truncate(acc.trim_end().len()); | 2392 | acc.truncate(acc.trim_end().len()); |
@@ -2403,10 +2421,12 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
2403 | } | 2421 | } |
2404 | ", | 2422 | ", |
2405 | ); | 2423 | ); |
2406 | let func = source_binder::function_from_position(&db, pos).unwrap(); | ||
2407 | { | 2424 | { |
2425 | let file = db.parse(pos.file_id); | ||
2426 | let node = | ||
2427 | algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent(); | ||
2408 | let events = db.log_executed(|| { | 2428 | let events = db.log_executed(|| { |
2409 | func.infer(&db); | 2429 | SourceAnalyzer::new(&db, pos.file_id, node, None); |
2410 | }); | 2430 | }); |
2411 | assert!(format!("{:?}", events).contains("infer")) | 2431 | assert!(format!("{:?}", events).contains("infer")) |
2412 | } | 2432 | } |
@@ -2423,8 +2443,11 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
2423 | db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); | 2443 | db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); |
2424 | 2444 | ||
2425 | { | 2445 | { |
2446 | let file = db.parse(pos.file_id); | ||
2447 | let node = | ||
2448 | algo::find_token_at_offset(file.syntax(), pos.offset).right_biased().unwrap().parent(); | ||
2426 | let events = db.log_executed(|| { | 2449 | let events = db.log_executed(|| { |
2427 | func.infer(&db); | 2450 | SourceAnalyzer::new(&db, pos.file_id, node, None); |
2428 | }); | 2451 | }); |
2429 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) | 2452 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) |
2430 | } | 2453 | } |