aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/tests')
-rw-r--r--crates/hir_ty/src/tests/coercion.rs101
-rw-r--r--crates/hir_ty/src/tests/incremental.rs51
-rw-r--r--crates/hir_ty/src/tests/macros.rs18
-rw-r--r--crates/hir_ty/src/tests/traits.rs157
4 files changed, 320 insertions, 7 deletions
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index bb568ea37..6dac7e103 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -832,11 +832,9 @@ fn coerce_unsize_super_trait_cycle() {
832 ); 832 );
833} 833}
834 834
835#[ignore]
836#[test] 835#[test]
837fn coerce_unsize_generic() { 836fn coerce_unsize_generic() {
838 // FIXME: Implement this 837 // FIXME: fix the type mismatches here
839 // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
840 check_infer_with_mismatches( 838 check_infer_with_mismatches(
841 r#" 839 r#"
842 #[lang = "unsize"] 840 #[lang = "unsize"]
@@ -854,8 +852,58 @@ fn coerce_unsize_generic() {
854 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); 852 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
855 } 853 }
856 "#, 854 "#,
857 expect![[r" 855 expect![[r#"
858 "]], 856 209..317 '{ ... }); }': ()
857 219..220 '_': &Foo<[usize]>
858 238..259 '&Foo {..., 3] }': &Foo<[usize]>
859 239..259 'Foo { ..., 3] }': Foo<[usize]>
860 248..257 '[1, 2, 3]': [usize; 3]
861 249..250 '1': usize
862 252..253 '2': usize
863 255..256 '3': usize
864 269..270 '_': &Bar<[usize]>
865 288..314 '&Bar(F... 3] })': &Bar<[i32; 3]>
866 289..292 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
867 289..314 'Bar(Fo... 3] })': Bar<[i32; 3]>
868 293..313 'Foo { ..., 3] }': Foo<[i32; 3]>
869 302..311 '[1, 2, 3]': [i32; 3]
870 303..304 '1': i32
871 306..307 '2': i32
872 309..310 '3': i32
873 248..257: expected [usize], got [usize; 3]
874 288..314: expected &Bar<[usize]>, got &Bar<[i32; 3]>
875 "#]],
876 );
877}
878
879#[test]
880fn coerce_unsize_apit() {
881 // FIXME: #8984
882 check_infer_with_mismatches(
883 r#"
884#[lang = "sized"]
885pub trait Sized {}
886#[lang = "unsize"]
887pub trait Unsize<T> {}
888#[lang = "coerce_unsized"]
889pub trait CoerceUnsized<T> {}
890
891impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
892
893trait Foo {}
894
895fn test(f: impl Foo) {
896 let _: &dyn Foo = &f;
897}
898 "#,
899 expect![[r#"
900 210..211 'f': impl Foo
901 223..252 '{ ... &f; }': ()
902 233..234 '_': &dyn Foo
903 247..249 '&f': &impl Foo
904 248..249 'f': impl Foo
905 247..249: expected &dyn Foo, got &impl Foo
906 "#]],
859 ); 907 );
860} 908}
861 909
@@ -912,3 +960,46 @@ fn test() -> i32 {
912 "#, 960 "#,
913 ) 961 )
914} 962}
963
964#[test]
965fn panic_macro() {
966 check_infer_with_mismatches(
967 r#"
968mod panic {
969 #[macro_export]
970 pub macro panic_2015 {
971 () => (
972 $crate::panicking::panic()
973 ),
974 }
975}
976
977mod panicking {
978 pub fn panic() -> ! { loop {} }
979}
980
981#[rustc_builtin_macro = "core_panic"]
982macro_rules! panic {
983 // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
984 // depending on the edition of the caller.
985 ($($arg:tt)*) => {
986 /* compiler built-in */
987 };
988}
989
990fn main() {
991 panic!()
992}
993 "#,
994 expect![[r#"
995 174..185 '{ loop {} }': !
996 176..183 'loop {}': !
997 181..183 '{}': ()
998 !0..24 '$crate...:panic': fn panic() -> !
999 !0..26 '$crate...anic()': !
1000 !0..26 '$crate...anic()': !
1001 !0..28 '$crate...015!()': !
1002 454..470 '{ ...c!() }': ()
1003 "#]],
1004 );
1005}
diff --git a/crates/hir_ty/src/tests/incremental.rs b/crates/hir_ty/src/tests/incremental.rs
new file mode 100644
index 000000000..3e08e83e8
--- /dev/null
+++ b/crates/hir_ty/src/tests/incremental.rs
@@ -0,0 +1,51 @@
1use std::sync::Arc;
2
3use base_db::{fixture::WithFixture, SourceDatabaseExt};
4
5use crate::{db::HirDatabase, test_db::TestDB};
6
7use super::visit_module;
8
9#[test]
10fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
11 let (mut db, pos) = TestDB::with_position(
12 "
13 //- /lib.rs
14 fn foo() -> i32 {
15 $01 + 1
16 }
17 ",
18 );
19 {
20 let events = db.log_executed(|| {
21 let module = db.module_for_file(pos.file_id);
22 let crate_def_map = module.def_map(&db);
23 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
24 db.infer(def);
25 });
26 });
27 assert!(format!("{:?}", events).contains("infer"))
28 }
29
30 let new_text = "
31 fn foo() -> i32 {
32 1
33 +
34 1
35 }
36 "
37 .to_string();
38
39 db.set_file_text(pos.file_id, Arc::new(new_text));
40
41 {
42 let events = db.log_executed(|| {
43 let module = db.module_for_file(pos.file_id);
44 let crate_def_map = module.def_map(&db);
45 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
46 db.infer(def);
47 });
48 });
49 assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
50 }
51}
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 6588aa46c..7647bb08b 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -752,6 +752,24 @@ fn bar() -> u32 {0}
752} 752}
753 753
754#[test] 754#[test]
755fn infer_builtin_macros_include_expression() {
756 check_types(
757 r#"
758//- /main.rs
759#[rustc_builtin_macro]
760macro_rules! include {() => {}}
761fn main() {
762 let i = include!("bla.rs");
763 i;
764 //^ i32
765}
766//- /bla.rs
7670
768 "#,
769 )
770}
771
772#[test]
755fn infer_builtin_macros_include_child_mod() { 773fn infer_builtin_macros_include_child_mod() {
756 check_types( 774 check_types(
757 r#" 775 r#"
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index a5a2df54c..49add4ab9 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -161,6 +161,58 @@ mod result {
161} 161}
162 162
163#[test] 163#[test]
164fn infer_try_trait_v2() {
165 check_types(
166 r#"
167//- /main.rs crate:main deps:core
168fn test() {
169 let r: Result<i32, u64> = Result::Ok(1);
170 let v = r?;
171 v;
172} //^ i32
173
174//- /core.rs crate:core
175mod ops {
176 mod try_trait {
177 pub trait Try: FromResidual {
178 type Output;
179 type Residual;
180 }
181 pub trait FromResidual<R = <Self as Try>::Residual> {}
182 }
183
184 pub use self::try_trait::FromResidual;
185 pub use self::try_trait::Try;
186}
187
188mov convert {
189 pub trait From<T> {}
190 impl<T> From<T> for T {}
191}
192
193#[prelude_import] use result::*;
194mod result {
195 use crate::convert::From;
196 use crate::ops::{Try, FromResidual};
197
198 pub enum Infallible {}
199 pub enum Result<O, E> {
200 Ok(O),
201 Err(E)
202 }
203
204 impl<O, E> Try for Result<O, E> {
205 type Output = O;
206 type Error = Result<Infallible, E>;
207 }
208
209 impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {}
210}
211"#,
212 );
213}
214
215#[test]
164fn infer_for_loop() { 216fn infer_for_loop() {
165 check_types( 217 check_types(
166 r#" 218 r#"
@@ -3041,7 +3093,7 @@ fn infer_fn_trait_arg() {
3041 3093
3042#[test] 3094#[test]
3043fn infer_box_fn_arg() { 3095fn infer_box_fn_arg() {
3044 // The type mismatch is a bug 3096 // The type mismatch is because we don't define Unsize and CoerceUnsized
3045 check_infer_with_mismatches( 3097 check_infer_with_mismatches(
3046 r#" 3098 r#"
3047//- /lib.rs deps:std 3099//- /lib.rs deps:std
@@ -3101,7 +3153,7 @@ fn foo() {
3101 555..557 'ps': {unknown} 3153 555..557 'ps': {unknown}
3102 559..561 '{}': () 3154 559..561 '{}': ()
3103 568..569 'f': Box<dyn FnOnce(&Option<i32>)> 3155 568..569 'f': Box<dyn FnOnce(&Option<i32>)>
3104 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3156 568..573 'f(&s)': ()
3105 570..572 '&s': &Option<i32> 3157 570..572 '&s': &Option<i32>
3106 571..572 's': Option<i32> 3158 571..572 's': Option<i32>
3107 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()> 3159 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
@@ -3571,3 +3623,104 @@ fn main() {
3571 "#]], 3623 "#]],
3572 ) 3624 )
3573} 3625}
3626
3627#[test]
3628fn fn_returning_unit() {
3629 check_infer_with_mismatches(
3630 r#"
3631#[lang = "fn_once"]
3632trait FnOnce<Args> {
3633 type Output;
3634}
3635
3636fn test<F: FnOnce()>(f: F) {
3637 let _: () = f();
3638}"#,
3639 expect![[r#"
3640 82..83 'f': F
3641 88..112 '{ ...f(); }': ()
3642 98..99 '_': ()
3643 106..107 'f': F
3644 106..109 'f()': ()
3645 "#]],
3646 );
3647}
3648
3649#[test]
3650fn trait_in_scope_of_trait_impl() {
3651 check_infer(
3652 r#"
3653mod foo {
3654 pub trait Foo {
3655 fn foo(self);
3656 fn bar(self) -> usize { 0 }
3657 }
3658}
3659impl foo::Foo for u32 {
3660 fn foo(self) {
3661 let _x = self.bar();
3662 }
3663}
3664 "#,
3665 expect![[r#"
3666 45..49 'self': Self
3667 67..71 'self': Self
3668 82..87 '{ 0 }': usize
3669 84..85 '0': usize
3670 131..135 'self': u32
3671 137..173 '{ ... }': ()
3672 151..153 '_x': usize
3673 156..160 'self': u32
3674 156..166 'self.bar()': usize
3675 "#]],
3676 );
3677}
3678
3679#[test]
3680fn infer_async_ret_type() {
3681 check_types(
3682 r#"
3683//- /main.rs crate:main deps:core
3684
3685enum Result<T, E> {
3686 Ok(T),
3687 Err(E),
3688}
3689
3690use Result::*;
3691
3692
3693struct Fooey;
3694
3695impl Fooey {
3696 fn collect<B: Convert>(self) -> B {
3697 B::new()
3698 }
3699}
3700
3701trait Convert {
3702 fn new() -> Self;
3703}
3704impl Convert for u32 {
3705 fn new() -> Self {
3706 0
3707 }
3708}
3709
3710async fn get_accounts() -> Result<u32, ()> {
3711 let ret = Fooey.collect();
3712 // ^ u32
3713 Ok(ret)
3714}
3715
3716//- /core.rs crate:core
3717#[prelude_import] use future::*;
3718mod future {
3719 #[lang = "future_trait"]
3720 trait Future {
3721 type Output;
3722 }
3723}
3724"#,
3725 );
3726}