diff options
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index d92d4659b..c4bddde85 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3643,6 +3643,231 @@ fn test<T: Trait1<Type = u32>>(x: T) { | |||
3643 | "### | 3643 | "### |
3644 | ); | 3644 | ); |
3645 | } | 3645 | } |
3646 | |||
3647 | #[test] | ||
3648 | fn where_clause_trait_in_scope_for_method_resolution() { | ||
3649 | let t = type_at( | ||
3650 | r#" | ||
3651 | //- /main.rs | ||
3652 | mod foo { | ||
3653 | trait Trait { | ||
3654 | fn foo(&self) -> u32 {} | ||
3655 | } | ||
3656 | } | ||
3657 | |||
3658 | fn test<T: foo::Trait>(x: T) { | ||
3659 | x.foo()<|>; | ||
3660 | } | ||
3661 | "#, | ||
3662 | ); | ||
3663 | assert_eq!(t, "u32"); | ||
3664 | } | ||
3665 | |||
3666 | #[test] | ||
3667 | fn super_trait_method_resolution() { | ||
3668 | assert_snapshot!( | ||
3669 | infer(r#" | ||
3670 | mod foo { | ||
3671 | trait SuperTrait { | ||
3672 | fn foo(&self) -> u32 {} | ||
3673 | } | ||
3674 | } | ||
3675 | trait Trait1: foo::SuperTrait {} | ||
3676 | trait Trait2 where Self: foo::SuperTrait {} | ||
3677 | |||
3678 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { | ||
3679 | x.foo(); | ||
3680 | y.foo(); | ||
3681 | } | ||
3682 | "#), | ||
3683 | @r###" | ||
3684 | [50; 54) 'self': &Self | ||
3685 | [63; 65) '{}': () | ||
3686 | [182; 183) 'x': T | ||
3687 | [188; 189) 'y': U | ||
3688 | [194; 223) '{ ...o(); }': () | ||
3689 | [200; 201) 'x': T | ||
3690 | [200; 207) 'x.foo()': u32 | ||
3691 | [213; 214) 'y': U | ||
3692 | [213; 220) 'y.foo()': u32 | ||
3693 | "### | ||
3694 | ); | ||
3695 | } | ||
3696 | |||
3697 | #[test] | ||
3698 | fn super_trait_cycle() { | ||
3699 | // This just needs to not crash | ||
3700 | assert_snapshot!( | ||
3701 | infer(r#" | ||
3702 | trait A: B {} | ||
3703 | trait B: A {} | ||
3704 | |||
3705 | fn test<T: A>(x: T) { | ||
3706 | x.foo(); | ||
3707 | } | ||
3708 | "#), | ||
3709 | @r###" | ||
3710 | [44; 45) 'x': T | ||
3711 | [50; 66) '{ ...o(); }': () | ||
3712 | [56; 57) 'x': T | ||
3713 | [56; 63) 'x.foo()': {unknown} | ||
3714 | "### | ||
3715 | ); | ||
3716 | } | ||
3717 | |||
3718 | #[test] | ||
3719 | fn super_trait_assoc_type_bounds() { | ||
3720 | assert_snapshot!( | ||
3721 | infer(r#" | ||
3722 | trait SuperTrait { type Type; } | ||
3723 | trait Trait where Self: SuperTrait {} | ||
3724 | |||
3725 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | ||
3726 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | ||
3727 | |||
3728 | struct S<T>; | ||
3729 | impl<T> SuperTrait for S<T> { type Type = T; } | ||
3730 | impl<T> Trait for S<T> {} | ||
3731 | |||
3732 | fn test() { | ||
3733 | get2(set(S)); | ||
3734 | } | ||
3735 | "#), | ||
3736 | @r###" | ||
3737 | [103; 104) 't': T | ||
3738 | [114; 116) '{}': () | ||
3739 | [146; 147) 't': T | ||
3740 | [157; 160) '{t}': T | ||
3741 | [158; 159) 't': T | ||
3742 | [259; 280) '{ ...S)); }': () | ||
3743 | [265; 269) 'get2': fn get2<u64, S<u64>>(T) -> U | ||
3744 | [265; 277) 'get2(set(S))': u64 | ||
3745 | [270; 273) 'set': fn set<S<u64>>(T) -> T | ||
3746 | [270; 276) 'set(S)': S<u64> | ||
3747 | [274; 275) 'S': S<u64> | ||
3748 | "### | ||
3749 | ); | ||
3750 | } | ||
3751 | |||
3752 | #[test] | ||
3753 | fn fn_trait() { | ||
3754 | assert_snapshot!( | ||
3755 | infer(r#" | ||
3756 | trait FnOnce<Args> { | ||
3757 | type Output; | ||
3758 | |||
3759 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; | ||
3760 | } | ||
3761 | |||
3762 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | ||
3763 | f.call_once((1, 2)); | ||
3764 | } | ||
3765 | "#), | ||
3766 | @r###" | ||
3767 | [57; 61) 'self': Self | ||
3768 | [63; 67) 'args': Args | ||
3769 | [150; 151) 'f': F | ||
3770 | [156; 184) '{ ...2)); }': () | ||
3771 | [162; 163) 'f': F | ||
3772 | [162; 181) 'f.call...1, 2))': {unknown} | ||
3773 | [174; 180) '(1, 2)': (u32, u64) | ||
3774 | [175; 176) '1': u32 | ||
3775 | [178; 179) '2': u64 | ||
3776 | "### | ||
3777 | ); | ||
3778 | } | ||
3779 | |||
3780 | #[test] | ||
3781 | fn closure_1() { | ||
3782 | assert_snapshot!( | ||
3783 | infer(r#" | ||
3784 | trait FnOnce<Args> { | ||
3785 | type Output; | ||
3786 | } | ||
3787 | |||
3788 | enum Option<T> { Some(T), None } | ||
3789 | impl<T> Option<T> { | ||
3790 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> U {} | ||
3791 | } | ||
3792 | |||
3793 | fn test() { | ||
3794 | let x = Option::Some(1i32); | ||
3795 | x.map(|v| v + 1); | ||
3796 | x.map(|_v| 1u64); | ||
3797 | let y: Option<i64> = x.map(|_v| 1); | ||
3798 | } | ||
3799 | "#), | ||
3800 | @r###" | ||
3801 | [128; 132) 'self': Option<T> | ||
3802 | [134; 135) 'f': F | ||
3803 | [145; 147) '{}': () | ||
3804 | [161; 280) '{ ... 1); }': () | ||
3805 | [171; 172) 'x': Option<i32> | ||
3806 | [175; 187) 'Option::Some': Some<i32>(T) -> Option<T> | ||
3807 | [175; 193) 'Option...(1i32)': Option<i32> | ||
3808 | [188; 192) '1i32': i32 | ||
3809 | [199; 200) 'x': Option<i32> | ||
3810 | [199; 215) 'x.map(...v + 1)': {unknown} | ||
3811 | [205; 214) '|v| v + 1': {unknown} | ||
3812 | [206; 207) 'v': {unknown} | ||
3813 | [209; 210) 'v': {unknown} | ||
3814 | [209; 214) 'v + 1': i32 | ||
3815 | [213; 214) '1': i32 | ||
3816 | [221; 222) 'x': Option<i32> | ||
3817 | [221; 237) 'x.map(... 1u64)': {unknown} | ||
3818 | [227; 236) '|_v| 1u64': {unknown} | ||
3819 | [228; 230) '_v': {unknown} | ||
3820 | [232; 236) '1u64': u64 | ||
3821 | [247; 248) 'y': Option<i64> | ||
3822 | [264; 265) 'x': Option<i32> | ||
3823 | [264; 277) 'x.map(|_v| 1)': Option<i64> | ||
3824 | [270; 276) '|_v| 1': {unknown} | ||
3825 | [271; 273) '_v': {unknown} | ||
3826 | [275; 276) '1': i32 | ||
3827 | "### | ||
3828 | ); | ||
3829 | } | ||
3830 | |||
3831 | #[test] | ||
3832 | fn closure_2() { | ||
3833 | assert_snapshot!( | ||
3834 | infer(r#" | ||
3835 | trait FnOnce<Args> { | ||
3836 | type Output; | ||
3837 | } | ||
3838 | |||
3839 | fn test<F: FnOnce(u32) -> u64>(f: F) { | ||
3840 | f(1); | ||
3841 | let g = |v| v + 1; | ||
3842 | g(1u64); | ||
3843 | let h = |v| 1u128 + v; | ||
3844 | } | ||
3845 | "#), | ||
3846 | @r###" | ||
3847 | [73; 74) 'f': F | ||
3848 | [79; 155) '{ ...+ v; }': () | ||
3849 | [85; 86) 'f': F | ||
3850 | [85; 89) 'f(1)': {unknown} | ||
3851 | [87; 88) '1': i32 | ||
3852 | [99; 100) 'g': {unknown} | ||
3853 | [103; 112) '|v| v + 1': {unknown} | ||
3854 | [104; 105) 'v': {unknown} | ||
3855 | [107; 108) 'v': {unknown} | ||
3856 | [107; 112) 'v + 1': i32 | ||
3857 | [111; 112) '1': i32 | ||
3858 | [118; 119) 'g': {unknown} | ||
3859 | [118; 125) 'g(1u64)': {unknown} | ||
3860 | [120; 124) '1u64': u64 | ||
3861 | [135; 136) 'h': {unknown} | ||
3862 | [139; 152) '|v| 1u128 + v': {unknown} | ||
3863 | [140; 141) 'v': u128 | ||
3864 | [143; 148) '1u128': u128 | ||
3865 | [143; 152) '1u128 + v': u128 | ||
3866 | [151; 152) 'v': u128 | ||
3867 | "### | ||
3868 | ); | ||
3869 | } | ||
3870 | |||
3646 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 3871 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
3647 | let file = db.parse(pos.file_id).ok().unwrap(); | 3872 | let file = db.parse(pos.file_id).ok().unwrap(); |
3648 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 3873 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |