]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/macros.rs
Merge #11461
[rust.git] / crates / hir_ty / src / tests / macros.rs
index 3eb01dbd0fa3b3be4868f78126aab9aeb40565b1..344e7293c59343fc9faee4ee7b24ebf304da6756 100644 (file)
@@ -27,7 +27,7 @@ fn test() {
 } //^ (i32, {unknown}, i32, {unknown})
 
 //- /foo.rs crate:foo
-struct S;
+pub struct S;
 
 #[cfg(not(test))]
 impl S {
@@ -190,7 +190,6 @@ fn spam() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
-            !0..6 '1isize': isize
             39..442 '{     ...!(); }': ()
             73..94 'spam!(...am!())': {unknown}
             100..119 'for _ ...!() {}': ()
@@ -198,6 +197,7 @@ fn spam() {
             117..119 '{}': ()
             124..134 '|| spam!()': || -> isize
             140..156 'while ...!() {}': ()
+            146..153 'spam!()': bool
             154..156 '{}': ()
             161..174 'break spam!()': !
             180..194 'return spam!()': !
@@ -271,7 +271,6 @@ fn spam() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
-            !0..6 '1isize': isize
             53..456 '{     ...!(); }': ()
             87..108 'spam!(...am!())': {unknown}
             114..133 'for _ ...!() {}': ()
@@ -279,6 +278,7 @@ fn spam() {
             131..133 '{}': ()
             138..148 '|| spam!()': || -> isize
             154..170 'while ...!() {}': ()
+            160..167 'spam!()': bool
             168..170 '{}': ()
             175..188 'break spam!()': !
             194..208 'return spam!()': !
@@ -372,6 +372,32 @@ fn foo() {
     );
 }
 
+#[test]
+fn infer_macro_defining_block_with_items() {
+    check_infer(
+        r#"
+        macro_rules! foo {
+            () => {{
+                fn bar() -> usize { 0 }
+                bar()
+            }};
+        }
+        fn main() {
+            let _a = foo!();
+        }
+    "#,
+        expect![[r#"
+            !15..18 '{0}': usize
+            !16..17 '0': usize
+            !0..24 '{fnbar...bar()}': usize
+            !18..21 'bar': fn bar() -> usize
+            !18..23 'bar()': usize
+            98..122 '{     ...!(); }': ()
+            108..110 '_a': usize
+        "#]],
+    );
+}
+
 #[test]
 fn infer_type_value_macro_having_same_name() {
     check_infer(
@@ -409,11 +435,11 @@ fn processes_impls_generated_by_macros() {
 macro_rules! m {
     ($ident:ident) => (impl Trait for $ident {})
 }
-trait Trait { fn foo(self) -> u128 {} }
+trait Trait { fn foo(self) -> u128 { 0 } }
 struct S;
 m!(S);
 fn test() { S.foo(); }
-                //^ u128
+          //^^^^^^^ u128
 "#,
     );
 }
@@ -431,7 +457,7 @@ impl S {
 }
 
 fn test() { S.foo(); }
-                //^ u128
+          //^^^^^^^ u128
 "#,
     );
 }
@@ -453,7 +479,7 @@ impl S {
 }
 
 fn test() { S.foo(); }
-                //^ u128
+          //^^^^^^^ u128
 "#,
     );
 }
@@ -717,7 +743,7 @@ macro_rules! include {() => {}}
 
 fn main() {
     bar();
-}     //^ u32
+} //^^^^^ u32
 
 //- /foo.rs
 fn bar() -> u32 {0}
@@ -725,6 +751,24 @@ fn bar() -> u32 {0}
     );
 }
 
+#[test]
+fn infer_builtin_macros_include_expression() {
+    check_types(
+        r#"
+//- /main.rs
+#[rustc_builtin_macro]
+macro_rules! include {() => {}}
+fn main() {
+    let i = include!("bla.rs");
+    i;
+  //^ i32
+}
+//- /bla.rs
+0
+        "#,
+    )
+}
+
 #[test]
 fn infer_builtin_macros_include_child_mod() {
     check_types(
@@ -737,7 +781,7 @@ macro_rules! include {() => {}}
 
 fn main() {
     bar::bar();
-}          //^ u32
+} //^^^^^^^^^^ u32
 
 //- /f/foo.rs
 pub mod bar;
@@ -809,7 +853,7 @@ macro_rules! include {() => {}}
 
 fn main() {
     RegisterBlock { };
-                  //^ RegisterBlock
+  //^^^^^^^^^^^^^^^^^ RegisterBlock
 }
     "#;
     let fixture = format!("{}\n//- /foo.rs\n{}", fixture, data);
@@ -835,7 +879,7 @@ macro_rules! concat {() => {}}
 
 fn main() {
     bar();
-}     //^ u32
+} //^^^^^ u32
 
 //- /foo.rs
 fn bar() -> u32 {0}
@@ -861,7 +905,7 @@ macro_rules! env {() => {}}
 
 fn main() {
     bar();
-}     //^ {unknown}
+} //^^^^^ {unknown}
 
 //- /foo.rs
 fn bar() -> u32 {0}
@@ -879,7 +923,7 @@ macro_rules! include {() => {}}
 include!("main.rs");
 
 fn main() {
-            0
+    0;
 } //^ i32
 "#,
     );
@@ -930,49 +974,12 @@ fn main() {
 fn infer_derive_clone_simple() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
+//- minicore: derive, clone
 #[derive(Clone)]
 struct S;
 fn test() {
     S.clone();
-}         //^ S
-
-//- /lib.rs crate:core
-#[prelude_import]
-use clone::*;
-mod clone {
-    trait Clone {
-        fn clone(&self) -> Self;
-    }
-    #[rustc_builtin_macro]
-    macro Clone {}
-}
-"#,
-    );
-}
-
-#[test]
-fn infer_derive_clone_in_core() {
-    check_types(
-        r#"
-//- /lib.rs crate:core
-#[prelude_import]
-use clone::*;
-mod clone {
-    trait Clone {
-        fn clone(&self) -> Self;
-    }
-    #[rustc_builtin_macro]
-    macro Clone {}
-}
-#[derive(Clone)]
-pub struct S;
-
-//- /main.rs crate:main deps:core
-use core::S;
-fn test() {
-    S.clone();
-}         //^ S
+} //^^^^^^^^^ S
 "#,
     );
 }
@@ -981,27 +988,17 @@ fn test() {
 fn infer_derive_clone_with_params() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
+//- minicore: clone, derive
 #[derive(Clone)]
 struct S;
 #[derive(Clone)]
 struct Wrapper<T>(T);
 struct NonClone;
 fn test() {
-    (Wrapper(S).clone(), Wrapper(NonClone).clone());
+    let x = (Wrapper(S).clone(), Wrapper(NonClone).clone());
+    x;
   //^ (Wrapper<S>, {unknown})
 }
-
-//- /lib.rs crate:core
-#[prelude_import]
-use clone::*;
-mod clone {
-    trait Clone {
-        fn clone(&self) -> Self;
-    }
-    #[rustc_builtin_macro]
-    macro Clone {}
-}
 "#,
     );
 }
@@ -1011,7 +1008,7 @@ fn infer_custom_derive_simple() {
     // FIXME: this test current now do nothing
     check_types(
         r#"
-//- /main.rs crate:main
+//- minicore: derive
 use foo::Foo;
 
 #[derive(Foo)]
@@ -1019,7 +1016,7 @@ struct S{}
 
 fn test() {
     S{};
-}   //^ S
+} //^^^ S
 "#,
     );
 }
@@ -1039,12 +1036,211 @@ fn main() {
         }
         "#,
         expect![[r#"
+            !0..2 '()': ()
             51..110 '{     ...  }; }': ()
             61..62 'x': u32
             65..107 'match ...     }': u32
             71..73 '()': ()
-            84..91 'unit!()': ()
             95..100 '92u32': u32
         "#]],
     );
 }
+
+#[test]
+fn macro_in_type_alias_position() {
+    check_infer(
+        r#"
+        macro_rules! U32 {
+            () => { u32 };
+        }
+
+        trait Foo {
+            type Ty;
+        }
+
+        impl<T> Foo for T {
+            type Ty = U32!();
+        }
+
+        type TayTo = U32!();
+
+        fn testy() {
+            let a: <() as Foo>::Ty;
+            let b: TayTo;
+        }
+        "#,
+        expect![[r#"
+            147..196 '{     ...yTo; }': ()
+            157..158 'a': u32
+            185..186 'b': u32
+        "#]],
+    );
+}
+
+#[test]
+fn nested_macro_in_type_alias_position() {
+    check_infer(
+        r#"
+        macro_rules! U32Inner2 {
+            () => { u32 };
+        }
+
+        macro_rules! U32Inner1 {
+            () => { U32Inner2!() };
+        }
+
+        macro_rules! U32 {
+            () => { U32Inner1!() };
+        }
+
+        trait Foo {
+            type Ty;
+        }
+
+        impl<T> Foo for T {
+            type Ty = U32!();
+        }
+
+        type TayTo = U32!();
+
+        fn testy() {
+            let a: <() as Foo>::Ty;
+            let b: TayTo;
+        }
+        "#,
+        expect![[r#"
+            259..308 '{     ...yTo; }': ()
+            269..270 'a': u32
+            297..298 'b': u32
+        "#]],
+    );
+}
+
+#[test]
+fn macros_in_type_alias_position_generics() {
+    check_infer(
+        r#"
+        struct Foo<A, B>(A, B);
+
+        macro_rules! U32 {
+            () => { u32 };
+        }
+
+        macro_rules! Bar {
+            () => { Foo<U32!(), U32!()> };
+        }
+
+        trait Moo {
+            type Ty;
+        }
+
+        impl<T> Moo for T {
+            type Ty = Bar!();
+        }
+
+        type TayTo = Bar!();
+
+        fn main() {
+            let a: <() as Moo>::Ty;
+            let b: TayTo;
+        }
+        "#,
+        expect![[r#"
+            228..277 '{     ...yTo; }': ()
+            238..239 'a': Foo<u32, u32>
+            266..267 'b': Foo<u32, u32>
+        "#]],
+    );
+}
+
+#[test]
+fn macros_in_type_position() {
+    check_infer(
+        r#"
+        struct Foo<A, B>(A, B);
+
+        macro_rules! U32 {
+            () => { u32 };
+        }
+
+        macro_rules! Bar {
+            () => { Foo<U32!(), U32!()> };
+        }
+
+        fn main() {
+            let a: Bar!();
+        }
+        "#,
+        expect![[r#"
+            133..155 '{     ...!(); }': ()
+            143..144 'a': Foo<u32, u32>
+        "#]],
+    );
+}
+
+#[test]
+fn macros_in_type_generics() {
+    check_infer(
+        r#"
+        struct Foo<A, B>(A, B);
+
+        macro_rules! U32 {
+            () => { u32 };
+        }
+
+        macro_rules! Bar {
+            () => { Foo<U32!(), U32!()> };
+        }
+
+        trait Moo {
+            type Ty;
+        }
+
+        impl<T> Moo for T {
+            type Ty = Foo<Bar!(), Bar!()>;
+        }
+
+        type TayTo = Foo<Bar!(), U32!()>;
+
+        fn main() {
+            let a: <() as Moo>::Ty;
+            let b: TayTo;
+        }
+        "#,
+        expect![[r#"
+            254..303 '{     ...yTo; }': ()
+            264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
+            292..293 'b': Foo<Foo<u32, u32>, u32>
+        "#]],
+    );
+}
+
+#[test]
+fn infinitely_recursive_macro_type() {
+    check_infer(
+        r#"
+        struct Bar<T, X>(T, X);
+
+        macro_rules! Foo {
+            () => { Foo!() }
+        }
+
+        macro_rules! U32 {
+            () => { u32 }
+        }
+
+        type A = Foo!();
+        type B = Bar<Foo!(), U32!()>;
+
+        fn main() {
+            let a: A;
+            let b: B;
+        }
+        "#,
+        expect![[r#"
+            166..197 '{     ...: B; }': ()
+            176..177 'a': {unknown}
+            190..191 'b': Bar<{unknown}, u32>
+        "#]],
+    );
+}