aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs155
-rw-r--r--crates/ra_ide/src/hover.rs104
2 files changed, 155 insertions, 104 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index e81193a3c..8efe05877 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -2888,3 +2888,158 @@ impl<A: Step> iter::Iterator for ops::Range<A> {
2888 ); 2888 );
2889 assert_eq!(t, "i32"); 2889 assert_eq!(t, "i32");
2890} 2890}
2891
2892#[test]
2893fn infer_closure_arg() {
2894 assert_snapshot!(
2895 infer(
2896 r#"
2897 //- /lib.rs
2898
2899 enum Option<T> {
2900 None,
2901 Some(T)
2902 }
2903
2904 fn foo() {
2905 let s = Option::None;
2906 let f = |x: Option<i32>| {};
2907 (&f)(s)
2908 }
2909 "#
2910 ),
2911 @r###"
2912 137..259 '{ ... }': ()
2913 159..160 's': Option<i32>
2914 163..175 'Option::None': Option<i32>
2915 197..198 'f': |Option<i32>| -> ()
2916 201..220 '|x: Op...2>| {}': |Option<i32>| -> ()
2917 202..203 'x': Option<i32>
2918 218..220 '{}': ()
2919 238..245 '(&f)(s)': ()
2920 239..241 '&f': &|Option<i32>| -> ()
2921 240..241 'f': |Option<i32>| -> ()
2922 243..244 's': Option<i32>
2923 "###
2924 );
2925}
2926
2927#[test]
2928fn infer_fn_trait_arg() {
2929 assert_snapshot!(
2930 infer(
2931 r#"
2932 //- /lib.rs deps:std
2933
2934 #[lang = "fn_once"]
2935 pub trait FnOnce<Args> {
2936 type Output;
2937
2938 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output;
2939 }
2940
2941 #[lang = "fn"]
2942 pub trait Fn<Args>:FnOnce<Args> {
2943 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
2944 }
2945
2946 enum Option<T> {
2947 None,
2948 Some(T)
2949 }
2950
2951 fn foo<F, T>(f: F) -> T
2952 where
2953 F: Fn(Option<i32>) -> T,
2954 {
2955 let s = None;
2956 f(s)
2957 }
2958 "#
2959 ),
2960 @r###"
2961 183..187 'self': &Self
2962 189..193 'args': Args
2963 350..354 'self': &Self
2964 356..360 'args': Args
2965 515..516 'f': F
2966 597..663 '{ ... }': T
2967 619..620 's': Option<i32>
2968 623..627 'None': Option<i32>
2969 645..646 'f': F
2970 645..649 'f(s)': T
2971 647..648 's': Option<i32>
2972 "###
2973 );
2974}
2975
2976#[test]
2977fn infer_box_fn_arg() {
2978 assert_snapshot!(
2979 infer(
2980 r#"
2981 //- /lib.rs deps:std
2982
2983 #[lang = "fn_once"]
2984 pub trait FnOnce<Args> {
2985 type Output;
2986
2987 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
2988 }
2989
2990 #[lang = "deref"]
2991 pub trait Deref {
2992 type Target: ?Sized;
2993
2994 fn deref(&self) -> &Self::Target;
2995 }
2996
2997 #[lang = "owned_box"]
2998 pub struct Box<T: ?Sized> {
2999 inner: *mut T,
3000 }
3001
3002 impl<T: ?Sized> Deref for Box<T> {
3003 type Target = T;
3004
3005 fn deref(&self) -> &T {
3006 &self.inner
3007 }
3008 }
3009
3010 enum Option<T> {
3011 None,
3012 Some(T)
3013 }
3014
3015 fn foo() {
3016 let s = Option::None;
3017 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3018 f(&s)
3019 }
3020 "#
3021 ),
3022 @r###"
3023 182..186 'self': Self
3024 188..192 'args': Args
3025 356..360 'self': &Self
3026 622..626 'self': &Box<T>
3027 634..685 '{ ... }': &T
3028 656..667 '&self.inner': &*mut T
3029 657..661 'self': &Box<T>
3030 657..667 'self.inner': *mut T
3031 812..957 '{ ... }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, ({unknown},)>
3032 834..835 's': Option<i32>
3033 838..850 'Option::None': Option<i32>
3034 872..873 'f': Box<dyn FnOnce<(&Option<i32>,)>>
3035 907..920 'box (|ps| {})': Box<|{unknown}| -> ()>
3036 912..919 '|ps| {}': |{unknown}| -> ()
3037 913..915 'ps': {unknown}
3038 917..919 '{}': ()
3039 938..939 'f': Box<dyn FnOnce<(&Option<i32>,)>>
3040 938..943 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, ({unknown},)>
3041 940..942 '&s': &Option<i32>
3042 941..942 's': Option<i32>
3043 "###
3044 );
3045}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index a03024d09..d870e4cbc 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -2410,108 +2410,4 @@ fn func(foo: i32) { if true { <|>foo; }; }
2410 ] 2410 ]
2411 "###); 2411 "###);
2412 } 2412 }
2413
2414 #[test]
2415 fn infer_closure_arg() {
2416 check_hover_result(
2417 r#"
2418 //- /lib.rs
2419
2420 enum Option<T> {
2421 None,
2422 Some(T)
2423 }
2424
2425 fn foo() {
2426 let s<|> = Option::None;
2427 let f = |x: Option<i32>| {};
2428 (&f)(s)
2429 }
2430 "#,
2431 &["Option<i32>"],
2432 );
2433 }
2434
2435 #[test]
2436 fn infer_fn_trait_arg() {
2437 check_hover_result(
2438 r#"
2439 //- /lib.rs deps:std
2440
2441 #[lang = "fn_once"]
2442 pub trait FnOnce<Args> {
2443 type Output;
2444
2445 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output;
2446 }
2447
2448 #[lang = "fn"]
2449 pub trait Fn<Args>:FnOnce<Args> {
2450 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
2451 }
2452
2453 enum Option<T> {
2454 None,
2455 Some(T)
2456 }
2457
2458 fn foo<F, T>(f: F) -> T
2459 where
2460 F: Fn(Option<i32>) -> T,
2461 {
2462 let s<|> = None;
2463 f(s)
2464 }
2465 "#,
2466 &["Option<i32>"],
2467 );
2468 }
2469
2470 #[test]
2471 fn infer_box_fn_arg() {
2472 check_hover_result(
2473 r#"
2474 //- /lib.rs deps:std
2475
2476 #[lang = "fn_once"]
2477 pub trait FnOnce<Args> {
2478 type Output;
2479
2480 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
2481 }
2482
2483 #[lang = "deref"]
2484 pub trait Deref {
2485 type Target: ?Sized;
2486
2487 fn deref(&self) -> &Self::Target;
2488 }
2489
2490 #[lang = "owned_box"]
2491 pub struct Box<T: ?Sized> {
2492 inner: *mut T,
2493 }
2494
2495 impl<T: ?Sized> Deref for Box<T> {
2496 type Target = T;
2497
2498 fn deref(&self) -> &T {
2499 &self.inner
2500 }
2501 }
2502
2503 enum Option<T> {
2504 None,
2505 Some(T)
2506 }
2507
2508 fn foo() {
2509 let s<|> = Option::None;
2510 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
2511 f(&s)
2512 }
2513 "#,
2514 &["Option<i32>"],
2515 );
2516 }
2517} 2413}