Skip to content

Commit

Permalink
Merge pull request #449 from nathanwhit/typename-fndef
Browse files Browse the repository at this point in the history
Add `FnDef` to `TypeName`
  • Loading branch information
nikomatsakis authored May 18, 2020
2 parents 03c7f3d + 4b23e07 commit c0daf93
Show file tree
Hide file tree
Showing 18 changed files with 523 additions and 62 deletions.
6 changes: 6 additions & 0 deletions chalk-integration/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use chalk_ir::AssocTypeId;
use chalk_ir::Canonical;
use chalk_ir::ConstrainedSubst;
use chalk_ir::Environment;
use chalk_ir::FnDefId;
use chalk_ir::GenericArg;
use chalk_ir::Goal;
use chalk_ir::ImplId;
Expand All @@ -22,6 +23,7 @@ use chalk_rust_ir::AdtDatum;
use chalk_rust_ir::AssociatedTyDatum;
use chalk_rust_ir::AssociatedTyValue;
use chalk_rust_ir::AssociatedTyValueId;
use chalk_rust_ir::FnDefDatum;
use chalk_rust_ir::ImplDatum;
use chalk_rust_ir::OpaqueTyDatum;
use chalk_rust_ir::TraitDatum;
Expand Down Expand Up @@ -114,6 +116,10 @@ impl RustIrDatabase<ChalkIr> for ChalkDatabase {
self.program_ir().unwrap().adt_datum(id)
}

fn fn_def_datum(&self, id: FnDefId<ChalkIr>) -> Arc<FnDefDatum<ChalkIr>> {
self.program_ir().unwrap().fn_def_datum(id)
}

fn impls_for_trait(
&self,
trait_id: TraitId<ChalkIr>,
Expand Down
1 change: 1 addition & 0 deletions chalk-integration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub use interner::{Identifier, RawId};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum TypeSort {
Struct,
FnDef,
Trait,
Opaque,
}
Expand Down
140 changes: 131 additions & 9 deletions chalk-integration/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::interner::ChalkIr;
use chalk_ir::cast::{Cast, Caster};
use chalk_ir::interner::HasInterner;
use chalk_ir::{
self, AdtId, AssocTypeId, BoundVar, ClausePriority, DebruijnIndex, ImplId, OpaqueTyId,
self, AdtId, AssocTypeId, BoundVar, ClausePriority, DebruijnIndex, FnDefId, ImplId, OpaqueTyId,
QuantifiedWhereClauses, Substitution, ToGenericArg, TraitId,
};
use chalk_parse::ast::*;
Expand All @@ -19,9 +19,11 @@ use crate::program::Program as LoweredProgram;
use crate::{Identifier as Ident, RawId, TypeKind, TypeSort};

type AdtIds = BTreeMap<Ident, chalk_ir::AdtId<ChalkIr>>;
type FnDefIds = BTreeMap<Ident, chalk_ir::FnDefId<ChalkIr>>;
type TraitIds = BTreeMap<Ident, chalk_ir::TraitId<ChalkIr>>;
type OpaqueTyIds = BTreeMap<Ident, chalk_ir::OpaqueTyId<ChalkIr>>;
type AdtKinds = BTreeMap<chalk_ir::AdtId<ChalkIr>, TypeKind>;
type FnDefKinds = BTreeMap<chalk_ir::FnDefId<ChalkIr>, TypeKind>;
type TraitKinds = BTreeMap<chalk_ir::TraitId<ChalkIr>, TypeKind>;
type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId<ChalkIr>, Ident), AssociatedTyLookup>;
type AssociatedTyValueIds =
Expand All @@ -36,6 +38,8 @@ pub type LowerResult<T> = Result<T, RustIrError>;
struct Env<'k> {
adt_ids: &'k AdtIds,
adt_kinds: &'k AdtKinds,
fn_def_ids: &'k FnDefIds,
fn_def_kinds: &'k FnDefKinds,
trait_ids: &'k TraitIds,
trait_kinds: &'k TraitKinds,
opaque_ty_ids: &'k OpaqueTyIds,
Expand Down Expand Up @@ -73,6 +77,7 @@ struct AssociatedTyLookup {
enum TypeLookup {
Adt(chalk_ir::AdtId<ChalkIr>),
GenericArg(BoundVar),
FnDef(chalk_ir::FnDefId<ChalkIr>),
Opaque(chalk_ir::OpaqueTyId<ChalkIr>),
}

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

if let Some(id) = self.fn_def_ids.get(&name.str) {
return Ok(TypeLookup::FnDef(*id));
}

if let Some(id) = self.opaque_ty_ids.get(&name.str) {
return Ok(TypeLookup::Opaque(*id));
}
Expand Down Expand Up @@ -140,6 +149,10 @@ impl<'k> Env<'k> {
&self.adt_kinds[&id]
}

fn fn_def_kind(&self, id: chalk_ir::FnDefId<ChalkIr>) -> &TypeKind {
&self.fn_def_kinds[&id]
}

fn trait_kind(&self, id: chalk_ir::TraitId<ChalkIr>) -> &TypeKind {
&self.trait_kinds[&id]
}
Expand Down Expand Up @@ -240,9 +253,11 @@ impl LowerProgram for Program {
}

let mut adt_ids = BTreeMap::new();
let mut fn_def_ids = BTreeMap::new();
let mut trait_ids = BTreeMap::new();
let mut opaque_ty_ids = BTreeMap::new();
let mut adt_kinds = BTreeMap::new();
let mut fn_def_kinds = BTreeMap::new();
let mut trait_kinds = BTreeMap::new();
let mut opaque_ty_kinds = BTreeMap::new();
let mut object_safe_traits = HashSet::new();
Expand All @@ -254,6 +269,12 @@ impl LowerProgram for Program {
adt_ids.insert(type_kind.name.clone(), id);
adt_kinds.insert(id, type_kind);
}
Item::FnDefn(defn) => {
let type_kind = defn.lower_type_kind()?;
let id = FnDefId(raw_id);
fn_def_ids.insert(type_kind.name.clone(), id);
fn_def_kinds.insert(id, type_kind);
}
Item::TraitDefn(defn) => {
let type_kind = defn.lower_type_kind()?;
let id = TraitId(raw_id);
Expand All @@ -276,6 +297,7 @@ impl LowerProgram for Program {
}

let mut adt_data = BTreeMap::new();
let mut fn_def_data = BTreeMap::new();
let mut trait_data = BTreeMap::new();
let mut well_known_traits = BTreeMap::new();
let mut impl_data = BTreeMap::new();
Expand All @@ -287,6 +309,8 @@ impl LowerProgram for Program {
let empty_env = Env {
adt_ids: &adt_ids,
adt_kinds: &adt_kinds,
fn_def_ids: &fn_def_ids,
fn_def_kinds: &fn_def_kinds,
trait_ids: &trait_ids,
trait_kinds: &trait_kinds,
opaque_ty_ids: &opaque_ty_ids,
Expand All @@ -299,6 +323,13 @@ impl LowerProgram for Program {
let adt_id = AdtId(raw_id);
adt_data.insert(adt_id, Arc::new(d.lower_adt(adt_id, &empty_env)?));
}
Item::FnDefn(ref defn) => {
let fn_def_id = FnDefId(raw_id);
fn_def_data.insert(
fn_def_id,
Arc::new(defn.lower_fn_def(fn_def_id, &empty_env)?),
);
}
Item::TraitDefn(ref trait_defn) => {
let trait_id = TraitId(raw_id);
let trait_datum = trait_defn.lower_trait(trait_id, &empty_env)?;
Expand Down Expand Up @@ -454,10 +485,13 @@ impl LowerProgram for Program {

let program = LoweredProgram {
adt_ids,
fn_def_ids,
trait_ids,
adt_kinds,
fn_def_kinds,
trait_kinds,
adt_data,
fn_def_data,
trait_data,
well_known_traits,
impl_data,
Expand Down Expand Up @@ -538,6 +572,16 @@ impl LowerParameterMap for StructDefn {
}
}

impl LowerParameterMap for FnDefn {
fn synthetic_parameters(&self) -> Option<NamedGenericArg> {
None
}

fn declared_parameters(&self) -> &[VariableKind] {
&self.variable_kinds
}
}

impl LowerParameterMap for Impl {
fn synthetic_parameters(&self) -> Option<NamedGenericArg> {
None
Expand Down Expand Up @@ -631,6 +675,26 @@ impl LowerTypeKind for StructDefn {
}
}

impl LowerTypeKind for FnDefn {
fn lower_type_kind(&self) -> LowerResult<TypeKind> {
let interner = &ChalkIr;
Ok(TypeKind {
sort: TypeSort::FnDef,
name: self.name.str.clone(),
binders: chalk_ir::Binders::new(
chalk_ir::VariableKinds::from(interner, self.all_parameters().anonymize()),
crate::Unit,
),
})
}
}

impl LowerWhereClauses for FnDefn {
fn where_clauses(&self) -> &[QuantifiedWhereClause] {
&self.where_clauses
}
}

impl LowerWhereClauses for StructDefn {
fn where_clauses(&self) -> &[QuantifiedWhereClause] {
&self.where_clauses
Expand Down Expand Up @@ -850,6 +914,39 @@ impl LowerAdtDefn for StructDefn {
}
}

trait LowerFnDefn {
fn lower_fn_def(
&self,
fn_def_id: chalk_ir::FnDefId<ChalkIr>,
env: &Env,
) -> LowerResult<rust_ir::FnDefDatum<ChalkIr>>;
}

impl LowerFnDefn for FnDefn {
fn lower_fn_def(
&self,
fn_def_id: chalk_ir::FnDefId<ChalkIr>,
env: &Env,
) -> LowerResult<rust_ir::FnDefDatum<ChalkIr>> {
let binders = env.in_binders(self.all_parameters(), |env| {
let args: LowerResult<_> = self.argument_types.iter().map(|t| t.lower(env)).collect();
let where_clauses = self.lower_where_clauses(env)?;
let return_type = self.return_type.lower(env)?;

Ok(rust_ir::FnDefDatumBound {
argument_types: args?,
where_clauses,
return_type,
})
})?;

Ok(rust_ir::FnDefDatum {
id: fn_def_id,
binders,
})
}
}

trait LowerTraitRef {
fn lower(&self, env: &Env) -> LowerResult<chalk_ir::TraitRef<ChalkIr>>;
}
Expand Down Expand Up @@ -1121,6 +1218,22 @@ impl LowerTy for Ty {
}
}
TypeLookup::GenericArg(d) => Ok(chalk_ir::TyData::BoundVar(d).intern(interner)),
TypeLookup::FnDef(id) => {
let k = env.fn_def_kind(id);
if k.binders.len(interner) > 0 {
Err(RustIrError::IncorrectNumberOfTypeParameters {
identifier: name.clone(),
expected: k.binders.len(interner),
actual: 0,
})
} else {
Ok(chalk_ir::TyData::Function(chalk_ir::Fn {
num_binders: k.binders.len(interner),
substitution: chalk_ir::Substitution::empty(interner),
})
.intern(interner))
}
}
TypeLookup::Opaque(id) => Ok(chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(
chalk_ir::OpaqueTy {
opaque_ty_id: id,
Expand Down Expand Up @@ -1157,14 +1270,14 @@ impl LowerTy for Ty {
.intern(interner)),

Ty::Apply { name, ref args } => {
let id = match env.lookup_type(name)? {
TypeLookup::Adt(id) => id,
let (id, k) = match env.lookup_type(name)? {
TypeLookup::Adt(id) => (id.0, env.adt_kind(id)),
TypeLookup::GenericArg(_) | TypeLookup::Opaque(_) => {
Err(RustIrError::CannotApplyTypeParameter(name.clone()))?
}
TypeLookup::FnDef(id) => (id.0, env.fn_def_kind(id)),
};

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

Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
name: chalk_ir::TypeName::Adt(id),
substitution,
})
.intern(interner))
match k.sort {
TypeSort::FnDef => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
name: chalk_ir::TypeName::FnDef(FnDefId(id)),
substitution,
})
.intern(interner)),
_ => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
name: chalk_ir::TypeName::Adt(AdtId(id)),
substitution,
})
.intern(interner)),
}
}

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

let env = Env {
adt_ids: &program.adt_ids,
fn_def_ids: &program.fn_def_ids,
trait_ids: &program.trait_ids,
opaque_ty_ids: &program.opaque_ty_ids,
adt_kinds: &program.adt_kinds,
fn_def_kinds: &program.fn_def_kinds,
trait_kinds: &program.trait_kinds,
associated_ty_lookups: &associated_ty_lookups,
parameter_map: BTreeMap::new(),
Expand Down
18 changes: 14 additions & 4 deletions chalk-integration/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use crate::{tls, Identifier, TypeKind};
use chalk_ir::could_match::CouldMatch;
use chalk_ir::debug::Angle;
use chalk_ir::{
debug::SeparatorTraitRef, AdtId, AliasTy, ApplicationTy, AssocTypeId, GenericArg, Goal, Goals,
ImplId, Lifetime, OpaqueTy, OpaqueTyId, ProgramClause, ProgramClauseImplication,
debug::SeparatorTraitRef, AdtId, AliasTy, ApplicationTy, AssocTypeId, FnDefId, GenericArg,
Goal, Goals, ImplId, Lifetime, OpaqueTy, OpaqueTyId, ProgramClause, ProgramClauseImplication,
ProgramClauses, ProjectionTy, Substitution, TraitId, Ty,
};
use chalk_rust_ir::{
AdtDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ImplDatum, ImplType,
OpaqueTyDatum, TraitDatum, WellKnownTrait,
AdtDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, FnDefDatum, ImplDatum,
ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait,
};
use chalk_solve::split::Split;
use chalk_solve::RustIrDatabase;
Expand All @@ -25,6 +25,10 @@ pub struct Program {
/// For each ADT:
pub adt_kinds: BTreeMap<AdtId<ChalkIr>, TypeKind>,

pub fn_def_ids: BTreeMap<Identifier, FnDefId<ChalkIr>>,

pub fn_def_kinds: BTreeMap<FnDefId<ChalkIr>, TypeKind>,

/// From trait name to item-id. Used during lowering only.
pub trait_ids: BTreeMap<Identifier, TraitId<ChalkIr>>,

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

pub fn_def_data: BTreeMap<FnDefId<ChalkIr>, Arc<FnDefDatum<ChalkIr>>>,

/// For each impl:
pub impl_data: BTreeMap<ImplId<ChalkIr>, Arc<ImplDatum<ChalkIr>>>,

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

fn fn_def_datum(&self, id: FnDefId<ChalkIr>) -> Arc<FnDefDatum<ChalkIr>> {
self.fn_def_data[&id].clone()
}

fn impls_for_trait(
&self,
trait_id: TraitId<ChalkIr>,
Expand Down
9 changes: 9 additions & 0 deletions chalk-ir/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ where
}
}

impl<I> CastTo<TypeName<I>> for FnDefId<I>
where
I: Interner,
{
fn cast_to(self, _interner: &I) -> TypeName<I> {
TypeName::FnDef(self)
}
}

impl<T> CastTo<T> for &T
where
T: Clone + HasInterner,
Expand Down
Loading

0 comments on commit c0daf93

Please sign in to comment.