aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/tests.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r--crates/ra_hir/src/ty/tests.rs225
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]
3648fn where_clause_trait_in_scope_for_method_resolution() {
3649 let t = type_at(
3650 r#"
3651//- /main.rs
3652mod foo {
3653 trait Trait {
3654 fn foo(&self) -> u32 {}
3655 }
3656}
3657
3658fn test<T: foo::Trait>(x: T) {
3659 x.foo()<|>;
3660}
3661"#,
3662 );
3663 assert_eq!(t, "u32");
3664}
3665
3666#[test]
3667fn super_trait_method_resolution() {
3668 assert_snapshot!(
3669 infer(r#"
3670mod foo {
3671 trait SuperTrait {
3672 fn foo(&self) -> u32 {}
3673 }
3674}
3675trait Trait1: foo::SuperTrait {}
3676trait Trait2 where Self: foo::SuperTrait {}
3677
3678fn 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]
3698fn super_trait_cycle() {
3699 // This just needs to not crash
3700 assert_snapshot!(
3701 infer(r#"
3702trait A: B {}
3703trait B: A {}
3704
3705fn 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]
3719fn super_trait_assoc_type_bounds() {
3720 assert_snapshot!(
3721 infer(r#"
3722trait SuperTrait { type Type; }
3723trait Trait where Self: SuperTrait {}
3724
3725fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
3726fn set<T: Trait<Type = u64>>(t: T) -> T {t}
3727
3728struct S<T>;
3729impl<T> SuperTrait for S<T> { type Type = T; }
3730impl<T> Trait for S<T> {}
3731
3732fn 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]
3753fn fn_trait() {
3754 assert_snapshot!(
3755 infer(r#"
3756trait FnOnce<Args> {
3757 type Output;
3758
3759 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
3760}
3761
3762fn 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]
3781fn closure_1() {
3782 assert_snapshot!(
3783 infer(r#"
3784trait FnOnce<Args> {
3785 type Output;
3786}
3787
3788enum Option<T> { Some(T), None }
3789impl<T> Option<T> {
3790 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> U {}
3791}
3792
3793fn 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]
3832fn closure_2() {
3833 assert_snapshot!(
3834 infer(r#"
3835trait FnOnce<Args> {
3836 type Output;
3837}
3838
3839fn 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
3646fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 3871fn 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();