Skip to content

Commit bfbc210

Browse files
committed
Use Chalk's built-in representation of function item types
1 parent d4daca9 commit bfbc210

File tree

7 files changed

+128
-10
lines changed

7 files changed

+128
-10
lines changed

crates/ra_hir_ty/src/db.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
7676
#[salsa::interned]
7777
fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
7878
#[salsa::interned]
79+
fn intern_callable_def(&self, callable_def: CallableDef) -> crate::CallableDefId;
80+
#[salsa::interned]
7981
fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
8082
#[salsa::interned]
8183
fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
@@ -94,6 +96,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
9496
#[salsa::invoke(crate::traits::chalk::impl_datum_query)]
9597
fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
9698

99+
#[salsa::invoke(crate::traits::chalk::fn_def_datum_query)]
100+
fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>;
101+
97102
#[salsa::invoke(crate::traits::chalk::associated_ty_value_query)]
98103
fn associated_ty_value(
99104
&self,

crates/ra_hir_ty/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ pub enum TypeCtor {
159159
pub struct TypeCtorId(salsa::InternId);
160160
impl_intern_key!(TypeCtorId);
161161

162+
/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
163+
/// we have different IDs for struct and enum variant constructors.
164+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
165+
pub struct CallableDefId(salsa::InternId);
166+
impl_intern_key!(CallableDefId);
167+
162168
impl TypeCtor {
163169
pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
164170
match self {

crates/ra_hir_ty/src/tests/traits.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,6 +2643,48 @@ fn test() {
26432643
);
26442644
}
26452645

2646+
#[test]
2647+
fn builtin_fn_def_copy() {
2648+
assert_snapshot!(
2649+
infer_with_mismatches(r#"
2650+
#[lang = "copy"]
2651+
trait Copy {}
2652+
2653+
fn foo() {}
2654+
fn bar<T: Copy>(T) -> T {}
2655+
struct Struct(usize);
2656+
enum Enum { Variant(usize) }
2657+
2658+
trait Test { fn test(&self) -> bool; }
2659+
impl<T: Copy> Test for T {}
2660+
2661+
fn test() {
2662+
foo.test();
2663+
bar.test();
2664+
Struct.test();
2665+
Enum::Variant.test();
2666+
}
2667+
"#, true),
2668+
// wrong result, because the built-in Copy impl for fn defs doesn't exist in Chalk yet
2669+
@r###"
2670+
42..44 '{}': ()
2671+
61..62 'T': {unknown}
2672+
69..71 '{}': ()
2673+
69..71: expected T, got ()
2674+
146..150 'self': &Self
2675+
202..282 '{ ...t(); }': ()
2676+
208..211 'foo': fn foo()
2677+
208..218 'foo.test()': {unknown}
2678+
224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2679+
224..234 'bar.test()': {unknown}
2680+
240..246 'Struct': Struct(usize) -> Struct
2681+
240..253 'Struct.test()': {unknown}
2682+
259..272 'Enum::Variant': Variant(usize) -> Enum
2683+
259..279 'Enum::...test()': {unknown}
2684+
"###
2685+
);
2686+
}
2687+
26462688
#[test]
26472689
fn builtin_sized() {
26482690
assert_snapshot!(

crates/ra_hir_ty/src/traits/chalk.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ra_db::{salsa::InternKey, CrateId};
1414
use super::{builtin, AssocTyValue, ChalkContext, Impl};
1515
use crate::{
1616
db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics,
17-
DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor,
17+
CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor,
1818
};
1919
use chalk_rust_ir::WellKnownTrait;
2020
use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
@@ -54,10 +54,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
5454

5555
fn fn_def_datum(
5656
&self,
57-
_fn_def_id: chalk_ir::FnDefId<Interner>,
57+
fn_def_id: chalk_ir::FnDefId<Interner>,
5858
) -> Arc<chalk_rust_ir::FnDefDatum<Interner>> {
59-
// We don't yet provide any FnDefs to Chalk
60-
unimplemented!()
59+
self.db.fn_def_datum(self.krate, fn_def_id)
6160
}
6261

6362
fn impls_for_trait(
@@ -405,6 +404,26 @@ fn type_alias_associated_ty_value(
405404
Arc::new(value)
406405
}
407406

407+
pub(crate) fn fn_def_datum_query(
408+
db: &dyn HirDatabase,
409+
_krate: CrateId,
410+
fn_def_id: FnDefId,
411+
) -> Arc<FnDefDatum> {
412+
let callable_def: CallableDef = from_chalk(db, fn_def_id);
413+
let generic_params = generics(db.upcast(), callable_def.into());
414+
let sig = db.callable_item_signature(callable_def);
415+
let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
416+
let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
417+
let bound = chalk_rust_ir::FnDefDatumBound {
418+
// Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
419+
argument_types: sig.value.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(),
420+
return_type: sig.value.ret().clone().to_chalk(db),
421+
where_clauses,
422+
};
423+
let datum = FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders) };
424+
Arc::new(datum)
425+
}
426+
408427
impl From<AdtId> for crate::TypeCtorId {
409428
fn from(struct_id: AdtId) -> Self {
410429
struct_id.0
@@ -417,6 +436,18 @@ impl From<crate::TypeCtorId> for AdtId {
417436
}
418437
}
419438

439+
impl From<FnDefId> for crate::CallableDefId {
440+
fn from(fn_def_id: FnDefId) -> Self {
441+
InternKey::from_intern_id(fn_def_id.0)
442+
}
443+
}
444+
445+
impl From<crate::CallableDefId> for FnDefId {
446+
fn from(callable_def_id: crate::CallableDefId) -> Self {
447+
chalk_ir::FnDefId(callable_def_id.as_intern_id())
448+
}
449+
}
450+
420451
impl From<ImplId> for crate::traits::GlobalImplId {
421452
fn from(impl_id: ImplId) -> Self {
422453
InternKey::from_intern_id(impl_id.0)

crates/ra_hir_ty/src/traits/chalk/interner.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub type ImplId = chalk_ir::ImplId<Interner>;
2020
pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>;
2121
pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>;
2222
pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>;
23+
pub type FnDefId = chalk_ir::FnDefId<Interner>;
24+
pub type FnDefDatum = chalk_rust_ir::FnDefDatum<Interner>;
2325

2426
impl chalk_ir::interner::Interner for Interner {
2527
type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?

crates/ra_hir_ty/src/traits/chalk/mapping.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::{
1515
db::HirDatabase,
1616
primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain},
1717
traits::{builtin, AssocTyValue, Canonical, Impl, Obligation},
18-
ApplicationTy, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, Substs,
19-
TraitEnvironment, TraitRef, Ty, TypeCtor,
18+
ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy,
19+
Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
2020
};
2121

2222
use super::interner::*;
@@ -217,11 +217,14 @@ impl ToChalk for TypeCtor {
217217
TypeCtor::Slice => TypeName::Slice,
218218
TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
219219
TypeCtor::Str => TypeName::Str,
220+
TypeCtor::FnDef(callable_def) => {
221+
let id = callable_def.to_chalk(db);
222+
TypeName::FnDef(id)
223+
}
220224
TypeCtor::Int(Uncertain::Unknown)
221225
| TypeCtor::Float(Uncertain::Unknown)
222226
| TypeCtor::Adt(_)
223227
| TypeCtor::Array
224-
| TypeCtor::FnDef(_)
225228
| TypeCtor::FnPtr { .. }
226229
| TypeCtor::Never
227230
| TypeCtor::Closure { .. } => {
@@ -260,7 +263,10 @@ impl ToChalk for TypeCtor {
260263
TypeName::Ref(mutability) => TypeCtor::Ref(from_chalk(db, mutability)),
261264
TypeName::Str => TypeCtor::Str,
262265

263-
TypeName::FnDef(_) => unreachable!(),
266+
TypeName::FnDef(fn_def_id) => {
267+
let callable_def = from_chalk(db, fn_def_id);
268+
TypeCtor::FnDef(callable_def)
269+
}
264270

265271
TypeName::Error => {
266272
// this should not be reached, since we don't represent TypeName::Error with TypeCtor
@@ -347,6 +353,18 @@ impl ToChalk for Impl {
347353
}
348354
}
349355

356+
impl ToChalk for CallableDef {
357+
type Chalk = FnDefId;
358+
359+
fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
360+
db.intern_callable_def(self).into()
361+
}
362+
363+
fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef {
364+
db.lookup_intern_callable_def(fn_def_id.into())
365+
}
366+
}
367+
350368
impl ToChalk for TypeAliasId {
351369
type Chalk = AssocTypeId;
352370

crates/ra_hir_ty/src/traits/chalk/tls.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,24 @@ impl DebugContext<'_> {
247247

248248
pub fn debug_fn_def_id(
249249
&self,
250-
_fn_def_id: chalk_ir::FnDefId<Interner>,
250+
fn_def_id: chalk_ir::FnDefId<Interner>,
251251
fmt: &mut fmt::Formatter<'_>,
252252
) -> Result<(), fmt::Error> {
253-
write!(fmt, "fn")
253+
let def: CallableDef = from_chalk(self.0, fn_def_id);
254+
let name = match def {
255+
CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(),
256+
CallableDef::StructId(s) => self.0.struct_data(s).name.clone(),
257+
CallableDef::EnumVariantId(e) => {
258+
let enum_data = self.0.enum_data(e.parent);
259+
enum_data.variants[e.local_id].name.clone()
260+
}
261+
};
262+
match def {
263+
CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name),
264+
CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
265+
write!(fmt, "{{ctor {}}}", name)
266+
}
267+
}
254268
}
255269

256270
pub fn debug_const(

0 commit comments

Comments
 (0)