Skip to content

refactor Program to separating lowering from solving #19

Closed
@nikomatsakis

Description

@nikomatsakis

Right now the ir::Program struct contains a lot of fields that encode the lowered Rust program:

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Program {
    /// From type-name to item-id. Used during lowering only.
    pub type_ids: HashMap<Identifier, ItemId>,

    /// For each struct/trait:
    pub type_kinds: HashMap<ItemId, TypeKind>,

    /// For each impl:
    pub impl_data: HashMap<ItemId, ImplDatum>,

    /// For each trait:
    pub trait_data: HashMap<ItemId, TraitDatum>,

    /// For each trait:
    pub associated_ty_data: HashMap<ItemId, AssociatedTyDatum>,

    /// Compiled forms of the above:
    pub program_clauses: Vec<ProgramClause>,
}

Since the trait solving routines in solve get access to an Arc<Program>, this suggests that they need all of this information. But in fact they do not. The goal is that they only need program_clauses, although it may be useful to have a bit more (basically, it depends a bit on how much code we lower to explicit program-clauses and how much code we choose to keep in Rust code).

However, these fields are used during lowering. And in particular we lower the input program and then, in the unit tests, save that state and come back and lower various goals.

I think we should introduce a new struct, let's call it the SharedEnvironment or ProgramEnvironment, which is used by the solving routines and contains only those fields needed by solving.

Looking through the code that would be two fields:

So we could refactor Program like so:

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Program {
    /// From type-name to item-id. Used during lowering only.
    pub type_ids: HashMap<Identifier, ItemId>,

    /// For each struct/trait:
    pub type_kinds: HashMap<ItemId, TypeKind>,

    /// For each impl:
    pub impl_data: HashMap<ItemId, ImplDatum>,

    /// For each trait:
    pub associated_ty_data: HashMap<ItemId, AssociatedTyDatum>,

    /// Data used by the solver routines:
    pub program_env: Arc<ProgramEnvironment>
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ProgramEnvironment {
    /// For each trait:
    pub trait_data: HashMap<ItemId, TraitDatum>,

    /// Compiled forms of the above:
    pub program_clauses: Vec<ProgramClause>,
}

Here I moved the trait_data field into the program-env. Another option would be to duplicate it. In that case, I suspect that Program would not need to have a link to the program-env at all. Instead, lowering could return a pair of (Program, ProgramEnvironment).

We would then also change the solve routines to take an Arc<ProgramEnvironment> instead of Arc<Program>.

I'm tagging this as help-wanted since it seems like a relatively good "intro bug".

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueA good issue to start working on Chalk with

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions