Skip to content

Commit c0daf93

Browse files
authored
Merge pull request #449 from nathanwhit/typename-fndef
Add `FnDef` to `TypeName`
2 parents 03c7f3d + 4b23e07 commit c0daf93

File tree

18 files changed

+523
-62
lines changed

18 files changed

+523
-62
lines changed

chalk-integration/src/db.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use chalk_ir::AssocTypeId;
1010
use chalk_ir::Canonical;
1111
use chalk_ir::ConstrainedSubst;
1212
use chalk_ir::Environment;
13+
use chalk_ir::FnDefId;
1314
use chalk_ir::GenericArg;
1415
use chalk_ir::Goal;
1516
use chalk_ir::ImplId;
@@ -22,6 +23,7 @@ use chalk_rust_ir::AdtDatum;
2223
use chalk_rust_ir::AssociatedTyDatum;
2324
use chalk_rust_ir::AssociatedTyValue;
2425
use chalk_rust_ir::AssociatedTyValueId;
26+
use chalk_rust_ir::FnDefDatum;
2527
use chalk_rust_ir::ImplDatum;
2628
use chalk_rust_ir::OpaqueTyDatum;
2729
use chalk_rust_ir::TraitDatum;
@@ -114,6 +116,10 @@ impl RustIrDatabase<ChalkIr> for ChalkDatabase {
114116
self.program_ir().unwrap().adt_datum(id)
115117
}
116118

119+
fn fn_def_datum(&self, id: FnDefId<ChalkIr>) -> Arc<FnDefDatum<ChalkIr>> {
120+
self.program_ir().unwrap().fn_def_datum(id)
121+
}
122+
117123
fn impls_for_trait(
118124
&self,
119125
trait_id: TraitId<ChalkIr>,

chalk-integration/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub use interner::{Identifier, RawId};
2222
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2323
pub enum TypeSort {
2424
Struct,
25+
FnDef,
2526
Trait,
2627
Opaque,
2728
}

chalk-integration/src/lowering.rs

Lines changed: 131 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::interner::ChalkIr;
22
use chalk_ir::cast::{Cast, Caster};
33
use chalk_ir::interner::HasInterner;
44
use chalk_ir::{
5-
self, AdtId, AssocTypeId, BoundVar, ClausePriority, DebruijnIndex, ImplId, OpaqueTyId,
5+
self, AdtId, AssocTypeId, BoundVar, ClausePriority, DebruijnIndex, FnDefId, ImplId, OpaqueTyId,
66
QuantifiedWhereClauses, Substitution, ToGenericArg, TraitId,
77
};
88
use chalk_parse::ast::*;
@@ -19,9 +19,11 @@ use crate::program::Program as LoweredProgram;
1919
use crate::{Identifier as Ident, RawId, TypeKind, TypeSort};
2020

2121
type AdtIds = BTreeMap<Ident, chalk_ir::AdtId<ChalkIr>>;
22+
type FnDefIds = BTreeMap<Ident, chalk_ir::FnDefId<ChalkIr>>;
2223
type TraitIds = BTreeMap<Ident, chalk_ir::TraitId<ChalkIr>>;
2324
type OpaqueTyIds = BTreeMap<Ident, chalk_ir::OpaqueTyId<ChalkIr>>;
2425
type AdtKinds = BTreeMap<chalk_ir::AdtId<ChalkIr>, TypeKind>;
26+
type FnDefKinds = BTreeMap<chalk_ir::FnDefId<ChalkIr>, TypeKind>;
2527
type TraitKinds = BTreeMap<chalk_ir::TraitId<ChalkIr>, TypeKind>;
2628
type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId<ChalkIr>, Ident), AssociatedTyLookup>;
2729
type AssociatedTyValueIds =
@@ -36,6 +38,8 @@ pub type LowerResult<T> = Result<T, RustIrError>;
3638
struct Env<'k> {
3739
adt_ids: &'k AdtIds,
3840
adt_kinds: &'k AdtKinds,
41+
fn_def_ids: &'k FnDefIds,
42+
fn_def_kinds: &'k FnDefKinds,
3943
trait_ids: &'k TraitIds,
4044
trait_kinds: &'k TraitKinds,
4145
opaque_ty_ids: &'k OpaqueTyIds,
@@ -73,6 +77,7 @@ struct AssociatedTyLookup {
7377
enum TypeLookup {
7478
Adt(chalk_ir::AdtId<ChalkIr>),
7579
GenericArg(BoundVar),
80+
FnDef(chalk_ir::FnDefId<ChalkIr>),
7681
Opaque(chalk_ir::OpaqueTyId<ChalkIr>),
7782
}
7883

@@ -96,6 +101,10 @@ impl<'k> Env<'k> {
96101
return Ok(TypeLookup::Adt(*id));
97102
}
98103

104+
if let Some(id) = self.fn_def_ids.get(&name.str) {
105+
return Ok(TypeLookup::FnDef(*id));
106+
}
107+
99108
if let Some(id) = self.opaque_ty_ids.get(&name.str) {
100109
return Ok(TypeLookup::Opaque(*id));
101110
}
@@ -140,6 +149,10 @@ impl<'k> Env<'k> {
140149
&self.adt_kinds[&id]
141150
}
142151

152+
fn fn_def_kind(&self, id: chalk_ir::FnDefId<ChalkIr>) -> &TypeKind {
153+
&self.fn_def_kinds[&id]
154+
}
155+
143156
fn trait_kind(&self, id: chalk_ir::TraitId<ChalkIr>) -> &TypeKind {
144157
&self.trait_kinds[&id]
145158
}
@@ -240,9 +253,11 @@ impl LowerProgram for Program {
240253
}
241254

242255
let mut adt_ids = BTreeMap::new();
256+
let mut fn_def_ids = BTreeMap::new();
243257
let mut trait_ids = BTreeMap::new();
244258
let mut opaque_ty_ids = BTreeMap::new();
245259
let mut adt_kinds = BTreeMap::new();
260+
let mut fn_def_kinds = BTreeMap::new();
246261
let mut trait_kinds = BTreeMap::new();
247262
let mut opaque_ty_kinds = BTreeMap::new();
248263
let mut object_safe_traits = HashSet::new();
@@ -254,6 +269,12 @@ impl LowerProgram for Program {
254269
adt_ids.insert(type_kind.name.clone(), id);
255270
adt_kinds.insert(id, type_kind);
256271
}
272+
Item::FnDefn(defn) => {
273+
let type_kind = defn.lower_type_kind()?;
274+
let id = FnDefId(raw_id);
275+
fn_def_ids.insert(type_kind.name.clone(), id);
276+
fn_def_kinds.insert(id, type_kind);
277+
}
257278
Item::TraitDefn(defn) => {
258279
let type_kind = defn.lower_type_kind()?;
259280
let id = TraitId(raw_id);
@@ -276,6 +297,7 @@ impl LowerProgram for Program {
276297
}
277298

278299
let mut adt_data = BTreeMap::new();
300+
let mut fn_def_data = BTreeMap::new();
279301
let mut trait_data = BTreeMap::new();
280302
let mut well_known_traits = BTreeMap::new();
281303
let mut impl_data = BTreeMap::new();
@@ -287,6 +309,8 @@ impl LowerProgram for Program {
287309
let empty_env = Env {
288310
adt_ids: &adt_ids,
289311
adt_kinds: &adt_kinds,
312+
fn_def_ids: &fn_def_ids,
313+
fn_def_kinds: &fn_def_kinds,
290314
trait_ids: &trait_ids,
291315
trait_kinds: &trait_kinds,
292316
opaque_ty_ids: &opaque_ty_ids,
@@ -299,6 +323,13 @@ impl LowerProgram for Program {
299323
let adt_id = AdtId(raw_id);
300324
adt_data.insert(adt_id, Arc::new(d.lower_adt(adt_id, &empty_env)?));
301325
}
326+
Item::FnDefn(ref defn) => {
327+
let fn_def_id = FnDefId(raw_id);
328+
fn_def_data.insert(
329+
fn_def_id,
330+
Arc::new(defn.lower_fn_def(fn_def_id, &empty_env)?),
331+
);
332+
}
302333
Item::TraitDefn(ref trait_defn) => {
303334
let trait_id = TraitId(raw_id);
304335
let trait_datum = trait_defn.lower_trait(trait_id, &empty_env)?;
@@ -454,10 +485,13 @@ impl LowerProgram for Program {
454485

455486
let program = LoweredProgram {
456487
adt_ids,
488+
fn_def_ids,
457489
trait_ids,
458490
adt_kinds,
491+
fn_def_kinds,
459492
trait_kinds,
460493
adt_data,
494+
fn_def_data,
461495
trait_data,
462496
well_known_traits,
463497
impl_data,
@@ -538,6 +572,16 @@ impl LowerParameterMap for StructDefn {
538572
}
539573
}
540574

575+
impl LowerParameterMap for FnDefn {
576+
fn synthetic_parameters(&self) -> Option<NamedGenericArg> {
577+
None
578+
}
579+
580+
fn declared_parameters(&self) -> &[VariableKind] {
581+
&self.variable_kinds
582+
}
583+
}
584+
541585
impl LowerParameterMap for Impl {
542586
fn synthetic_parameters(&self) -> Option<NamedGenericArg> {
543587
None
@@ -631,6 +675,26 @@ impl LowerTypeKind for StructDefn {
631675
}
632676
}
633677

678+
impl LowerTypeKind for FnDefn {
679+
fn lower_type_kind(&self) -> LowerResult<TypeKind> {
680+
let interner = &ChalkIr;
681+
Ok(TypeKind {
682+
sort: TypeSort::FnDef,
683+
name: self.name.str.clone(),
684+
binders: chalk_ir::Binders::new(
685+
chalk_ir::VariableKinds::from(interner, self.all_parameters().anonymize()),
686+
crate::Unit,
687+
),
688+
})
689+
}
690+
}
691+
692+
impl LowerWhereClauses for FnDefn {
693+
fn where_clauses(&self) -> &[QuantifiedWhereClause] {
694+
&self.where_clauses
695+
}
696+
}
697+
634698
impl LowerWhereClauses for StructDefn {
635699
fn where_clauses(&self) -> &[QuantifiedWhereClause] {
636700
&self.where_clauses
@@ -850,6 +914,39 @@ impl LowerAdtDefn for StructDefn {
850914
}
851915
}
852916

917+
trait LowerFnDefn {
918+
fn lower_fn_def(
919+
&self,
920+
fn_def_id: chalk_ir::FnDefId<ChalkIr>,
921+
env: &Env,
922+
) -> LowerResult<rust_ir::FnDefDatum<ChalkIr>>;
923+
}
924+
925+
impl LowerFnDefn for FnDefn {
926+
fn lower_fn_def(
927+
&self,
928+
fn_def_id: chalk_ir::FnDefId<ChalkIr>,
929+
env: &Env,
930+
) -> LowerResult<rust_ir::FnDefDatum<ChalkIr>> {
931+
let binders = env.in_binders(self.all_parameters(), |env| {
932+
let args: LowerResult<_> = self.argument_types.iter().map(|t| t.lower(env)).collect();
933+
let where_clauses = self.lower_where_clauses(env)?;
934+
let return_type = self.return_type.lower(env)?;
935+
936+
Ok(rust_ir::FnDefDatumBound {
937+
argument_types: args?,
938+
where_clauses,
939+
return_type,
940+
})
941+
})?;
942+
943+
Ok(rust_ir::FnDefDatum {
944+
id: fn_def_id,
945+
binders,
946+
})
947+
}
948+
}
949+
853950
trait LowerTraitRef {
854951
fn lower(&self, env: &Env) -> LowerResult<chalk_ir::TraitRef<ChalkIr>>;
855952
}
@@ -1121,6 +1218,22 @@ impl LowerTy for Ty {
11211218
}
11221219
}
11231220
TypeLookup::GenericArg(d) => Ok(chalk_ir::TyData::BoundVar(d).intern(interner)),
1221+
TypeLookup::FnDef(id) => {
1222+
let k = env.fn_def_kind(id);
1223+
if k.binders.len(interner) > 0 {
1224+
Err(RustIrError::IncorrectNumberOfTypeParameters {
1225+
identifier: name.clone(),
1226+
expected: k.binders.len(interner),
1227+
actual: 0,
1228+
})
1229+
} else {
1230+
Ok(chalk_ir::TyData::Function(chalk_ir::Fn {
1231+
num_binders: k.binders.len(interner),
1232+
substitution: chalk_ir::Substitution::empty(interner),
1233+
})
1234+
.intern(interner))
1235+
}
1236+
}
11241237
TypeLookup::Opaque(id) => Ok(chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(
11251238
chalk_ir::OpaqueTy {
11261239
opaque_ty_id: id,
@@ -1157,14 +1270,14 @@ impl LowerTy for Ty {
11571270
.intern(interner)),
11581271

11591272
Ty::Apply { name, ref args } => {
1160-
let id = match env.lookup_type(name)? {
1161-
TypeLookup::Adt(id) => id,
1273+
let (id, k) = match env.lookup_type(name)? {
1274+
TypeLookup::Adt(id) => (id.0, env.adt_kind(id)),
11621275
TypeLookup::GenericArg(_) | TypeLookup::Opaque(_) => {
11631276
Err(RustIrError::CannotApplyTypeParameter(name.clone()))?
11641277
}
1278+
TypeLookup::FnDef(id) => (id.0, env.fn_def_kind(id)),
11651279
};
11661280

1167-
let k = env.adt_kind(id);
11681281
if k.binders.len(interner) != args.len() {
11691282
Err(RustIrError::IncorrectNumberOfTypeParameters {
11701283
identifier: name.clone(),
@@ -1188,11 +1301,18 @@ impl LowerTy for Ty {
11881301
}
11891302
}
11901303

1191-
Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1192-
name: chalk_ir::TypeName::Adt(id),
1193-
substitution,
1194-
})
1195-
.intern(interner))
1304+
match k.sort {
1305+
TypeSort::FnDef => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1306+
name: chalk_ir::TypeName::FnDef(FnDefId(id)),
1307+
substitution,
1308+
})
1309+
.intern(interner)),
1310+
_ => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1311+
name: chalk_ir::TypeName::Adt(AdtId(id)),
1312+
substitution,
1313+
})
1314+
.intern(interner)),
1315+
}
11961316
}
11971317

11981318
Ty::Projection { ref proj } => Ok(chalk_ir::TyData::Alias(
@@ -1485,9 +1605,11 @@ impl LowerGoal<LoweredProgram> for Goal {
14851605

14861606
let env = Env {
14871607
adt_ids: &program.adt_ids,
1608+
fn_def_ids: &program.fn_def_ids,
14881609
trait_ids: &program.trait_ids,
14891610
opaque_ty_ids: &program.opaque_ty_ids,
14901611
adt_kinds: &program.adt_kinds,
1612+
fn_def_kinds: &program.fn_def_kinds,
14911613
trait_kinds: &program.trait_kinds,
14921614
associated_ty_lookups: &associated_ty_lookups,
14931615
parameter_map: BTreeMap::new(),

chalk-integration/src/program.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use crate::{tls, Identifier, TypeKind};
33
use chalk_ir::could_match::CouldMatch;
44
use chalk_ir::debug::Angle;
55
use chalk_ir::{
6-
debug::SeparatorTraitRef, AdtId, AliasTy, ApplicationTy, AssocTypeId, GenericArg, Goal, Goals,
7-
ImplId, Lifetime, OpaqueTy, OpaqueTyId, ProgramClause, ProgramClauseImplication,
6+
debug::SeparatorTraitRef, AdtId, AliasTy, ApplicationTy, AssocTypeId, FnDefId, GenericArg,
7+
Goal, Goals, ImplId, Lifetime, OpaqueTy, OpaqueTyId, ProgramClause, ProgramClauseImplication,
88
ProgramClauses, ProjectionTy, Substitution, TraitId, Ty,
99
};
1010
use chalk_rust_ir::{
11-
AdtDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ImplDatum, ImplType,
12-
OpaqueTyDatum, TraitDatum, WellKnownTrait,
11+
AdtDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, FnDefDatum, ImplDatum,
12+
ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait,
1313
};
1414
use chalk_solve::split::Split;
1515
use chalk_solve::RustIrDatabase;
@@ -25,6 +25,10 @@ pub struct Program {
2525
/// For each ADT:
2626
pub adt_kinds: BTreeMap<AdtId<ChalkIr>, TypeKind>,
2727

28+
pub fn_def_ids: BTreeMap<Identifier, FnDefId<ChalkIr>>,
29+
30+
pub fn_def_kinds: BTreeMap<FnDefId<ChalkIr>, TypeKind>,
31+
2832
/// From trait name to item-id. Used during lowering only.
2933
pub trait_ids: BTreeMap<Identifier, TraitId<ChalkIr>>,
3034

@@ -34,6 +38,8 @@ pub struct Program {
3438
/// For each ADT:
3539
pub adt_data: BTreeMap<AdtId<ChalkIr>, Arc<AdtDatum<ChalkIr>>>,
3640

41+
pub fn_def_data: BTreeMap<FnDefId<ChalkIr>, Arc<FnDefDatum<ChalkIr>>>,
42+
3743
/// For each impl:
3844
pub impl_data: BTreeMap<ImplId<ChalkIr>, Arc<ImplDatum<ChalkIr>>>,
3945

@@ -334,6 +340,10 @@ impl RustIrDatabase<ChalkIr> for Program {
334340
self.adt_data[&id].clone()
335341
}
336342

343+
fn fn_def_datum(&self, id: FnDefId<ChalkIr>) -> Arc<FnDefDatum<ChalkIr>> {
344+
self.fn_def_data[&id].clone()
345+
}
346+
337347
fn impls_for_trait(
338348
&self,
339349
trait_id: TraitId<ChalkIr>,

chalk-ir/src/cast.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,15 @@ where
303303
}
304304
}
305305

306+
impl<I> CastTo<TypeName<I>> for FnDefId<I>
307+
where
308+
I: Interner,
309+
{
310+
fn cast_to(self, _interner: &I) -> TypeName<I> {
311+
TypeName::FnDef(self)
312+
}
313+
}
314+
306315
impl<T> CastTo<T> for &T
307316
where
308317
T: Clone + HasInterner,

0 commit comments

Comments
 (0)