From 194dd9eb0d44284f7e952a1e84296fcda4d90f5e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 22 May 2020 19:13:17 +0200 Subject: Use Chalk's Ty::Function for function pointer types Function pointers can be 'higher-ranked' over lifetimes, which is why they're not an application type in Chalk, but since we don't model lifetimes it doesn't matter for us yet. --- crates/ra_hir_ty/src/tests/traits.rs | 32 ++++++++++++++++++++++++++++ crates/ra_hir_ty/src/traits/chalk/mapping.rs | 27 ++++++++++++++++------- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 17c646076..0419bc751 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -2685,6 +2685,38 @@ fn test() { ); } +#[test] +fn builtin_fn_ptr_copy() { + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "copy"] +trait Copy {} + +trait Test { fn test(&self) -> bool; } +impl Test for T {} + +fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { + f1.test(); + f2.test(); + f3.test(); +} +"#, true), + @r###" + 55..59 'self': &Self + 109..111 'f1': fn() + 119..121 'f2': fn(usize) -> u8 + 140..142 'f3': fn(u8, u8) -> &u8 + 163..211 '{ ...t(); }': () + 169..171 'f1': fn() + 169..178 'f1.test()': bool + 184..186 'f2': fn(usize) -> u8 + 184..193 'f2.test()': bool + 199..201 'f3': fn(u8, u8) -> &u8 + 199..208 'f3.test()': bool + "### + ); +} + #[test] fn builtin_sized() { assert_snapshot!( diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 7841a0e21..7082cb095 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -26,14 +26,19 @@ impl ToChalk for Ty { type Chalk = chalk_ir::Ty; fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { match self { - Ty::Apply(apply_ty) => { - if let TypeCtor::Ref(m) = apply_ty.ctor { - return ref_to_chalk(db, m, apply_ty.parameters); + Ty::Apply(apply_ty) => match apply_ty.ctor { + TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), + TypeCtor::FnPtr { num_args: _ } => { + let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); + chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) + .intern(&Interner) } - let name = apply_ty.ctor.to_chalk(db); - let substitution = apply_ty.parameters.to_chalk(db); - chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) - } + _ => { + let name = apply_ty.ctor.to_chalk(db); + let substitution = apply_ty.parameters.to_chalk(db); + chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) + } + }, Ty::Projection(proj_ty) => { let associated_ty_id = proj_ty.associated_ty.to_chalk(db); let substitution = proj_ty.parameters.to_chalk(db); @@ -93,7 +98,13 @@ impl ToChalk for Ty { Ty::Projection(ProjectionTy { associated_ty, parameters }) } chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), - chalk_ir::TyData::Function(_) => unimplemented!(), + chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { + let parameters: Substs = from_chalk(db, substitution); + Ty::Apply(ApplicationTy { + ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, + parameters, + }) + } chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, chalk_ir::TyData::Dyn(where_clauses) => { -- cgit v1.2.3