Closed
Description
The purpose of this issue is to setup a trait-solving structure that can change between the current trait solver and the type checker, allowing for us to easily switch to the chalk-style solving when a command line flag is given.
Currently, the interface between the two is the FulfillmentContext
, so we have a relationship like this:
[ type checker ] --> [ fulfillment context ] --> [ existing trait solver ]
The first phase then is to introduce another layer in between, let's call it the TraitEngine
:
[ type checker ] --> [ TraitEngine ] --> [ fulfillment context ] --> [ existing trait solver ]
When we're done with this phase, everything should work exactly the same, but that the type checker never interacts directly with the fulfillment context.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
nikomatsakis commentedon Mar 9, 2018
Mentoring instructions (part 1)
How it works today
The main interaction that the type checker has with the fulfillment context is to "register" obligations with it and try to solve them. Registering is primarily done with this method:
rust/src/librustc/traits/fulfill.rs
Lines 147 to 149 in fedce67
Solving is done with
select_where_possible
, which selects obligations when it can, but defers in the case of ambiguity:rust/src/librustc/traits/fulfill.rs
Lines 193 to 195 in fedce67
And
select_all_or_error
, which selects obligations and reports errors if anything comes up as ambiguous (maybe true, maybe false):rust/src/librustc/traits/fulfill.rs
Lines 175 to 177 in fedce67
Step 1: Introduce
TraitEngine
traitWe should introduce a new module, let's call it
rustc::traits::engine
. In there would be a traitTraitEngine
that (to start) encapsulates aFulfilllmentContext
:Then we can have
FulfillmentContext
implement this trait. This could be done by forwarding to the inherent methods, or by moving them out from the inherent impl:Finally, we create a factory method on
TraitEngine
; for now it can always create a fulfillment context. The important part is that it returns aBox<dyn TraitEngine<'tcx>>
:Next, we want to modify typeck to use this. For that, we would modify this field from having type
RefCell<traits::FulfillmentContext<'tcx>>
toRefCell<Box<dyn TraitEngine<'tcx>>>
:rust/src/librustc_typeck/check/mod.rs
Line 198 in fedce67
There may be other uses of
FulfillmentContext
withinlibrustc_typeck
, you can ripgrep around. We should be able to convert them all.Step 2: Add compiler flag and alternative implementation
I'll leave this step for later. =)
nikomatsakis commentedon Mar 9, 2018
cc @rust-lang/wg-traits -- this is the refactoring step that will allow us to introduce
-Zchalk
and change implementations. Mentoring instructions are included, looking for someone to pick it up!sgrif commentedon Mar 9, 2018
This is the sort of structural change that is right up my alley (but I also have a non-zero number of things already on my plate so if someone else is looking for a thing to do, go for it)
csmoe commentedon Mar 11, 2018
This work looks not so hard for a rustlang newbie from the mentoring instructions up to now.
If I didn’t underestimate the difficulty, please consider me for this.
nikomatsakis commentedon Mar 12, 2018
@csmoe I don't think this will be very hard! Please feel free to leave questions here (but expect longer latency) or ping me on gitter (shorter latency)
[-]introduce abstraction layer between trait solver and type checker[/-][+]🛠 introduce abstraction layer between trait solver and type checker[/+]nikomatsakis commentedon Mar 20, 2018
@csmoe How goes? Have you had a chance to take a look at this yet? It would be very useful. =)
csmoe commentedon Mar 20, 2018
@nikomatsakis I have done mostly, but stuck at the lifetime errors.
7 remaining items