diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-09 08:50:18 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-09 08:50:18 +0100 |
commit | f59cd1a4a0d6c369025a7014e838d25f91d478e4 (patch) | |
tree | 2c4b9dc868a87507ed63e9dc46530cc60f38ae64 /crates/ra_hir/src/ty/tests.rs | |
parent | 35f28c538a9b9f461bb4db1a78d02e9f02a3d296 (diff) | |
parent | 9afbf2dff43dee3227358f10162d4c77d192ce7a (diff) |
Merge #1515
1515: Trait environment r=matklad a=flodiebold
This adds the environment, i.e. the set of `where` clauses in scope, when solving trait goals. That means that e.g. in
```rust
fn foo<T: SomeTrait>(t: T) {}
```
, we are able to complete methods of `SomeTrait` on the `t`. This affects the trait APIs quite a bit (since every method that needs to be able to solve for some trait needs to get this environment somehow), so I thought I'd do it rather sooner than later ;)
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/tests.rs')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 6aea1fb4a..2410602a6 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3003,6 +3003,85 @@ fn test(o: O<S>) { | |||
3003 | assert_eq!(t, "&str"); | 3003 | assert_eq!(t, "&str"); |
3004 | } | 3004 | } |
3005 | 3005 | ||
3006 | #[test] | ||
3007 | fn generic_param_env_1() { | ||
3008 | let t = type_at( | ||
3009 | r#" | ||
3010 | //- /main.rs | ||
3011 | trait Clone {} | ||
3012 | trait Trait { fn foo(self) -> u128; } | ||
3013 | struct S; | ||
3014 | impl Clone for S {} | ||
3015 | impl<T> Trait for T where T: Clone {} | ||
3016 | fn test<T: Clone>(t: T) { t.foo()<|>; } | ||
3017 | "#, | ||
3018 | ); | ||
3019 | assert_eq!(t, "u128"); | ||
3020 | } | ||
3021 | |||
3022 | #[test] | ||
3023 | fn generic_param_env_1_not_met() { | ||
3024 | let t = type_at( | ||
3025 | r#" | ||
3026 | //- /main.rs | ||
3027 | trait Clone {} | ||
3028 | trait Trait { fn foo(self) -> u128; } | ||
3029 | struct S; | ||
3030 | impl Clone for S {} | ||
3031 | impl<T> Trait for T where T: Clone {} | ||
3032 | fn test<T>(t: T) { t.foo()<|>; } | ||
3033 | "#, | ||
3034 | ); | ||
3035 | assert_eq!(t, "{unknown}"); | ||
3036 | } | ||
3037 | |||
3038 | #[test] | ||
3039 | fn generic_param_env_2() { | ||
3040 | let t = type_at( | ||
3041 | r#" | ||
3042 | //- /main.rs | ||
3043 | trait Trait { fn foo(self) -> u128; } | ||
3044 | struct S; | ||
3045 | impl Trait for S {} | ||
3046 | fn test<T: Trait>(t: T) { t.foo()<|>; } | ||
3047 | "#, | ||
3048 | ); | ||
3049 | assert_eq!(t, "u128"); | ||
3050 | } | ||
3051 | |||
3052 | #[test] | ||
3053 | fn generic_param_env_2_not_met() { | ||
3054 | let t = type_at( | ||
3055 | r#" | ||
3056 | //- /main.rs | ||
3057 | trait Trait { fn foo(self) -> u128; } | ||
3058 | struct S; | ||
3059 | impl Trait for S {} | ||
3060 | fn test<T>(t: T) { t.foo()<|>; } | ||
3061 | "#, | ||
3062 | ); | ||
3063 | assert_eq!(t, "{unknown}"); | ||
3064 | } | ||
3065 | |||
3066 | #[test] | ||
3067 | fn generic_param_env_deref() { | ||
3068 | let t = type_at( | ||
3069 | r#" | ||
3070 | //- /main.rs | ||
3071 | #[lang = "deref"] | ||
3072 | trait Deref { | ||
3073 | type Target; | ||
3074 | } | ||
3075 | trait Trait {} | ||
3076 | impl<T> Deref for T where T: Trait { | ||
3077 | type Target = i128; | ||
3078 | } | ||
3079 | fn test<T: Trait>(t: T) { (*t)<|>; } | ||
3080 | "#, | ||
3081 | ); | ||
3082 | assert_eq!(t, "i128"); | ||
3083 | } | ||
3084 | |||
3006 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 3085 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
3007 | let file = db.parse(pos.file_id).ok().unwrap(); | 3086 | let file = db.parse(pos.file_id).ok().unwrap(); |
3008 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 3087 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |