aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/tests.rs205
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]
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 // FIXME should be u32
3664 assert_eq!(t, "{unknown}");
3665}
3666
3667#[test]
3668fn super_trait_method_resolution() {
3669 assert_snapshot!(
3670 infer(r#"
3671mod foo {
3672 trait SuperTrait {
3673 fn foo(&self) -> u32 {}
3674 }
3675}
3676trait Trait1: SuperTrait {}
3677trait Trait2 where Self: SuperTrait {}
3678
3679fn 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]
3699fn super_trait_assoc_type_bounds() {
3700 assert_snapshot!(
3701 infer(r#"
3702trait SuperTrait { type Type; }
3703trait Trait where Self: SuperTrait {}
3704
3705fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
3706fn set<T: Trait<Type = u64>>(t: T) -> T {t}
3707
3708struct S<T>;
3709impl<T> SuperTrait for S<T> { type Type = T; }
3710impl<T> Trait for S<T> {}
3711
3712fn 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]
3733fn fn_trait() {
3734 assert_snapshot!(
3735 infer(r#"
3736trait FnOnce<Args> {
3737 type Output;
3738
3739 fn call_once(self, args: Args) -> Self::Output;
3740}
3741
3742fn 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]
3761fn closure_1() {
3762 assert_snapshot!(
3763 infer(r#"
3764trait FnOnce<Args> {
3765 type Output;
3766}
3767
3768enum Option<T> { Some(T), None }
3769impl<T> Option<T> {
3770 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> U {}
3771}
3772
3773fn 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]
3812fn closure_2() {
3813 assert_snapshot!(
3814 infer(r#"
3815trait FnOnce<Args> {
3816 type Output;
3817}
3818
3819fn 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
3646fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 3851fn 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();