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