From d8cd0e36f5288dd4c14fb5a07b73533d88f29788 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 5 May 2019 15:01:07 +0200 Subject: Handle Chalk conversion for FnDef --- crates/ra_hir/src/marks.rs | 1 + crates/ra_hir/src/ty/tests.rs | 13 +++++++++++++ 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!( glob_across_crates std_prelude match_ergonomics_ref + trait_resolution_on_fn_type ); 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()<|>; } assert_eq!(t, "S1"); } +#[test] +fn method_resolution_encountering_fn_type() { + covers!(trait_resolution_on_fn_type); + type_at( + r#" +//- /main.rs +fn foo() {} +trait FnOnce { fn call(self); } +fn test() { foo.call()<|>; } +"#, + ); +} + fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { let file = db.parse(pos.file_id); let expr = algo::find_node_at_offset::(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; use chalk_ir::{TypeId, ImplId, TypeKindId, ProjectionTy, Parameter, Identifier, cast::Cast, PlaceholderIndex, UniverseIndex, TypeName}; use chalk_rust_ir::{AssociatedTyDatum, TraitDatum, StructDatum, ImplDatum}; +use test_utils::tested_by; use ra_db::salsa::{InternId, InternKey}; use crate::{ Trait, HasGenericParams, ImplBlock, db::HirDatabase, - ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, + ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, ty::CallableDef, }; use super::ChalkContext; @@ -261,7 +262,29 @@ where } TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true), TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true), - TypeCtor::FnDef(_) => unimplemented!(), + TypeCtor::FnDef(callable) => { + tested_by!(trait_resolution_on_fn_type); + let krate = match callable { + CallableDef::Function(f) => f.module(self.db).krate(self.db), + CallableDef::Struct(s) => s.module(self.db).krate(self.db), + CallableDef::EnumVariant(v) => { + v.parent_enum(self.db).module(self.db).krate(self.db) + } + }; + let generic_def: GenericDef = match callable { + CallableDef::Function(f) => f.into(), + CallableDef::Struct(s) => s.into(), + CallableDef::EnumVariant(v) => v.parent_enum(self.db).into(), + }; + let generic_params = generic_def.generic_params(self.db); + let bound_vars = Substs::bound_vars(&generic_params); + let where_clauses = convert_where_clauses(self.db, generic_def, &bound_vars); + ( + generic_params.count_params_including_parent(), + where_clauses, + krate != Some(self.krate), + ) + } TypeCtor::Adt(adt) => { let generic_params = adt.generic_params(self.db); let bound_vars = Substs::bound_vars(&generic_params); -- cgit v1.2.3