diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-06 17:28:42 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-06 17:28:42 +0100 |
commit | 9dc9a7a3e2fa858125f9b3c6170c0b259da06fb6 (patch) | |
tree | cce758eabcbcfbb1bc1673601477a9c86580cb2b /crates/ra_hir/src | |
parent | 219e0e8c8d6672feaab2f19b7c3280d5967360e4 (diff) | |
parent | f854a29c9adcfeaa7164928ff91daab9ca9a063c (diff) |
Merge #1496
1496: Add trait obligations for where clauses when calling functions/methods r=matklad a=flodiebold
E.g. if we call `foo<T: Into<u32>>(x)`, that adds an obligation that `x: Into<u32>`, etc., which sometimes allows type inference to make further progress.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/generics.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 134 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 6 |
9 files changed, 171 insertions, 42 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9c6c52d9..0e6e3fdb7 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -163,10 +163,10 @@ pub trait HirDatabase: DefDatabase + AstDatabase { | |||
163 | #[salsa::invoke(crate::ty::callable_item_sig)] | 163 | #[salsa::invoke(crate::ty::callable_item_sig)] |
164 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | 164 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; |
165 | 165 | ||
166 | #[salsa::invoke(crate::ty::generic_predicates)] | 166 | #[salsa::invoke(crate::ty::generic_predicates_query)] |
167 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; | 167 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; |
168 | 168 | ||
169 | #[salsa::invoke(crate::ty::generic_defaults)] | 169 | #[salsa::invoke(crate::ty::generic_defaults_query)] |
170 | fn generic_defaults(&self, def: GenericDef) -> Substs; | 170 | fn generic_defaults(&self, def: GenericDef) -> Substs; |
171 | 171 | ||
172 | #[salsa::invoke(crate::expr::body_with_source_map_query)] | 172 | #[salsa::invoke(crate::expr::body_with_source_map_query)] |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 9929331d3..521e47090 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -11,8 +11,8 @@ use crate::{ | |||
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | path::Path, | 12 | path::Path, |
13 | type_ref::TypeRef, | 13 | type_ref::TypeRef, |
14 | AdtDef, AsName, Container, Enum, Function, HasSource, ImplBlock, Name, Struct, Trait, | 14 | AdtDef, AsName, Container, Enum, EnumVariant, Function, HasSource, ImplBlock, Name, Struct, |
15 | TypeAlias, Union, | 15 | Trait, TypeAlias, Union, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// Data about a generic parameter (to a function, struct, impl, ...). | 18 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -50,8 +50,11 @@ pub enum GenericDef { | |||
50 | Trait(Trait), | 50 | Trait(Trait), |
51 | TypeAlias(TypeAlias), | 51 | TypeAlias(TypeAlias), |
52 | ImplBlock(ImplBlock), | 52 | ImplBlock(ImplBlock), |
53 | // enum variants cannot have generics themselves, but their parent enums | ||
54 | // can, and this makes some code easier to write | ||
55 | EnumVariant(EnumVariant), | ||
53 | } | 56 | } |
54 | impl_froms!(GenericDef: Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock); | 57 | impl_froms!(GenericDef: Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock, EnumVariant); |
55 | 58 | ||
56 | impl GenericParams { | 59 | impl GenericParams { |
57 | pub(crate) fn generic_params_query( | 60 | pub(crate) fn generic_params_query( |
@@ -62,6 +65,7 @@ impl GenericParams { | |||
62 | let parent = match def { | 65 | let parent = match def { |
63 | GenericDef::Function(it) => it.container(db).map(GenericDef::from), | 66 | GenericDef::Function(it) => it.container(db).map(GenericDef::from), |
64 | GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), | 67 | GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), |
68 | GenericDef::EnumVariant(it) => Some(it.parent_enum(db).into()), | ||
65 | GenericDef::Struct(_) | 69 | GenericDef::Struct(_) |
66 | | GenericDef::Union(_) | 70 | | GenericDef::Union(_) |
67 | | GenericDef::Enum(_) | 71 | | GenericDef::Enum(_) |
@@ -86,6 +90,7 @@ impl GenericParams { | |||
86 | } | 90 | } |
87 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).ast, start), | 91 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).ast, start), |
88 | GenericDef::ImplBlock(it) => generics.fill(&*it.source(db).ast, start), | 92 | GenericDef::ImplBlock(it) => generics.fill(&*it.source(db).ast, start), |
93 | GenericDef::EnumVariant(_) => {} | ||
89 | } | 94 | } |
90 | 95 | ||
91 | Arc::new(generics) | 96 | Arc::new(generics) |
@@ -184,6 +189,7 @@ impl GenericDef { | |||
184 | GenericDef::Trait(inner) => inner.resolver(db), | 189 | GenericDef::Trait(inner) => inner.resolver(db), |
185 | GenericDef::TypeAlias(inner) => inner.resolver(db), | 190 | GenericDef::TypeAlias(inner) => inner.resolver(db), |
186 | GenericDef::ImplBlock(inner) => inner.resolver(db), | 191 | GenericDef::ImplBlock(inner) => inner.resolver(db), |
192 | GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), | ||
187 | } | 193 | } |
188 | } | 194 | } |
189 | } | 195 | } |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index c8be27e54..e2a7639b0 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -221,6 +221,18 @@ impl Resolver { | |||
221 | pub(crate) fn krate(&self) -> Option<Crate> { | 221 | pub(crate) fn krate(&self) -> Option<Crate> { |
222 | self.module().map(|t| t.0.krate()) | 222 | self.module().map(|t| t.0.krate()) |
223 | } | 223 | } |
224 | |||
225 | pub(crate) fn where_predicates_in_scope<'a>( | ||
226 | &'a self, | ||
227 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { | ||
228 | self.scopes | ||
229 | .iter() | ||
230 | .filter_map(|scope| match scope { | ||
231 | Scope::GenericParams(params) => Some(params), | ||
232 | _ => None, | ||
233 | }) | ||
234 | .flat_map(|params| params.where_predicates.iter()) | ||
235 | } | ||
224 | } | 236 | } |
225 | 237 | ||
226 | impl Resolver { | 238 | impl Resolver { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 11afdc0f3..d8c7945e1 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -23,8 +23,8 @@ pub(crate) use autoderef::autoderef; | |||
23 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; | 23 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; |
24 | pub use lower::CallableDef; | 24 | pub use lower::CallableDef; |
25 | pub(crate) use lower::{ | 25 | pub(crate) use lower::{ |
26 | callable_item_sig, generic_defaults, generic_predicates, type_for_def, type_for_field, | 26 | callable_item_sig, generic_defaults_query, generic_predicates_query, type_for_def, |
27 | TypableDef, | 27 | type_for_field, TypableDef, |
28 | }; | 28 | }; |
29 | pub(crate) use traits::ProjectionPredicate; | 29 | pub(crate) use traits::ProjectionPredicate; |
30 | 30 | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index a23daabc2..e79e5e223 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -849,8 +849,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
849 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 849 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
850 | if let Ty::Apply(a_ty) = callable_ty { | 850 | if let Ty::Apply(a_ty) = callable_ty { |
851 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 851 | if let TypeCtor::FnDef(def) = a_ty.ctor { |
852 | let generic_predicates = self.db.generic_predicates(def.into()); | ||
853 | for predicate in generic_predicates.iter() { | ||
854 | let predicate = predicate.clone().subst(&a_ty.parameters); | ||
855 | if let Some(obligation) = Obligation::from_predicate(predicate) { | ||
856 | self.obligations.push(obligation); | ||
857 | } | ||
858 | } | ||
852 | // add obligation for trait implementation, if this is a trait method | 859 | // add obligation for trait implementation, if this is a trait method |
853 | // FIXME also register obligations from where clauses from the trait or impl and method | ||
854 | match def { | 860 | match def { |
855 | CallableDef::Function(f) => { | 861 | CallableDef::Function(f) => { |
856 | if let Some(trait_) = f.parent_trait(self.db) { | 862 | if let Some(trait_) = f.parent_trait(self.db) { |
@@ -992,7 +998,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
992 | (Vec::new(), Ty::Unknown) | 998 | (Vec::new(), Ty::Unknown) |
993 | } | 999 | } |
994 | }; | 1000 | }; |
995 | // FIXME register obligations from where clauses from the function | 1001 | self.register_obligations_for_call(&callee_ty); |
996 | let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); | 1002 | let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); |
997 | for (arg, param) in args.iter().zip(param_iter) { | 1003 | for (arg, param) in args.iter().zip(param_iter) { |
998 | self.infer_expr(*arg, &Expectation::has_type(param)); | 1004 | self.infer_expr(*arg, &Expectation::has_type(param)); |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 8b1b2a7f9..b48ada760 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -318,15 +318,13 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | |||
318 | } | 318 | } |
319 | 319 | ||
320 | /// Resolve the where clause(s) of an item with generics. | 320 | /// Resolve the where clause(s) of an item with generics. |
321 | pub(crate) fn generic_predicates( | 321 | pub(crate) fn generic_predicates_query( |
322 | db: &impl HirDatabase, | 322 | db: &impl HirDatabase, |
323 | def: GenericDef, | 323 | def: GenericDef, |
324 | ) -> Arc<[GenericPredicate]> { | 324 | ) -> Arc<[GenericPredicate]> { |
325 | let resolver = def.resolver(db); | 325 | let resolver = def.resolver(db); |
326 | let generic_params = def.generic_params(db); | 326 | let predicates = resolver |
327 | let predicates = generic_params | 327 | .where_predicates_in_scope() |
328 | .where_predicates | ||
329 | .iter() | ||
330 | .map(|pred| { | 328 | .map(|pred| { |
331 | TraitRef::for_where_predicate(db, &resolver, pred) | 329 | TraitRef::for_where_predicate(db, &resolver, pred) |
332 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) | 330 | .map_or(GenericPredicate::Error, GenericPredicate::Implemented) |
@@ -336,7 +334,7 @@ pub(crate) fn generic_predicates( | |||
336 | } | 334 | } |
337 | 335 | ||
338 | /// Resolve the default type params from generics | 336 | /// Resolve the default type params from generics |
339 | pub(crate) fn generic_defaults(db: &impl HirDatabase, def: GenericDef) -> Substs { | 337 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { |
340 | let resolver = def.resolver(db); | 338 | let resolver = def.resolver(db); |
341 | let generic_params = def.generic_params(db); | 339 | let generic_params = def.generic_params(db); |
342 | 340 | ||
@@ -511,3 +509,13 @@ pub enum CallableDef { | |||
511 | EnumVariant(EnumVariant), | 509 | EnumVariant(EnumVariant), |
512 | } | 510 | } |
513 | impl_froms!(CallableDef: Function, Struct, EnumVariant); | 511 | impl_froms!(CallableDef: Function, Struct, EnumVariant); |
512 | |||
513 | impl From<CallableDef> for GenericDef { | ||
514 | fn from(def: CallableDef) -> GenericDef { | ||
515 | match def { | ||
516 | CallableDef::Function(f) => f.into(), | ||
517 | CallableDef::Struct(s) => s.into(), | ||
518 | CallableDef::EnumVariant(e) => e.into(), | ||
519 | } | ||
520 | } | ||
521 | } | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 20fa74fb4..aacd94a26 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2232,16 +2232,18 @@ fn test() { | |||
2232 | } | 2232 | } |
2233 | "#), | 2233 | "#), |
2234 | @r###" | 2234 | @r###" |
2235 | [86; 87) 't': T | 2235 | ⋮ |
2236 | [92; 94) '{}': () | 2236 | ⋮[86; 87) 't': T |
2237 | [105; 144) '{ ...(s); }': () | 2237 | ⋮[92; 94) '{}': () |
2238 | [115; 116) 's': S<{unknown}> | 2238 | ⋮[105; 144) '{ ...(s); }': () |
2239 | [119; 120) 'S': S<{unknown}>(T) -> S<T> | 2239 | ⋮[115; 116) 's': S<u32> |
2240 | [119; 129) 'S(unknown)': S<{unknown}> | 2240 | ⋮[119; 120) 'S': S<u32>(T) -> S<T> |
2241 | [121; 128) 'unknown': {unknown} | 2241 | ⋮[119; 129) 'S(unknown)': S<u32> |
2242 | [135; 138) 'foo': fn foo<S<{unknown}>>(T) -> () | 2242 | ⋮[121; 128) 'unknown': u32 |
2243 | [135; 141) 'foo(s)': () | 2243 | ⋮[135; 138) 'foo': fn foo<S<u32>>(T) -> () |
2244 | [139; 140) 's': S<{unknown}>"### | 2244 | ⋮[135; 141) 'foo(s)': () |
2245 | ⋮[139; 140) 's': S<u32> | ||
2246 | "### | ||
2245 | ); | 2247 | ); |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2259,17 +2261,19 @@ fn test() { | |||
2259 | } | 2261 | } |
2260 | "#), | 2262 | "#), |
2261 | @r###" | 2263 | @r###" |
2262 | [87; 88) 't': T | 2264 | ⋮ |
2263 | [98; 100) '{}': () | 2265 | ⋮[87; 88) 't': T |
2264 | [111; 163) '{ ...(s); }': () | 2266 | ⋮[98; 100) '{}': () |
2265 | [121; 122) 's': S<{unknown}> | 2267 | ⋮[111; 163) '{ ...(s); }': () |
2266 | [125; 126) 'S': S<{unknown}>(T) -> S<T> | 2268 | ⋮[121; 122) 's': S<u32> |
2267 | [125; 135) 'S(unknown)': S<{unknown}> | 2269 | ⋮[125; 126) 'S': S<u32>(T) -> S<T> |
2268 | [127; 134) 'unknown': {unknown} | 2270 | ⋮[125; 135) 'S(unknown)': S<u32> |
2269 | [145; 146) 'x': u32 | 2271 | ⋮[127; 134) 'unknown': u32 |
2270 | [154; 157) 'foo': fn foo<u32, S<{unknown}>>(T) -> U | 2272 | ⋮[145; 146) 'x': u32 |
2271 | [154; 160) 'foo(s)': u32 | 2273 | ⋮[154; 157) 'foo': fn foo<u32, S<u32>>(T) -> U |
2272 | [158; 159) 's': S<{unknown}>"### | 2274 | ⋮[154; 160) 'foo(s)': u32 |
2275 | ⋮[158; 159) 's': S<u32> | ||
2276 | "### | ||
2273 | ); | 2277 | ); |
2274 | } | 2278 | } |
2275 | 2279 | ||
@@ -2822,6 +2826,94 @@ fn test(s: S) { | |||
2822 | assert_eq!(t, "{unknown}"); | 2826 | assert_eq!(t, "{unknown}"); |
2823 | } | 2827 | } |
2824 | 2828 | ||
2829 | #[test] | ||
2830 | fn obligation_from_function_clause() { | ||
2831 | let t = type_at( | ||
2832 | r#" | ||
2833 | //- /main.rs | ||
2834 | struct S; | ||
2835 | |||
2836 | trait Trait<T> {} | ||
2837 | impl Trait<u32> for S {} | ||
2838 | |||
2839 | fn foo<T: Trait<U>, U>(t: T) -> U {} | ||
2840 | |||
2841 | fn test(s: S) { | ||
2842 | foo(s)<|>; | ||
2843 | } | ||
2844 | "#, | ||
2845 | ); | ||
2846 | assert_eq!(t, "u32"); | ||
2847 | } | ||
2848 | |||
2849 | #[test] | ||
2850 | fn obligation_from_method_clause() { | ||
2851 | let t = type_at( | ||
2852 | r#" | ||
2853 | //- /main.rs | ||
2854 | struct S; | ||
2855 | |||
2856 | trait Trait<T> {} | ||
2857 | impl Trait<isize> for S {} | ||
2858 | |||
2859 | struct O; | ||
2860 | impl O { | ||
2861 | fn foo<T: Trait<U>, U>(&self, t: T) -> U {} | ||
2862 | } | ||
2863 | |||
2864 | fn test() { | ||
2865 | O.foo(S)<|>; | ||
2866 | } | ||
2867 | "#, | ||
2868 | ); | ||
2869 | assert_eq!(t, "isize"); | ||
2870 | } | ||
2871 | |||
2872 | #[test] | ||
2873 | fn obligation_from_self_method_clause() { | ||
2874 | let t = type_at( | ||
2875 | r#" | ||
2876 | //- /main.rs | ||
2877 | struct S; | ||
2878 | |||
2879 | trait Trait<T> {} | ||
2880 | impl Trait<i64> for S {} | ||
2881 | |||
2882 | impl S { | ||
2883 | fn foo<U>(&self) -> U where Self: Trait<U> {} | ||
2884 | } | ||
2885 | |||
2886 | fn test() { | ||
2887 | S.foo()<|>; | ||
2888 | } | ||
2889 | "#, | ||
2890 | ); | ||
2891 | assert_eq!(t, "i64"); | ||
2892 | } | ||
2893 | |||
2894 | #[test] | ||
2895 | fn obligation_from_impl_clause() { | ||
2896 | let t = type_at( | ||
2897 | r#" | ||
2898 | //- /main.rs | ||
2899 | struct S; | ||
2900 | |||
2901 | trait Trait<T> {} | ||
2902 | impl Trait<&str> for S {} | ||
2903 | |||
2904 | struct O<T>; | ||
2905 | impl<U, T: Trait<U>> O<T> { | ||
2906 | fn foo(&self) -> U {} | ||
2907 | } | ||
2908 | |||
2909 | fn test(o: O<S>) { | ||
2910 | o.foo()<|>; | ||
2911 | } | ||
2912 | "#, | ||
2913 | ); | ||
2914 | assert_eq!(t, "&str"); | ||
2915 | } | ||
2916 | |||
2825 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2917 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
2826 | let file = db.parse(pos.file_id).ok().unwrap(); | 2918 | let file = db.parse(pos.file_id).ok().unwrap(); |
2827 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 2919 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index cff4de316..23a26a971 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -7,7 +7,7 @@ use parking_lot::Mutex; | |||
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
9 | 9 | ||
10 | use super::{Canonical, ProjectionTy, TraitRef, Ty}; | 10 | use super::{Canonical, GenericPredicate, ProjectionTy, TraitRef, Ty}; |
11 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; | 11 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; |
12 | 12 | ||
13 | use self::chalk::{from_chalk, ToChalk}; | 13 | use self::chalk::{from_chalk, ToChalk}; |
@@ -78,6 +78,15 @@ pub enum Obligation { | |||
78 | // Projection(ProjectionPredicate), | 78 | // Projection(ProjectionPredicate), |
79 | } | 79 | } |
80 | 80 | ||
81 | impl Obligation { | ||
82 | pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> { | ||
83 | match predicate { | ||
84 | GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)), | ||
85 | GenericPredicate::Error => None, | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
81 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 90 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
82 | pub struct ProjectionPredicate { | 91 | pub struct ProjectionPredicate { |
83 | pub projection_ty: ProjectionTy, | 92 | pub projection_ty: ProjectionTy, |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 2a0537bc3..4c3744b44 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -428,11 +428,7 @@ pub(crate) fn struct_datum_query( | |||
428 | CallableDef::Struct(s) => s.module(db).krate(db), | 428 | CallableDef::Struct(s) => s.module(db).krate(db), |
429 | CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db), | 429 | CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db), |
430 | } != Some(krate); | 430 | } != Some(krate); |
431 | let generic_def: GenericDef = match callable { | 431 | let generic_def: GenericDef = callable.into(); |
432 | CallableDef::Function(f) => f.into(), | ||
433 | CallableDef::Struct(s) => s.into(), | ||
434 | CallableDef::EnumVariant(v) => v.parent_enum(db).into(), | ||
435 | }; | ||
436 | let generic_params = generic_def.generic_params(db); | 432 | let generic_params = generic_def.generic_params(db); |
437 | let bound_vars = Substs::bound_vars(&generic_params); | 433 | let bound_vars = Substs::bound_vars(&generic_params); |
438 | let where_clauses = convert_where_clauses(db, generic_def, &bound_vars); | 434 | let where_clauses = convert_where_clauses(db, generic_def, &bound_vars); |