| 
 | 1 | +# The lowering module in rustc  | 
 | 2 | + | 
 | 3 | +The program clauses described in the  | 
 | 4 | +[lowering rules](./traits-lowering-rules.html) section are actually  | 
 | 5 | +created in the [`rustc_traits::lowering`][lowering] module.  | 
 | 6 | + | 
 | 7 | +[lowering]: https://github.com/rust-lang/rust/tree/master/src/librustc_traits/lowering.rs  | 
 | 8 | + | 
 | 9 | +## The `program_clauses_for` query  | 
 | 10 | + | 
 | 11 | +The main entry point is the `program_clauses_for` [query], which --  | 
 | 12 | +given a def-id -- produces a set of Chalk program clauses. These  | 
 | 13 | +queries are tested using a  | 
 | 14 | +[dedicated unit-testing mechanism, described below](#unit-tests).  The  | 
 | 15 | +query is invoked on a `DefId` that identifies something like a trait,  | 
 | 16 | +an impl, or an associated item definition. It then produces and  | 
 | 17 | +returns a vector of program clauses.  | 
 | 18 | + | 
 | 19 | +[query]: ./query.html  | 
 | 20 | + | 
 | 21 | +<a name=unit-tests>  | 
 | 22 | + | 
 | 23 | +## Unit tests  | 
 | 24 | + | 
 | 25 | +Unit tests are located in [`src/test/ui/chalkify`][chalkify]. A good  | 
 | 26 | +example test is [the `lower_impl` test][lower_impl]. At the time of  | 
 | 27 | +this writing, it looked like this:  | 
 | 28 | + | 
 | 29 | +```rust  | 
 | 30 | +#![feature(rustc_attrs)]  | 
 | 31 | + | 
 | 32 | +trait Foo { }  | 
 | 33 | + | 
 | 34 | +#[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :-  | 
 | 35 | +impl<T: 'static> Foo for T where T: Iterator<Item = i32> { }  | 
 | 36 | + | 
 | 37 | +fn main() {  | 
 | 38 | +    println!("hello");  | 
 | 39 | +}  | 
 | 40 | +```  | 
 | 41 | + | 
 | 42 | +The `#[rustc_dump_program_clauses]` annotation can be attached to  | 
 | 43 | +anything with a def-id.  (It requires the `rustc_attrs` feature.) The  | 
 | 44 | +compiler will then invoke the `program_clauses_for` query on that  | 
 | 45 | +item, and emit compiler errors that dump the clauses produced. These  | 
 | 46 | +errors just exist for unit-testing, as we can then leverage the  | 
 | 47 | +standard [ui test] mechanisms to check them. In this case, there is a  | 
 | 48 | +`//~ ERROR Implemented` annotation which is intentionally minimal (it  | 
 | 49 | +need only be a prefix of the error), but [the stderr file] contains  | 
 | 50 | +the full details:  | 
 | 51 | + | 
 | 52 | +```  | 
 | 53 | +error: Implemented(T: Foo) :- ProjectionEq(<T as std::iter::Iterator>::Item == i32), TypeOutlives(T \  | 
 | 54 | +: 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized).  | 
 | 55 | +  --> $DIR/lower_impl.rs:15:1  | 
 | 56 | +   |  | 
 | 57 | +LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :-  | 
 | 58 | +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  | 
 | 59 | +
  | 
 | 60 | +error: aborting due to previous error  | 
 | 61 | +```  | 
 | 62 | + | 
 | 63 | +[chalkify]: https://github.com/rust-lang/rust/tree/master/src/test/ui/chalkify  | 
 | 64 | +[lower_impl]: https://github.com/rust-lang/rust/tree/master/src/test/ui/chalkify/lower_impl.rs  | 
 | 65 | +[the stderr file]: https://github.com/rust-lang/rust/tree/master/src/test/ui/chalkify/lower_impl.stderr  | 
 | 66 | +[ui test]: https://rust-lang-nursery.github.io/rustc-guide/tests/adding.html#guide-to-the-ui-tests  | 
0 commit comments