From 8b147624ff906a11134d2e18be071c6cb8ec4beb Mon Sep 17 00:00:00 2001 From: Jade Date: Wed, 12 May 2021 04:39:48 -0700 Subject: Add lowering of array lengths in types Now e.g. ```rust fn a(b: [u8; 2]) { } ``` will know about the length of b. --- crates/hir_ty/src/tests/coercion.rs | 44 ++++++++++++++++++------------------- crates/hir_ty/src/tests/patterns.rs | 8 +++---- crates/hir_ty/src/tests/simple.rs | 16 +++++++------- 3 files changed, 34 insertions(+), 34 deletions(-) (limited to 'crates/hir_ty/src/tests') diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs index aad3d610e..c2afaf6ec 100644 --- a/crates/hir_ty/src/tests/coercion.rs +++ b/crates/hir_ty/src/tests/coercion.rs @@ -64,42 +64,42 @@ fn coerce_places() { 81..92 '{ loop {} }': T 83..90 'loop {}': ! 88..90 '{}': () - 121..132 '{ loop {} }': *mut [T; _] + 121..132 '{ loop {} }': *mut [T; 2] 123..130 'loop {}': ! 128..130 '{}': () 159..172 '{ gen() }': *mut [U] - 165..168 'gen': fn gen() -> *mut [U; _] - 165..170 'gen()': *mut [U; _] + 165..168 'gen': fn gen() -> *mut [U; 2] + 165..170 'gen()': *mut [U; 2] 185..419 '{ ...rr); }': () - 195..198 'arr': &[u8; _] + 195..198 'arr': &[u8; 1] 211..215 '&[1]': &[u8; 1] 212..215 '[1]': [u8; 1] 213..214 '1': u8 226..227 'a': &[u8] - 236..239 'arr': &[u8; _] + 236..239 'arr': &[u8; 1] 249..250 'b': u8 253..254 'f': fn f(&[u8]) -> u8 253..259 'f(arr)': u8 - 255..258 'arr': &[u8; _] + 255..258 'arr': &[u8; 1] 269..270 'c': &[u8] 279..286 '{ arr }': &[u8] - 281..284 'arr': &[u8; _] + 281..284 'arr': &[u8; 1] 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]; _] + 309..312 'arr': &[u8; 1] + 325..326 'e': [&[u8]; 1] 340..345 '[arr]': [&[u8]; 1] - 341..344 'arr': &[u8; _] - 355..356 'f': [&[u8]; _] + 341..344 'arr': &[u8; 1] + 355..356 'f': [&[u8]; 2] 370..378 '[arr; 2]': [&[u8]; _] - 371..374 'arr': &[u8; _] + 371..374 'arr': &[u8; 1] 376..377 '2': usize 388..389 'g': (&[u8], &[u8]) 406..416 '(arr, arr)': (&[u8], &[u8]) - 407..410 'arr': &[u8; _] - 412..415 'arr': &[u8; _] + 407..410 'arr': &[u8; 1] + 412..415 'arr': &[u8; 1] "#]], ); } @@ -159,7 +159,7 @@ fn infer_custom_coerce_unsized() { 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" + expect![[r#" 257..258 'x': A<[T]> 278..283 '{ x }': A<[T]> 280..281 'x': A<[T]> @@ -169,23 +169,23 @@ fn infer_custom_coerce_unsized() { 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; _]> + 369..370 'a': A<[u8; 2]> + 384..385 'b': B<[u8; 2]> + 399..400 'c': C<[u8; 2]> 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; _]> + 433..434 'a': A<[u8; 2]> 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; _]> + 454..455 'b': B<[u8; 2]> 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; _]> - "]], + 475..476 'c': C<[u8; 2]> + "#]], ); } diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs index 33305f208..b36e77e91 100644 --- a/crates/hir_ty/src/tests/patterns.rs +++ b/crates/hir_ty/src/tests/patterns.rs @@ -345,19 +345,19 @@ fn infer_pattern_match_arr() { "#, expect![[r#" 10..179 '{ ... } }': () - 20..23 'arr': [f64; _] + 20..23 'arr': [f64; 2] 36..46 '[0.0, 1.0]': [f64; 2] 37..40 '0.0': f64 42..45 '1.0': f64 52..177 'match ... }': () - 58..61 'arr': [f64; _] - 72..80 '[1.0, a]': [f64; _] + 58..61 'arr': [f64; 2] + 72..80 '[1.0, a]': [f64; 2] 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; _] + 120..126 '[b, c]': [f64; 2] 121..122 'b': f64 124..125 'c': f64 130..171 '{ ... }': () diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 8b09f2e4a..19775a4ec 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs @@ -1313,7 +1313,7 @@ fn infer_array() { 255..256 'a': [&str; 1] 258..263 '["b"]': [&str; 1] 259..262 '"b"': &str - 274..275 'x': [u8; _] + 274..275 'x': [u8; 0] 287..289 '[]': [u8; 0] "#]], ); @@ -2409,38 +2409,38 @@ fn infer_operator_overload() { 320..422 '{ ... }': V2 334..335 'x': f32 338..342 'self': V2 - 338..344 'self.0': [f32; _] + 338..344 'self.0': [f32; 2] 338..347 'self.0[0]': {unknown} 338..358 'self.0...s.0[0]': f32 345..346 '0': i32 350..353 'rhs': V2 - 350..355 'rhs.0': [f32; _] + 350..355 'rhs.0': [f32; 2] 350..358 'rhs.0[0]': {unknown} 356..357 '0': i32 372..373 'y': f32 376..380 'self': V2 - 376..382 'self.0': [f32; _] + 376..382 'self.0': [f32; 2] 376..385 'self.0[1]': {unknown} 376..396 'self.0...s.0[1]': f32 383..384 '1': i32 388..391 'rhs': V2 - 388..393 'rhs.0': [f32; _] + 388..393 'rhs.0': [f32; 2] 388..396 'rhs.0[1]': {unknown} 394..395 '1': i32 - 406..408 'V2': V2([f32; _]) -> V2 + 406..408 'V2': V2([f32; 2]) -> V2 406..416 'V2([x, y])': V2 409..415 '[x, y]': [f32; 2] 410..411 'x': f32 413..414 'y': f32 436..519 '{ ... vb; }': () 446..448 'va': V2 - 451..453 'V2': V2([f32; _]) -> V2 + 451..453 'V2': V2([f32; 2]) -> V2 451..465 'V2([0.0, 1.0])': V2 454..464 '[0.0, 1.0]': [f32; 2] 455..458 '0.0': f32 460..463 '1.0': f32 475..477 'vb': V2 - 480..482 'V2': V2([f32; _]) -> V2 + 480..482 'V2': V2([f32; 2]) -> V2 480..494 'V2([0.0, 1.0])': V2 483..493 '[0.0, 1.0]': [f32; 2] 484..487 '0.0': f32 -- cgit v1.2.3 From 73023c0299d4adeada026648c3684621f129e038 Mon Sep 17 00:00:00 2001 From: Jade Date: Wed, 12 May 2021 05:44:01 -0700 Subject: Support length for ByteStrings I am not confident that my added byte string parsing is right. --- crates/hir_ty/src/tests/simple.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/hir_ty/src/tests') diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 19775a4ec..79445a12d 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs @@ -496,7 +496,7 @@ fn infer_literals() { 26..30 '5f32': f32 36..40 '5f64': f64 46..53 '"hello"': &str - 59..67 'b"bytes"': &[u8; _] + 59..67 'b"bytes"': &[u8; 5] 73..76 ''c'': char 82..86 'b'b'': u8 92..96 '3.14': f64 @@ -504,7 +504,7 @@ fn infer_literals() { 112..117 'false': bool 123..127 'true': bool 133..197 'r#" ... "#': &str - 203..213 'br#"yolo"#': &[u8; _] + 203..213 'br#"yolo"#': &[u8; 4] "##]], ); } -- cgit v1.2.3 From e666589e63fd4de16baa5f1ebda4ab07aa5a5437 Mon Sep 17 00:00:00 2001 From: Jade Date: Wed, 12 May 2021 05:59:35 -0700 Subject: Add support for lengths in array repeats, if they are literals Now we will get the type of `[0u8; 4]`. --- crates/hir_ty/src/tests/coercion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/hir_ty/src/tests') diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs index c2afaf6ec..190471069 100644 --- a/crates/hir_ty/src/tests/coercion.rs +++ b/crates/hir_ty/src/tests/coercion.rs @@ -93,7 +93,7 @@ fn coerce_places() { 340..345 '[arr]': [&[u8]; 1] 341..344 'arr': &[u8; 1] 355..356 'f': [&[u8]; 2] - 370..378 '[arr; 2]': [&[u8]; _] + 370..378 '[arr; 2]': [&[u8]; 2] 371..374 'arr': &[u8; 1] 376..377 '2': usize 388..389 'g': (&[u8], &[u8]) -- cgit v1.2.3 From 32c600664e5a599bbe3f0254274211474b89914a Mon Sep 17 00:00:00 2001 From: Jade Date: Wed, 12 May 2021 21:22:13 -0700 Subject: Test lowering byte strings some more --- crates/hir_ty/src/tests/simple.rs | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'crates/hir_ty/src/tests') diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 79445a12d..1032f09ac 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs @@ -488,23 +488,34 @@ fn infer_literals() { mod foo {} "#; br#"yolo"#; + let a = b"a\x20b\ + c"; + let b = br"g\ +h"; + let c = br#"x"\"yb"#; } "##, 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; 5] - 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; 4] + 18..478 '{ ... }': () + 32..36 '5i32': i32 + 50..54 '5f32': f32 + 68..72 '5f64': f64 + 86..93 '"hello"': &str + 107..115 'b"bytes"': &[u8; 5] + 129..132 ''c'': char + 146..150 'b'b'': u8 + 164..168 '3.14': f64 + 182..186 '5000': i32 + 200..205 'false': bool + 219..223 'true': bool + 237..333 'r#" ... "#': &str + 347..357 'br#"yolo"#': &[u8; 4] + 375..376 'a': &[u8; 4] + 379..403 'b"a\x2... c"': &[u8; 4] + 421..422 'b': &[u8; 4] + 425..433 'br"g\ h"': &[u8; 4] + 451..452 'c': &[u8; 6] + 455..467 'br#"x"\"yb"#': &[u8; 6] "##]], ); } -- cgit v1.2.3 From 78d6b88f211cc9faf88815ce7fb1a91546cfce15 Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 14 May 2021 00:59:30 -0700 Subject: Add more tests, refactor array lengths/consteval work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #2922: add unknown length as a condition for a type having unknown. Incorporate reviews: * Extract some of the const evaluation workings into functions * Add fixmes on the hacks * Add tests for impls on specific array lengths (these work!!! 😁) * Add tests for const generics (indeed we don't support it yet) --- crates/hir_ty/src/tests/simple.rs | 10 +++- crates/hir_ty/src/tests/traits.rs | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) (limited to 'crates/hir_ty/src/tests') diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 1032f09ac..a9cd42186 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs @@ -1271,12 +1271,14 @@ fn infer_array() { let b = [a, ["b"]]; let x: [u8; 0] = []; + // FIXME: requires const evaluation/taking type from rhs somehow + let y: [u8; 2+2] = [1,2,3,4]; } "#, expect![[r#" 8..9 'x': &str 17..18 'y': isize - 27..292 '{ ... []; }': () + 27..395 '{ ...,4]; }': () 37..38 'a': [&str; 1] 41..44 '[x]': [&str; 1] 42..43 'x': &str @@ -1326,6 +1328,12 @@ fn infer_array() { 259..262 '"b"': &str 274..275 'x': [u8; 0] 287..289 '[]': [u8; 0] + 368..369 'y': [u8; _] + 383..392 '[1,2,3,4]': [u8; 4] + 384..385 '1': u8 + 386..387 '2': u8 + 388..389 '3': u8 + 390..391 '4': u8 "#]], ); } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 47a1455fd..f80cf9879 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -3474,3 +3474,100 @@ fn main(){ "#]], ) } + +#[test] +fn array_length() { + check_infer( + r#" +trait T { + type Output; + fn do_thing(&self) -> Self::Output; +} + +impl T for [u8; 4] { + type Output = usize; + fn do_thing(&self) -> Self::Output { + 2 + } +} + +impl T for [u8; 2] { + type Output = u8; + fn do_thing(&self) -> Self::Output { + 2 + } +} + +fn main() { + let v = [0u8; 2]; + let v2 = v.do_thing(); + let v3 = [0u8; 4]; + let v4 = v3.do_thing(); +} +"#, + expect![[r#" + 44..48 'self': &Self + 133..137 'self': &[u8; 4] + 155..172 '{ ... }': usize + 165..166 '2': usize + 236..240 'self': &[u8; 2] + 258..275 '{ ... }': u8 + 268..269 '2': u8 + 289..392 '{ ...g(); }': () + 299..300 'v': [u8; 2] + 303..311 '[0u8; 2]': [u8; 2] + 304..307 '0u8': u8 + 309..310 '2': usize + 321..323 'v2': u8 + 326..327 'v': [u8; 2] + 326..338 'v.do_thing()': u8 + 348..350 'v3': [u8; 4] + 353..361 '[0u8; 4]': [u8; 4] + 354..357 '0u8': u8 + 359..360 '4': usize + 371..373 'v4': usize + 376..378 'v3': [u8; 4] + 376..389 'v3.do_thing()': usize + "#]], + ) +} + +// FIXME: We should infer the length of the returned array :) +#[test] +fn const_generics() { + check_infer( + r#" +trait T { + type Output; + fn do_thing(&self) -> Self::Output; +} + +impl T for [u8; L] { + type Output = [u8; L]; + fn do_thing(&self) -> Self::Output { + *self + } +} + +fn main() { + let v = [0u8; 2]; + let v2 = v.do_thing(); +} +"#, + expect![[r#" + 44..48 'self': &Self + 151..155 'self': &[u8; _] + 173..194 '{ ... }': [u8; _] + 183..188 '*self': [u8; _] + 184..188 'self': &[u8; _] + 208..260 '{ ...g(); }': () + 218..219 'v': [u8; 2] + 222..230 '[0u8; 2]': [u8; 2] + 223..226 '0u8': u8 + 228..229 '2': usize + 240..242 'v2': [u8; _] + 245..246 'v': [u8; 2] + 245..257 'v.do_thing()': [u8; _] + "#]], + ) +} -- cgit v1.2.3