diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 27 |
3 files changed, 39 insertions, 2 deletions
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs index 5b6400042..2d831f0d8 100644 --- a/crates/ra_hir/src/marks.rs +++ b/crates/ra_hir/src/marks.rs | |||
@@ -9,4 +9,5 @@ test_utils::marks!( | |||
9 | glob_across_crates | 9 | glob_across_crates |
10 | std_prelude | 10 | std_prelude |
11 | match_ergonomics_ref | 11 | match_ergonomics_ref |
12 | trait_resolution_on_fn_type | ||
12 | ); | 13 | ); |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 3c55a093f..f0793bfb4 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2568,6 +2568,19 @@ fn test() { S2.into()<|>; } | |||
2568 | assert_eq!(t, "S1"); | 2568 | assert_eq!(t, "S1"); |
2569 | } | 2569 | } |
2570 | 2570 | ||
2571 | #[test] | ||
2572 | fn method_resolution_encountering_fn_type() { | ||
2573 | covers!(trait_resolution_on_fn_type); | ||
2574 | type_at( | ||
2575 | r#" | ||
2576 | //- /main.rs | ||
2577 | fn foo() {} | ||
2578 | trait FnOnce { fn call(self); } | ||
2579 | fn test() { foo.call()<|>; } | ||
2580 | "#, | ||
2581 | ); | ||
2582 | } | ||
2583 | |||
2571 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2584 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
2572 | let file = db.parse(pos.file_id); | 2585 | let file = db.parse(pos.file_id); |
2573 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 2586 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 787970186..7bb6a4f4a 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -6,12 +6,13 @@ use log::debug; | |||
6 | use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; | 6 | use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; |
7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; | 7 | use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; |
8 | 8 | ||
9 | use test_utils::tested_by; | ||
9 | use ra_db::salsa::{InternId, InternKey}; | 10 | use ra_db::salsa::{InternId, InternKey}; |
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
12 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, |
13 | db::HirDatabase, | 14 | db::HirDatabase, |
14 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, ty::CallableDef, |
15 | }; | 16 | }; |
16 | use super::ChalkContext; | 17 | use super::ChalkContext; |
17 | 18 | ||
@@ -261,7 +262,29 @@ where | |||
261 | } | 262 | } |
262 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), | 263 | TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), |
263 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), | 264 | TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), |
264 | TypeCtor::FnDef(_) => unimplemented!(), | 265 | TypeCtor::FnDef(callable) => { |
266 | tested_by!(trait_resolution_on_fn_type); | ||
267 | let krate = match callable { | ||
268 | CallableDef::Function(f) => f.module(self.db).krate(self.db), | ||
269 | CallableDef::Struct(s) => s.module(self.db).krate(self.db), | ||
270 | CallableDef::EnumVariant(v) => { | ||
271 | v.parent_enum(self.db).module(self.db).krate(self.db) | ||
272 | } | ||
273 | }; | ||
274 | let generic_def: GenericDef = match callable { | ||
275 | CallableDef::Function(f) => f.into(), | ||
276 | CallableDef::Struct(s) => s.into(), | ||
277 | CallableDef::EnumVariant(v) => v.parent_enum(self.db).into(), | ||
278 | }; | ||
279 | let generic_params = generic_def.generic_params(self.db); | ||
280 | let bound_vars = Substs::bound_vars(&generic_params); | ||
281 | let where_clauses = convert_where_clauses(self.db, generic_def, &bound_vars); | ||
282 | ( | ||
283 | generic_params.count_params_including_parent(), | ||
284 | where_clauses, | ||
285 | krate != Some(self.krate), | ||
286 | ) | ||
287 | } | ||
265 | TypeCtor::Adt(adt) => { | 288 | TypeCtor::Adt(adt) => { |
266 | let generic_params = adt.generic_params(self.db); | 289 | let generic_params = adt.generic_params(self.db); |
267 | let bound_vars = Substs::bound_vars(&generic_params); | 290 | let bound_vars = Substs::bound_vars(&generic_params); |