Skip to content

Commit dd03cf7

Browse files
authored
Merge pull request #95 from nikomatsakis/traits-lowering-deets
describe how the lowering code works
2 parents fc109db + 28da7a0 commit dd03cf7

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

Diff for: src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- [Canonical queries](./traits-canonical-queries.md)
3434
- [Canonicalization](./traits-canonicalization.md)
3535
- [Lowering rules](./traits-lowering-rules.md)
36+
- [The lowering module in rustc](./traits-lowering-module.md)
3637
- [Well-formedness checking](./traits-wf.md)
3738
- [The SLG solver](./traits-slg.md)
3839
- [Bibliography](./traits-bibliography.md)

Diff for: src/traits-lowering-module.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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

Comments
 (0)