From 3a9aa80502e9be1bc9341393cb53804843f8e834 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Thu, 21 May 2020 18:26:50 +0300 Subject: editors/vscode: added patchelf after download --- editors/code/src/main.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index ac3bb365e..0a234cb84 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -1,7 +1,7 @@ import * as vscode from 'vscode'; import * as path from "path"; import * as os from "os"; -import { promises as fs } from "fs"; +import { promises as fs, PathLike } from "fs"; import * as commands from './commands'; import { activateInlayHints } from './inlay_hints'; @@ -12,6 +12,7 @@ import { log, assert, isValidExecutable } from './util'; import { PersistentState } from './persistent_state'; import { fetchRelease, download } from './net'; import { activateTaskProvider } from './tasks'; +import { exec } from 'child_process'; let ctx: Ctx | undefined; @@ -188,6 +189,46 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< return path; } +async function patchelf(dest: PathLike): Promise { + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: "Patching rust-analysis for NixOS" + }, + async (progress, _) => { + let patch_path = path.join(os.tmpdir(), "patch-ra.nix") + progress.report({message: "Writing nix file", increment: 5}) + await fs.writeFile(patch_path, ` + {src, pkgs ? import {}}: + pkgs.stdenv.mkDerivation { + name = "rust-analyzer"; + inherit src; + phases = [ "installPhase" "fixupPhase" ]; + installPhase = "cp $src $out"; + fixupPhase = '' + chmod 755 $out + patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out + ''; + } + `) + let orig_file = dest + "-orig" + await fs.rename(dest, orig_file) + progress.report({message: "Patching executable", increment: 20}) + await new Promise((resolve, reject) => { + exec(`nix-build ${patch_path} --arg src '${orig_file}' -o ${dest}`, + (err, stdout, stderr) => { + if (err != null) { + reject(Error(stderr)) + } else { + resolve(stdout) + } + }) + }) + // await fs.unlink(orig_file) + } + ) +} + async function getServer(config: Config, state: PersistentState): Promise { const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; if (explicitPath) { @@ -237,6 +278,12 @@ async function getServer(config: Config, state: PersistentState): Promise true).catch(_ => false)) { + await patchelf(dest) + } + await state.updateServerVersion(config.package.version); return dest; } -- cgit v1.2.3 From 125e4197d8af1eca498e0088aa37cf48e0b3827e Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Thu, 21 May 2020 18:45:37 +0300 Subject: editors/vscode: removing original file after patching --- editors/code/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 0a234cb84..0a2c30594 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -224,7 +224,7 @@ async function patchelf(dest: PathLike): Promise { } }) }) - // await fs.unlink(orig_file) + await fs.unlink(orig_file) } ) } -- cgit v1.2.3 From 8e0d776369f807c1d3f60abb899d2fe0d83570d4 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Thu, 21 May 2020 18:49:30 +0300 Subject: editor/vscode: lint --- editors/code/src/main.ts | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 0a2c30594..1c6e3093b 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -192,13 +192,13 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< async function patchelf(dest: PathLike): Promise { await vscode.window.withProgress( { - location: vscode.ProgressLocation.Notification, + location: vscode.ProgressLocation.Notification, title: "Patching rust-analysis for NixOS" - }, + }, async (progress, _) => { - let patch_path = path.join(os.tmpdir(), "patch-ra.nix") - progress.report({message: "Writing nix file", increment: 5}) - await fs.writeFile(patch_path, ` + const patchPath = path.join(os.tmpdir(), "patch-ra.nix"); + progress.report({ message: "Writing nix file", increment: 5 }); + await fs.writeFile(patchPath, ` {src, pkgs ? import {}}: pkgs.stdenv.mkDerivation { name = "rust-analyzer"; @@ -210,23 +210,23 @@ async function patchelf(dest: PathLike): Promise { patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out ''; } - `) - let orig_file = dest + "-orig" - await fs.rename(dest, orig_file) - progress.report({message: "Patching executable", increment: 20}) + `); + const origFile = dest + "-orig"; + await fs.rename(dest, origFile); + progress.report({ message: "Patching executable", increment: 20 }); await new Promise((resolve, reject) => { - exec(`nix-build ${patch_path} --arg src '${orig_file}' -o ${dest}`, - (err, stdout, stderr) => { - if (err != null) { - reject(Error(stderr)) - } else { - resolve(stdout) - } - }) - }) - await fs.unlink(orig_file) + exec(`nix-build ${patchPath} --arg src '${origFile}' -o ${dest}`, + (err, stdout, stderr) => { + if (err != null) { + reject(Error(stderr)); + } else { + resolve(stdout); + } + }); + }); + await fs.unlink(origFile); } - ) + ); } async function getServer(config: Config, state: PersistentState): Promise { @@ -281,7 +281,7 @@ async function getServer(config: Config, state: PersistentState): Promise true).catch(_ => false)) { - await patchelf(dest) + await patchelf(dest); } await state.updateServerVersion(config.package.version); -- cgit v1.2.3 From d7331b2d5dcdb2002a45ac4afe64b4d801658df5 Mon Sep 17 00:00:00 2001 From: Cabia Rangris Date: Thu, 21 May 2020 17:50:28 +0200 Subject: Update editors/code/src/main.ts Co-authored-by: Jeremy Kolb --- editors/code/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 1c6e3093b..bfa9980be 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -193,7 +193,7 @@ async function patchelf(dest: PathLike): Promise { await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, - title: "Patching rust-analysis for NixOS" + title: "Patching rust-analyzer for NixOS" }, async (progress, _) => { const patchPath = path.join(os.tmpdir(), "patch-ra.nix"); -- cgit v1.2.3 From 757292856b5d3653926e52dd4da473b062b9a832 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Thu, 21 May 2020 21:30:56 +0300 Subject: editors/vscode: patchelf-ing without intermediate files --- editors/code/src/main.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 1c6e3093b..dbb241192 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -196,9 +196,7 @@ async function patchelf(dest: PathLike): Promise { title: "Patching rust-analysis for NixOS" }, async (progress, _) => { - const patchPath = path.join(os.tmpdir(), "patch-ra.nix"); - progress.report({ message: "Writing nix file", increment: 5 }); - await fs.writeFile(patchPath, ` + const expression = ` {src, pkgs ? import {}}: pkgs.stdenv.mkDerivation { name = "rust-analyzer"; @@ -210,12 +208,12 @@ async function patchelf(dest: PathLike): Promise { patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out ''; } - `); + `; const origFile = dest + "-orig"; await fs.rename(dest, origFile); progress.report({ message: "Patching executable", increment: 20 }); await new Promise((resolve, reject) => { - exec(`nix-build ${patchPath} --arg src '${origFile}' -o ${dest}`, + const handle = exec(`nix-build -E - --arg src '${origFile}' -o ${dest}`, (err, stdout, stderr) => { if (err != null) { reject(Error(stderr)); @@ -223,6 +221,8 @@ async function patchelf(dest: PathLike): Promise { resolve(stdout); } }); + handle.stdin?.write(expression); + handle.stdin?.end(); }); await fs.unlink(origFile); } -- cgit v1.2.3 From ec5162fa7f2344ea86e11237383cb9d5ce5707aa Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Thu, 21 May 2020 21:32:27 +0300 Subject: editors/vscode: forgotten await in os check --- editors/code/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index dbb241192..42685e0c7 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -280,7 +280,7 @@ async function getServer(config: Config, state: PersistentState): Promise true).catch(_ => false)) { + if (await fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) { await patchelf(dest); } -- cgit v1.2.3 From bfbc210bc1216b79e355eb70449caf08dc67d5ad Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 22 May 2020 18:15:53 +0200 Subject: Use Chalk's built-in representation of function item types --- crates/ra_hir_ty/src/db.rs | 5 ++++ crates/ra_hir_ty/src/lib.rs | 6 ++++ crates/ra_hir_ty/src/tests/traits.rs | 42 +++++++++++++++++++++++++++ crates/ra_hir_ty/src/traits/chalk.rs | 39 ++++++++++++++++++++++--- crates/ra_hir_ty/src/traits/chalk/interner.rs | 2 ++ crates/ra_hir_ty/src/traits/chalk/mapping.rs | 26 ++++++++++++++--- crates/ra_hir_ty/src/traits/chalk/tls.rs | 18 ++++++++++-- 7 files changed, 128 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index dfc6c7dd6..0a8bb24ac 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs @@ -76,6 +76,8 @@ pub trait HirDatabase: DefDatabase + Upcast { #[salsa::interned] fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; #[salsa::interned] + fn intern_callable_def(&self, callable_def: CallableDef) -> crate::CallableDefId; + #[salsa::interned] fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; #[salsa::interned] fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; @@ -94,6 +96,9 @@ pub trait HirDatabase: DefDatabase + Upcast { #[salsa::invoke(crate::traits::chalk::impl_datum_query)] fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc; + #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] + fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc; + #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] fn associated_ty_value( &self, diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index e91c9be04..93cb45a64 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -159,6 +159,12 @@ pub enum TypeCtor { pub struct TypeCtorId(salsa::InternId); impl_intern_key!(TypeCtorId); +/// This exists just for Chalk, because Chalk just has a single `FnDefId` where +/// we have different IDs for struct and enum variant constructors. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct CallableDefId(salsa::InternId); +impl_intern_key!(CallableDefId); + impl TypeCtor { pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { match self { diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 6826610cb..17c646076 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -2643,6 +2643,48 @@ fn test() { ); } +#[test] +fn builtin_fn_def_copy() { + assert_snapshot!( + infer_with_mismatches(r#" +#[lang = "copy"] +trait Copy {} + +fn foo() {} +fn bar(T) -> T {} +struct Struct(usize); +enum Enum { Variant(usize) } + +trait Test { fn test(&self) -> bool; } +impl Test for T {} + +fn test() { + foo.test(); + bar.test(); + Struct.test(); + Enum::Variant.test(); +} +"#, true), + // wrong result, because the built-in Copy impl for fn defs doesn't exist in Chalk yet + @r###" + 42..44 '{}': () + 61..62 'T': {unknown} + 69..71 '{}': () + 69..71: expected T, got () + 146..150 'self': &Self + 202..282 '{ ...t(); }': () + 208..211 'foo': fn foo() + 208..218 'foo.test()': {unknown} + 224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown} + 224..234 'bar.test()': {unknown} + 240..246 'Struct': Struct(usize) -> Struct + 240..253 'Struct.test()': {unknown} + 259..272 'Enum::Variant': Variant(usize) -> Enum + 259..279 'Enum::...test()': {unknown} + "### + ); +} + #[test] fn builtin_sized() { assert_snapshot!( diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index e2f2a9ccb..5b0f12a3c 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -14,7 +14,7 @@ use ra_db::{salsa::InternKey, CrateId}; use super::{builtin, AssocTyValue, ChalkContext, Impl}; use crate::{ db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, - DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, + CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, }; use chalk_rust_ir::WellKnownTrait; use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; @@ -54,10 +54,9 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { fn fn_def_datum( &self, - _fn_def_id: chalk_ir::FnDefId, + fn_def_id: chalk_ir::FnDefId, ) -> Arc> { - // We don't yet provide any FnDefs to Chalk - unimplemented!() + self.db.fn_def_datum(self.krate, fn_def_id) } fn impls_for_trait( @@ -405,6 +404,26 @@ fn type_alias_associated_ty_value( Arc::new(value) } +pub(crate) fn fn_def_datum_query( + db: &dyn HirDatabase, + _krate: CrateId, + fn_def_id: FnDefId, +) -> Arc { + let callable_def: CallableDef = from_chalk(db, fn_def_id); + let generic_params = generics(db.upcast(), callable_def.into()); + let sig = db.callable_item_signature(callable_def); + let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); + let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); + let bound = chalk_rust_ir::FnDefDatumBound { + // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway + argument_types: sig.value.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(), + return_type: sig.value.ret().clone().to_chalk(db), + where_clauses, + }; + let datum = FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders) }; + Arc::new(datum) +} + impl From for crate::TypeCtorId { fn from(struct_id: AdtId) -> Self { struct_id.0 @@ -417,6 +436,18 @@ impl From for AdtId { } } +impl From for crate::CallableDefId { + fn from(fn_def_id: FnDefId) -> Self { + InternKey::from_intern_id(fn_def_id.0) + } +} + +impl From for FnDefId { + fn from(callable_def_id: crate::CallableDefId) -> Self { + chalk_ir::FnDefId(callable_def_id.as_intern_id()) + } +} + impl From for crate::traits::GlobalImplId { fn from(impl_id: ImplId) -> Self { InternKey::from_intern_id(impl_id.0) diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs index 060372819..2a27f8ed8 100644 --- a/crates/ra_hir_ty/src/traits/chalk/interner.rs +++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs @@ -20,6 +20,8 @@ pub type ImplId = chalk_ir::ImplId; pub type ImplDatum = chalk_rust_ir::ImplDatum; pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue; +pub type FnDefId = chalk_ir::FnDefId; +pub type FnDefDatum = chalk_rust_ir::FnDefDatum; impl chalk_ir::interner::Interner for Interner { type InternedType = Box>; // FIXME use Arc? diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index a83d82fd8..7841a0e21 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs @@ -15,8 +15,8 @@ use crate::{ db::HirDatabase, primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, - ApplicationTy, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, Substs, - TraitEnvironment, TraitRef, Ty, TypeCtor, + ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, + Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, }; use super::interner::*; @@ -217,11 +217,14 @@ impl ToChalk for TypeCtor { TypeCtor::Slice => TypeName::Slice, TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), TypeCtor::Str => TypeName::Str, + TypeCtor::FnDef(callable_def) => { + let id = callable_def.to_chalk(db); + TypeName::FnDef(id) + } TypeCtor::Int(Uncertain::Unknown) | TypeCtor::Float(Uncertain::Unknown) | TypeCtor::Adt(_) | TypeCtor::Array - | TypeCtor::FnDef(_) | TypeCtor::FnPtr { .. } | TypeCtor::Never | TypeCtor::Closure { .. } => { @@ -260,7 +263,10 @@ impl ToChalk for TypeCtor { TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)), TypeName::Str => TypeCtor::Str, - TypeName::FnDef(_) => unreachable!(), + TypeName::FnDef(fn_def_id) => { + let callable_def = from_chalk(db, fn_def_id); + TypeCtor::FnDef(callable_def) + } TypeName::Error => { // this should not be reached, since we don't represent TypeName::Error with TypeCtor @@ -347,6 +353,18 @@ impl ToChalk for Impl { } } +impl ToChalk for CallableDef { + type Chalk = FnDefId; + + fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { + db.intern_callable_def(self).into() + } + + fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { + db.lookup_intern_callable_def(fn_def_id.into()) + } +} + impl ToChalk for TypeAliasId { type Chalk = AssocTypeId; diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs index ebf402a07..d88828c7c 100644 --- a/crates/ra_hir_ty/src/traits/chalk/tls.rs +++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs @@ -247,10 +247,24 @@ impl DebugContext<'_> { pub fn debug_fn_def_id( &self, - _fn_def_id: chalk_ir::FnDefId, + fn_def_id: chalk_ir::FnDefId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { - write!(fmt, "fn") + let def: CallableDef = from_chalk(self.0, fn_def_id); + let name = match def { + CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), + CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), + CallableDef::EnumVariantId(e) => { + let enum_data = self.0.enum_data(e.parent); + enum_data.variants[e.local_id].name.clone() + } + }; + match def { + CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name), + CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { + write!(fmt, "{{ctor {}}}", name) + } + } } pub fn debug_const( -- cgit v1.2.3 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