]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/simple.rs
hir_ty: fix visibility in infer_inherent_method test
[rust.git] / crates / hir_ty / src / tests / simple.rs
index 59eb59d5fab036df05d68e98fdc919a910e52e6b..361cd63026fdec3662d8195c4809d97bea5551b1 100644 (file)
@@ -1,4 +1,4 @@
-use expect::expect;
+use expect_test::expect;
 
 use super::{check_infer, check_types};
 
@@ -27,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; _], {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(
@@ -1079,7 +1103,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 {}
             }
         }
 
@@ -1093,21 +1117,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
         "#]],
     );
 }
@@ -1889,31 +1913,45 @@ fn main() {
 fn effects_smoke_test() {
     check_infer(
         r#"
-        fn main() {
+        async fn main() {
             let x = unsafe { 92 };
             let y = async { async { () }.await };
             let z = try { () };
+            let w = const { 92 };
             let t = 'a: { 92 };
         }
+
+        #[prelude_import] use future::*;
+
+        mod future {
+            #[lang = "future_trait"]
+            pub trait Future { type Output; }
+        }
         "#,
         expect![[r#"
-            10..130 '{     ...2 }; }': ()
-            20..21 'x': i32
-            24..37 'unsafe { 92 }': i32
-            31..37 '{ 92 }': i32
-            33..35 '92': i32
-            47..48 'y': {unknown}
-            57..79 '{ asyn...wait }': {unknown}
-            59..77 'async ....await': {unknown}
-            65..71 '{ () }': ()
-            67..69 '()': ()
-            89..90 'z': {unknown}
-            93..103 'try { () }': {unknown}
-            97..103 '{ () }': ()
-            99..101 '()': ()
-            113..114 't': i32
-            121..127 '{ 92 }': i32
-            123..125 '92': i32
+            16..162 '{     ...2 }; }': ()
+            26..27 'x': i32
+            30..43 'unsafe { 92 }': i32
+            37..43 '{ 92 }': i32
+            39..41 '92': i32
+            53..54 'y': impl Future<Output = ()>
+            57..85 'async ...wait }': impl Future<Output = ()>
+            63..85 '{ asyn...wait }': ()
+            65..77 'async { () }': impl Future<Output = ()>
+            65..83 'async ....await': ()
+            71..77 '{ () }': ()
+            73..75 '()': ()
+            95..96 'z': {unknown}
+            99..109 'try { () }': {unknown}
+            103..109 '{ () }': ()
+            105..107 '()': ()
+            119..120 'w': i32
+            123..135 'const { 92 }': i32
+            129..135 '{ 92 }': i32
+            131..133 '92': i32
+            145..146 't': i32
+            153..159 '{ 92 }': i32
+            155..157 '92': i32
         "#]],
     )
 }
@@ -2064,6 +2102,62 @@ fn foo() {
     );
 }
 
+#[test]
+fn infer_labelled_block_break_with_val() {
+    check_infer(
+        r#"
+        fn default<T>() -> T { loop {} }
+        fn foo() {
+            let _x = 'outer: {
+                let inner = 'inner: {
+                    let i = default();
+                    if (break 'outer i) {
+                        break 'inner 5i8;
+                    } else if true {
+                        break 'inner 6;
+                    }
+                    break 'inner 'innermost: { 0 };
+                    42
+                };
+                break 'outer inner < 8;
+            };
+        }
+        "#,
+        expect![[r#"
+            21..32 '{ loop {} }': T
+            23..30 'loop {}': !
+            28..30 '{}': ()
+            42..381 '{     ...  }; }': ()
+            52..54 '_x': bool
+            65..378 '{     ...     }': bool
+            79..84 'inner': i8
+            95..339 '{     ...     }': i8
+            113..114 'i': bool
+            117..124 'default': fn default<bool>() -> bool
+            117..126 'default()': bool
+            140..270 'if (br...     }': ()
+            144..158 'break 'outer i': !
+            157..158 'i': bool
+            160..209 '{     ...     }': ()
+            178..194 'break ...er 5i8': !
+            191..194 '5i8': i8
+            215..270 'if tru...     }': ()
+            218..222 'true': bool
+            223..270 '{     ...     }': ()
+            241..255 'break 'inner 6': !
+            254..255 '6': i8
+            283..313 'break ... { 0 }': !
+            308..313 '{ 0 }': i8
+            310..311 '0': i8
+            327..329 '42': i8
+            349..371 'break ...er < 8': !
+            362..367 'inner': i8
+            362..371 'inner < 8': bool
+            370..371 '8': i8
+        "#]],
+    );
+}
+
 #[test]
 fn generic_default() {
     check_infer(
@@ -2216,3 +2310,257 @@ fn test(t1: Thing) {
         "#]],
     );
 }
+
+#[test]
+fn infer_operator_overload() {
+    cov_mark::check!(infer_expr_inner_binary_operator_overload);
+
+    check_infer(
+        r#"
+        struct V2([f32; 2]);
+
+        #[lang = "add"]
+        pub trait Add<Rhs = Self> {
+            /// The resulting type after applying the `+` operator.
+            type Output;
+
+            /// Performs the `+` operation.
+            #[must_use]
+            fn add(self, rhs: Rhs) -> Self::Output;
+        }
+
+        impl Add<V2> for V2 {
+            type Output = V2;
+
+            fn add(self, rhs: V2) -> V2 {
+                let x = self.0[0] + rhs.0[0];
+                let y = self.0[1] + rhs.0[1];
+                V2([x, y])
+            }
+        }
+
+        fn test() {
+            let va = V2([0.0, 1.0]);
+            let vb = V2([0.0, 1.0]);
+
+            let r = va + vb;
+        }
+
+        "#,
+        expect![[r#"
+            207..211 'self': Self
+            213..216 'rhs': Rhs
+            299..303 'self': V2
+            305..308 'rhs': V2
+            320..422 '{     ...     }': V2
+            334..335 'x': f32
+            338..342 'self': V2
+            338..344 'self.0': [f32; _]
+            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..358 'rhs.0[0]': {unknown}
+            356..357 '0': i32
+            372..373 'y': f32
+            376..380 'self': V2
+            376..382 'self.0': [f32; _]
+            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..396 'rhs.0[1]': {unknown}
+            394..395 '1': i32
+            406..408 'V2': V2([f32; _]) -> V2
+            406..416 'V2([x, y])': V2
+            409..415 '[x, y]': [f32; _]
+            410..411 'x': f32
+            413..414 'y': f32
+            436..519 '{     ... vb; }': ()
+            446..448 'va': V2
+            451..453 'V2': V2([f32; _]) -> V2
+            451..465 'V2([0.0, 1.0])': V2
+            454..464 '[0.0, 1.0]': [f32; _]
+            455..458 '0.0': f32
+            460..463 '1.0': f32
+            475..477 'vb': V2
+            480..482 'V2': V2([f32; _]) -> V2
+            480..494 'V2([0.0, 1.0])': V2
+            483..493 '[0.0, 1.0]': [f32; _]
+            484..487 '0.0': f32
+            489..492 '1.0': f32
+            505..506 'r': V2
+            509..511 'va': V2
+            509..516 'va + vb': V2
+            514..516 'vb': V2
+        "#]],
+    );
+}
+
+#[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; _], Global>
+            684..690 '[1i32]': [i32; _]
+            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}
+}
+    "#,
+    )
+}