aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/marks.rs1
-rw-r--r--crates/ra_hir/src/ty/tests.rs13
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs27
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]
2572fn method_resolution_encountering_fn_type() {
2573 covers!(trait_resolution_on_fn_type);
2574 type_at(
2575 r#"
2576//- /main.rs
2577fn foo() {}
2578trait FnOnce { fn call(self); }
2579fn test() { foo.call()<|>; }
2580"#,
2581 );
2582}
2583
2571fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 2584fn 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;
6use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; 6use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName};
7use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; 7use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum};
8 8
9use test_utils::tested_by;
9use ra_db::salsa::{InternId, InternKey}; 10use ra_db::salsa::{InternId, InternKey};
10 11
11use crate::{ 12use 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};
16use super::ChalkContext; 17use 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);