]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/simple.rs
Add more tests, refactor array lengths/consteval work
[rust.git] / crates / hir_ty / src / tests / simple.rs
index a61282d5a744222e63a27e374768d50490f0d69a..a9cd42186ed01af5c1eb42c99777ea520f329021 100644 (file)
@@ -1,5 +1,4 @@
 use expect_test::expect;
-use test_utils::mark;
 
 use super::{check_infer, check_types};
 
@@ -12,7 +11,7 @@ fn test() {
     let x = box 1;
     let t = (x, box x, box &1, box [1]);
     t;
-} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; _]>)
+} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; 1]>)
 
 //- /std.rs crate:std
 #[prelude_import] use prelude::*;
@@ -28,6 +27,30 @@ pub struct Box<T: ?Sized> {
     );
 }
 
+#[test]
+fn infer_box_with_allocator() {
+    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<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>)
+
+//- /std.rs crate:std
+#[prelude_import] use prelude::*;
+mod boxed {
+    #[lang = "owned_box"]
+    pub struct Box<T: ?Sized, A: Allocator> {
+        inner: *mut T,
+        allocator: A,
+    }
+}
+"#,
+    );
+}
+
 #[test]
 fn infer_adt_self() {
     check_types(
@@ -465,23 +488,34 @@ fn test() {
                 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; _]
-            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; _]
+            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]
         "##]],
     );
 }
@@ -1005,6 +1039,42 @@ fn main(foo: Foo) {
     )
 }
 
+#[test]
+fn infer_closure_unify() {
+    check_infer(
+        r#"
+        fn foo(f: bool) {
+            let a = |x| x;
+            let b = |x| x;
+            let id = if f { a } else { b };
+            id(123);
+        }
+        "#,
+        expect![[r#"
+            7..8 'f': bool
+            16..106 '{     ...23); }': ()
+            26..27 'a': |i32| -> i32
+            30..35 '|x| x': |i32| -> i32
+            31..32 'x': i32
+            34..35 'x': i32
+            45..46 'b': |i32| -> i32
+            49..54 '|x| x': |i32| -> i32
+            50..51 'x': i32
+            53..54 'x': i32
+            64..66 'id': |i32| -> i32
+            69..90 'if f {... { b }': |i32| -> i32
+            72..73 'f': bool
+            74..79 '{ a }': |i32| -> i32
+            76..77 'a': |i32| -> i32
+            85..90 '{ b }': |i32| -> i32
+            87..88 'b': |i32| -> i32
+            96..98 'id': |i32| -> i32
+            96..103 'id(123)': i32
+            99..102 '123': i32
+        "#]],
+    )
+}
+
 #[test]
 fn infer_if_match_with_return() {
     check_infer(
@@ -1080,7 +1150,7 @@ fn foo(self, x: u32) -> i32 {}
 
         mod b {
             impl super::A {
-                fn bar(&self, x: u64) -> i64 {}
+                pub fn bar(&self, x: u64) -> i64 {}
             }
         }
 
@@ -1094,21 +1164,21 @@ fn test(a: A) {
             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
+            106..110 'self': &A
+            112..113 'x': u64
+            127..129 '{}': ()
+            147..148 'a': A
+            153..201 '{     ...(1); }': ()
+            159..160 'a': A
+            159..167 'a.foo(1)': i32
+            165..166 '1': u32
+            173..184 '(&a).bar(1)': i64
+            174..176 '&a': &A
+            175..176 'a': A
+            182..183 '1': u64
+            190..191 'a': A
+            190..198 'a.bar(1)': i64
+            196..197 '1': u64
         "#]],
     );
 }
@@ -1201,61 +1271,69 @@ fn test(x: &str, y: isize) {
 
             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 '{     ... []; }': ()
-            37..38 'a': [&str; _]
-            41..44 '[x]': [&str; _]
+            27..395 '{     ...,4]; }': ()
+            37..38 'a': [&str; 1]
+            41..44 '[x]': [&str; 1]
             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; _]
+            54..55 'b': [[&str; 1]; 2]
+            58..64 '[a, a]': [[&str; 1]; 2]
+            59..60 'a': [&str; 1]
+            62..63 'a': [&str; 1]
+            74..75 'c': [[[&str; 1]; 2]; 2]
+            78..84 '[b, b]': [[[&str; 1]; 2]; 2]
+            79..80 'b': [[&str; 1]; 2]
+            82..83 'b': [[&str; 1]; 2]
+            95..96 'd': [isize; 4]
+            99..111 '[y, 1, 2, 3]': [isize; 4]
             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; _]
+            121..122 'd': [isize; 4]
+            125..137 '[1, y, 2, 3]': [isize; 4]
             126..127 '1': isize
             129..130 'y': isize
             132..133 '2': isize
             135..136 '3': isize
-            147..148 'e': [isize; _]
-            151..154 '[y]': [isize; _]
+            147..148 'e': [isize; 1]
+            151..154 '[y]': [isize; 1]
             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; _]
+            164..165 'f': [[isize; 4]; 2]
+            168..174 '[d, d]': [[isize; 4]; 2]
+            169..170 'd': [isize; 4]
+            172..173 'd': [isize; 4]
+            184..185 'g': [[isize; 1]; 2]
+            188..194 '[e, e]': [[isize; 1]; 2]
+            189..190 'e': [isize; 1]
+            192..193 'e': [isize; 1]
+            205..206 'h': [i32; 2]
+            209..215 '[1, 2]': [i32; 2]
             210..211 '1': i32
             213..214 '2': i32
-            225..226 'i': [&str; _]
-            229..239 '["a", "b"]': [&str; _]
+            225..226 'i': [&str; 2]
+            229..239 '["a", "b"]': [&str; 2]
             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; _]
+            250..251 'b': [[&str; 1]; 2]
+            254..264 '[a, ["b"]]': [[&str; 1]; 2]
+            255..256 'a': [&str; 1]
+            258..263 '["b"]': [&str; 1]
             259..262 '"b"': &str
-            274..275 'x': [u8; _]
-            287..289 '[]': [u8; _]
+            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
         "#]],
     );
 }
@@ -1741,6 +1819,24 @@ fn main() {
     );
 }
 
+#[test]
+fn shadowing_primitive_with_inner_items() {
+    check_types(
+        r#"
+struct i32;
+struct Foo;
+
+impl i32 { fn foo(&self) -> Foo { Foo } }
+
+fn main() {
+    fn inner() {}
+    let x: i32 = i32;
+    x.foo();
+        //^ Foo
+}"#,
+    );
+}
+
 #[test]
 fn not_shadowing_primitive_by_module() {
     check_types(
@@ -2290,7 +2386,7 @@ fn test(t1: Thing) {
 
 #[test]
 fn infer_operator_overload() {
-    mark::check!(infer_expr_inner_binary_operator_overload);
+    cov_mark::check!(infer_expr_inner_binary_operator_overload);
 
     check_infer(
         r#"
@@ -2332,40 +2428,40 @@ fn test() {
             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; _]
+            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; _]
+            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; _]
+            483..493 '[0.0, 1.0]': [f32; 2]
             484..487 '0.0': f32
             489..492 '1.0': f32
             505..506 'r': V2
@@ -2375,3 +2471,202 @@ fn test() {
         "#]],
     );
 }
+
+#[test]
+fn infer_const_params() {
+    check_infer(
+        r#"
+        fn foo<const FOO: usize>() {
+            let bar = FOO;
+        }
+        "#,
+        expect![[r#"
+            27..49 '{     ...FOO; }': ()
+            37..40 'bar': usize
+            43..46 'FOO': usize
+        "#]],
+    );
+}
+
+#[test]
+fn infer_inner_type() {
+    check_infer(
+        r#"
+        fn foo() {
+            struct S { field: u32 }
+            let s = S { field: 0 };
+            let f = s.field;
+        }
+    "#,
+        expect![[r#"
+            9..89 '{     ...eld; }': ()
+            47..48 's': S
+            51..65 'S { field: 0 }': S
+            62..63 '0': u32
+            75..76 'f': u32
+            79..80 's': S
+            79..86 's.field': u32
+        "#]],
+    );
+}
+
+#[test]
+fn infer_nested_inner_type() {
+    check_infer(
+        r#"
+        fn foo() {
+            {
+                let s = S { field: 0 };
+                let f = s.field;
+            }
+            struct S { field: u32 }
+        }
+    "#,
+        expect![[r#"
+            9..109 '{     ...32 } }': ()
+            15..79 '{     ...     }': ()
+            29..30 's': S
+            33..47 'S { field: 0 }': S
+            44..45 '0': u32
+            61..62 'f': u32
+            65..66 's': S
+            65..72 's.field': u32
+        "#]],
+    );
+}
+
+#[test]
+fn inner_use_enum_rename() {
+    check_infer(
+        r#"
+        enum Request {
+            Info
+        }
+
+        fn f() {
+            use Request as R;
+
+            let r = R::Info;
+            match r {
+                R::Info => {}
+            }
+        }
+    "#,
+        expect![[r#"
+            34..123 '{     ...   } }': ()
+            67..68 'r': Request
+            71..78 'R::Info': Request
+            84..121 'match ...     }': ()
+            90..91 'r': Request
+            102..109 'R::Info': Request
+            113..115 '{}': ()
+        "#]],
+    )
+}
+
+#[test]
+fn box_into_vec() {
+    check_infer(
+        r#"
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "unsize"]
+pub trait Unsize<T: ?Sized> {}
+
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T> {}
+
+pub unsafe trait Allocator {}
+
+pub struct Global;
+unsafe impl Allocator for Global {}
+
+#[lang = "owned_box"]
+#[fundamental]
+pub struct Box<T: ?Sized, A: Allocator = Global>;
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
+
+pub struct Vec<T, A: Allocator = Global> {}
+
+#[lang = "slice"]
+impl<T> [T] {}
+
+#[lang = "slice_alloc"]
+impl<T> [T] {
+    pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
+        unimplemented!()
+    }
+}
+
+fn test() {
+    let vec = <[_]>::into_vec(box [1i32]);
+}
+"#,
+        expect![[r#"
+            569..573 'self': Box<[T], A>
+            602..634 '{     ...     }': Vec<T, A>
+            612..628 'unimpl...ted!()': Vec<T, A>
+            648..694 '{     ...2]); }': ()
+            658..661 'vec': Vec<i32, Global>
+            664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
+            664..691 '<[_]>:...1i32])': Vec<i32, Global>
+            680..690 'box [1i32]': Box<[i32; 1], Global>
+            684..690 '[1i32]': [i32; 1]
+            685..689 '1i32': i32
+        "#]],
+    )
+}
+
+#[test]
+fn cfgd_out_assoc_items() {
+    check_types(
+        r#"
+struct S;
+
+impl S {
+    #[cfg(FALSE)]
+    const C: S = S;
+}
+
+fn f() {
+    S::C;
+  //^^^^ {unknown}
+}
+    "#,
+    )
+}
+
+#[test]
+fn infer_type_alias_variant() {
+    check_infer(
+        r#"
+type Qux = Foo;
+enum Foo {
+    Bar(i32),
+    Baz { baz: f32 }
+}
+
+fn f() {
+    match Foo::Bar(3) {
+        Qux::Bar(bar) => (),
+        Qux::Baz { baz } => (),
+    }
+}
+    "#,
+        expect![[r#"
+            72..166 '{     ...   } }': ()
+            78..164 'match ...     }': ()
+            84..92 'Foo::Bar': Bar(i32) -> Foo
+            84..95 'Foo::Bar(3)': Foo
+            93..94 '3': i32
+            106..119 'Qux::Bar(bar)': Foo
+            115..118 'bar': i32
+            123..125 '()': ()
+            135..151 'Qux::B... baz }': Foo
+            146..149 'baz': f32
+            155..157 '()': ()
+        "#]],
+    )
+}