From f5177f91ae61e1d812efd6b55a1ec7ab07c7c7e1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 8 May 2020 15:17:35 +0200 Subject: Fix type of byte literals They're `&[u8; N]`, not `&[u8]` (see #4374). --- crates/ra_hir_ty/src/tests/method_resolution.rs | 13 +++++++------ crates/ra_hir_ty/src/tests/simple.rs | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index ab87f598a..67f964ab5 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -17,8 +17,8 @@ impl [T] { #[lang = "slice_alloc"] impl [T] {} -fn test() { - <[_]>::foo(b"foo"); +fn test(x: &[u8]) { + <[_]>::foo(x); } "#), @r###" @@ -26,10 +26,11 @@ fn test() { 56..79 '{ ... }': T 66..73 'loop {}': ! 71..73 '{}': () - 133..160 '{ ...o"); }': () - 139..149 '<[_]>::foo': fn foo(&[u8]) -> u8 - 139..157 '<[_]>:..."foo")': u8 - 150..156 'b"foo"': &[u8] + 131..132 'x': &[u8] + 141..163 '{ ...(x); }': () + 147..157 '<[_]>::foo': fn foo(&[u8]) -> u8 + 147..160 '<[_]>::foo(x)': u8 + 158..159 'x': &[u8] "### ); } diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 3d3088965..e17a17900 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -414,7 +414,7 @@ fn test() { 27..31 '5f32': f32 37..41 '5f64': f64 47..54 '"hello"': &str - 60..68 'b"bytes"': &[u8] + 60..68 'b"bytes"': &[u8; _] 74..77 ''c'': char 83..87 'b'b'': u8 93..97 '3.14': f64 @@ -422,7 +422,7 @@ fn test() { 113..118 'false': bool 124..128 'true': bool 134..202 'r#" ... "#': &str - 208..218 'br#"yolo"#': &[u8] + 208..218 'br#"yolo"#': &[u8; _] "### ); } -- cgit v1.2.3 From fe93675e8ac2b55d051156151489dbe0496efec3 Mon Sep 17 00:00:00 2001 From: Timo Freiberg Date: Sat, 25 Apr 2020 16:57:59 +0200 Subject: New HirDisplay method for displaying sourcecode --- crates/ra_hir_ty/src/tests/display_source_code.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 crates/ra_hir_ty/src/tests/display_source_code.rs (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/display_source_code.rs b/crates/ra_hir_ty/src/tests/display_source_code.rs new file mode 100644 index 000000000..ca1748615 --- /dev/null +++ b/crates/ra_hir_ty/src/tests/display_source_code.rs @@ -0,0 +1,23 @@ +use super::displayed_source_at_pos; +use crate::test_db::TestDB; +use ra_db::fixture::WithFixture; + +#[test] +fn qualify_path_to_submodule() { + let (db, pos) = TestDB::with_position( + r#" +//- /main.rs + +mod foo { + pub struct Foo; +} + +fn bar() { + let foo: foo::Foo = foo::Foo; + foo<|> +} + +"#, + ); + assert_eq!("foo::Foo", displayed_source_at_pos(&db, pos)); +} -- cgit v1.2.3 From fe7bf993aa8d64668707e348f2ea69918cfda9a4 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 8 May 2020 17:36:11 +0200 Subject: Implement better handling of divergence Divergence here means that for some reason, the end of a block will not be reached. We tried to model this just using the never type, but that doesn't work fully (e.g. in `let x = { loop {}; "foo" };` x should still have type `&str`); so this introduces a `diverges` flag that the type checker keeps track of, like rustc does. --- crates/ra_hir_ty/src/tests/coercion.rs | 4 +- crates/ra_hir_ty/src/tests/macros.rs | 2 +- crates/ra_hir_ty/src/tests/never_type.rs | 107 ++++++++++++++++++++++++++++++- crates/ra_hir_ty/src/tests/simple.rs | 10 +-- 4 files changed, 114 insertions(+), 9 deletions(-) (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 index e6fb3e123..0c3a833bd 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -384,7 +384,7 @@ fn foo() -> u32 { } "#, true), @r###" - 17..40 '{ ...own; }': ! + 17..40 '{ ...own; }': u32 23..37 'return unknown': ! 30..37 'unknown': u32 "### @@ -514,7 +514,7 @@ fn foo() { 27..103 '{ ... }': &u32 37..82 'if tru... }': () 40..44 'true': bool - 45..82 '{ ... }': ! + 45..82 '{ ... }': () 59..71 'return &1u32': ! 66..71 '&1u32': &u32 67..71 '1u32': u32 diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 07398ddcc..4c6099aa2 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs @@ -197,7 +197,7 @@ fn spam() { !0..6 '1isize': isize !0..6 '1isize': isize !0..6 '1isize': isize - 54..457 '{ ...!(); }': ! + 54..457 '{ ...!(); }': () 88..109 'spam!(...am!())': {unknown} 115..134 'for _ ...!() {}': () 119..120 '_': {unknown} diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs index a77209480..1721f97c5 100644 --- a/crates/ra_hir_ty/src/tests/never_type.rs +++ b/crates/ra_hir_ty/src/tests/never_type.rs @@ -1,4 +1,6 @@ -use super::type_at; +use insta::assert_snapshot; + +use super::{infer_with_mismatches, type_at}; #[test] fn infer_never1() { @@ -261,3 +263,106 @@ fn test(a: i32) { ); assert_eq!(t, "f64"); } + +#[test] +fn diverging_expression_1() { + let t = 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 {}; }; }; +} +"#, + true, + ); + assert_snapshot!(t, @r###" + 25..53 '{ ...urn; }': () + 35..36 'x': u32 + 44..50 'return': ! + 65..98 '{ ...; }; }': () + 75..76 'x': u32 + 84..95 '{ return; }': u32 + 86..92 'return': ! + 110..139 '{ ... {}; }': () + 120..121 'x': u32 + 129..136 'loop {}': ! + 134..136 '{}': () + 151..184 '{ ...} }; }': () + 161..162 'x': u32 + 170..181 '{ loop {} }': u32 + 172..179 'loop {}': ! + 177..179 '{}': () + 196..260 '{ ...} }; }': () + 206..207 'x': u32 + 215..257 '{ if t...}; } }': u32 + 217..255 'if tru... {}; }': u32 + 220..224 'true': bool + 225..237 '{ loop {}; }': u32 + 227..234 'loop {}': ! + 232..234 '{}': () + 243..255 '{ loop {}; }': u32 + 245..252 'loop {}': ! + 250..252 '{}': () + 272..324 '{ ...; }; }': () + 282..283 'x': u32 + 291..321 '{ let ...; }; }': u32 + 297..298 'y': u32 + 306..318 '{ loop {}; }': u32 + 308..315 'loop {}': ! + 313..315 '{}': () + "###); +} + +#[test] +fn diverging_expression_2() { + let t = infer_with_mismatches( + r#" +//- /main.rs +fn test1() { + // should give type mismatch + let x: u32 = { loop {}; "foo" }; +} +"#, + true, + ); + assert_snapshot!(t, @r###" + 25..98 '{ ..." }; }': () + 68..69 'x': u32 + 77..95 '{ loop...foo" }': &str + 79..86 'loop {}': ! + 84..86 '{}': () + 88..93 '"foo"': &str + 77..95: expected u32, got &str + 88..93: expected u32, got &str + "###); +} + +#[test] +fn diverging_expression_3_break() { + let t = infer_with_mismatches( + r#" +//- /main.rs +fn test1() { + // should give type mismatch + let x: u32 = { loop { break; } }; +} +"#, + true, + ); + assert_snapshot!(t, @r###""###); +} diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index e17a17900..3820175f6 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -179,7 +179,7 @@ fn test(a: u32, b: isize, c: !, d: &str) { 17..18 'b': isize 27..28 'c': ! 33..34 'd': &str - 42..121 '{ ...f32; }': ! + 42..121 '{ ...f32; }': () 48..49 'a': u32 55..56 'b': isize 62..63 'c': ! @@ -935,7 +935,7 @@ fn foo() { 29..33 'true': bool 34..51 '{ ... }': i32 44..45 '1': i32 - 57..80 '{ ... }': ! + 57..80 '{ ... }': i32 67..73 'return': ! 90..93 '_x2': i32 96..149 'if tru... }': i32 @@ -951,7 +951,7 @@ fn foo() { 186..190 'true': bool 194..195 '3': i32 205..206 '_': bool - 210..241 '{ ... }': ! + 210..241 '{ ... }': i32 224..230 'return': ! 257..260 '_x4': i32 263..320 'match ... }': i32 @@ -1687,7 +1687,7 @@ fn foo() -> u32 { 17..59 '{ ...; }; }': () 27..28 'x': || -> usize 31..56 '|| -> ...n 1; }': || -> usize - 43..56 '{ return 1; }': ! + 43..56 '{ return 1; }': usize 45..53 'return 1': ! 52..53 '1': usize "### @@ -1706,7 +1706,7 @@ fn foo() -> u32 { 17..48 '{ ...; }; }': () 27..28 'x': || -> () 31..45 '|| { return; }': || -> () - 34..45 '{ return; }': ! + 34..45 '{ return; }': () 36..42 'return': ! "### ); -- cgit v1.2.3 From b60970fd2050f844e3e52fcfd1724a8c527a11af Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 8 May 2020 17:59:58 +0200 Subject: Handle break somewhat better Still no break-with-value or labels, but at least we know that `loop { break; }` doesn't diverge. --- crates/ra_hir_ty/src/tests/never_type.rs | 72 +++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs index 1721f97c5..082c47208 100644 --- a/crates/ra_hir_ty/src/tests/never_type.rs +++ b/crates/ra_hir_ty/src/tests/never_type.rs @@ -361,8 +361,78 @@ 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; }; }; +} "#, true, ); - assert_snapshot!(t, @r###""###); + assert_snapshot!(t, @r###" + 25..99 '{ ...} }; }': () + 68..69 'x': u32 + 77..96 '{ loop...k; } }': () + 79..94 'loop { break; }': () + 84..94 '{ break; }': () + 86..91 'break': ! + 77..96: expected u32, got () + 79..94: expected u32, got () + 111..357 '{ ...; }; }': () + 154..155 'x': u32 + 163..189 '{ for ...; }; }': () + 165..186 'for a ...eak; }': () + 169..170 'a': {unknown} + 174..175 'b': {unknown} + 176..186 '{ break; }': () + 178..183 'break': ! + 240..241 'x': u32 + 249..267 '{ for ... {}; }': () + 251..264 'for a in b {}': () + 255..256 'a': {unknown} + 260..261 'b': {unknown} + 262..264 '{}': () + 318..319 'x': u32 + 327..354 '{ for ...; }; }': () + 329..351 'for a ...urn; }': () + 333..334 'a': {unknown} + 338..339 'b': {unknown} + 340..351 '{ return; }': () + 342..348 'return': ! + 163..189: expected u32, got () + 249..267: expected u32, got () + 327..354: expected u32, got () + 369..668 '{ ...; }; }': () + 412..413 'x': u32 + 421..447 '{ whil...; }; }': () + 423..444 'while ...eak; }': () + 429..433 'true': bool + 434..444 '{ break; }': () + 436..441 'break': ! + 551..552 'x': u32 + 560..578 '{ whil... {}; }': () + 562..575 'while true {}': () + 568..572 'true': bool + 573..575 '{}': () + 629..630 'x': u32 + 638..665 '{ whil...; }; }': () + 640..662 'while ...urn; }': () + 646..650 'true': bool + 651..662 '{ return; }': () + 653..659 'return': ! + 421..447: expected u32, got () + 560..578: expected u32, got () + 638..665: expected u32, got () + "###); } -- cgit v1.2.3 From a3d866e776f43c1ae717740bf0c507f4d9fe47cb Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 8 May 2020 22:12:16 +0200 Subject: Handle coercing function types to function pointers in match E.g. in ```rust match x { 1 => function1, 2 => function2, } ``` we need to try coercing both to pointers. Turns out this is a special case in rustc as well (see the link in the comment). --- crates/ra_hir_ty/src/tests/coercion.rs | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (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 index 0c3a833bd..6dc4b2cd1 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs @@ -545,6 +545,48 @@ fn test() { ); } +#[test] +fn coerce_fn_items_in_match_arms() { + covers!(coerce_fn_reification); + assert_snapshot!( + infer_with_mismatches(r#" +fn foo1(x: u32) -> isize { 1 } +fn foo2(x: u32) -> isize { 2 } +fn foo3(x: u32) -> isize { 3 } +fn test() { + let x = match 1 { + 1 => foo1, + 2 => foo2, + _ => foo3, + }; +} +"#, true), + @r###" + 9..10 'x': u32 + 26..31 '{ 1 }': isize + 28..29 '1': isize + 40..41 'x': u32 + 57..62 '{ 2 }': isize + 59..60 '2': isize + 71..72 'x': u32 + 88..93 '{ 3 }': isize + 90..91 '3': isize + 104..193 '{ ... }; }': () + 114..115 'x': fn(u32) -> isize + 118..190 'match ... }': fn(u32) -> isize + 124..125 '1': i32 + 136..137 '1': i32 + 136..137 '1': i32 + 141..145 'foo1': fn foo1(u32) -> isize + 155..156 '2': i32 + 155..156 '2': i32 + 160..164 'foo2': fn foo2(u32) -> isize + 174..175 '_': i32 + 179..183 'foo3': fn foo3(u32) -> isize + "### + ); +} + #[test] fn coerce_closure_to_fn_ptr() { assert_snapshot!( -- cgit v1.2.3