Skip to content

Commit 2c072cc

Browse files
authored
Merge pull request #406 from detrumi/book-improvements
Book improvements
2 parents 109e18b + 50266d2 commit 2c072cc

11 files changed

+222
-219
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
A [Prolog-ish][Prolog] interpreter written in Rust, intended perhaps for use in
88
the compiler, but also for experimentation.
99

10+
See the [Chalk book](https://rust-lang.github.io/chalk/book/) for more information.
11+
1012
## FAQ
1113

1214
**How does chalk relate to rustc?** The plan is to have rustc use the `chalk-engine` crate (in this repo), which defines chalk's solver. The rest of chalk can then be considered an elaborate unit testing harness. For more details, see [the Traits chapter of the rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/traits/index.html).
@@ -51,8 +53,9 @@ Unique; substitution [], lifetime constraints []
5153
If you'd like to contribute, consider joining the [Traits Working Group][working-group].
5254
We hang out on the [rust-lang zulip][rust-lang-zulip] in the [#wg-traits][wg-traits-stream] stream.
5355

54-
See [CONTRIBUTING.md](CONTRIBUTING.md) for more info.
56+
See [the contributing chapter][contributing] in the chalk book for more info.
5557

5658
[working-group]: https://rust-lang.github.io/compiler-team/working-groups/traits/
5759
[rust-lang-zulip]:https://rust-lang.zulipchat.com
5860
[wg-traits-stream]: https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits
61+
[contributing]: https://rust-lang.github.io/chalk/book/contributing.html

book/src/SUMMARY.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22

33
- [What is Chalk?](./what_is_chalk.md)
44
- [Crates](./what_is_chalk/crates.md)
5+
- [REPL](./what_is_chalk/repl.md)
56
- [Contribution guide](./contribution_guide.md)
6-
- [REPL](./repl.md)
7-
- [Representing and manipulating Rust types](./types.md)
8-
- [The role of the `Interner`](./types/role_of_interner.md)
9-
- [Controlling representation with `Interner`](./types/how_to_control_repr.md)
7+
- [Representing and manipulating types](./types.md)
8+
- [The `Interner`](./types/role_of_interner.md)
109
- [Rust types](./types/rust_types.md)
1110
- [Application types](./types/rust_types/application_ty.md)
1211
- [Rust lifetimes](./types/rust_lifetimes.md)
1312
- [Operations](./types/operations.md)
1413
- [Fold and the Folder trait](./types/operations/fold.md)
15-
- [Representing traits, impls, and other parts of Rust programs](./rust_ir.md)
1614
- [Lowering Rust IR to logic](./clauses.md)
1715
- [Goals and clauses](./clauses/goals_and_clauses.md)
1816
- [Type equality and unification](./clauses/type_equality.md)
@@ -21,7 +19,7 @@
2119
- [Well-formedness checking](./clauses/wf.md)
2220
- [Canonical queries](./canonical_queries.md)
2321
- [Canonicalization](./canonical_queries/canonicalization.md)
24-
- [How does the engine work](./engine.md)
22+
- [Chalk engine](./engine.md)
2523
- [Major concepts](./engine/major_concepts.md)
2624
- [Logic](./engine/logic.md)
2725
- [Coinduction](./engine/logic/coinduction.md)

book/src/contribution_guide.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,75 @@
11
# Contribution guide
2+
3+
Thank you for your interest in contributing to chalk! There are many ways to
4+
contribute, and we appreciate all of them.
5+
6+
* [Bug Reports](#bug-reports)
7+
* [Running and Debugging](#running-and-debugging)
8+
* [Pull Requests](#pull-requests)
9+
* [Writing Documentation](#writing-documentation)
10+
11+
If you'd like to contribute, consider joining the [Traits Working Group][traits-working-group].
12+
We hang out on the [rust-lang zulip][rust-lang-zulip] in the [#wg-traits][wg-traits-stream] stream.
13+
14+
As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
15+
16+
[traits-working-group]: https://rust-lang.github.io/compiler-team/working-groups/traits/
17+
[rust-lang-zulip]:https://rust-lang.zulipchat.com
18+
[wg-traits-stream]: https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits
19+
[coc]: https://www.rust-lang.org/conduct.html
20+
21+
## Bug Reports
22+
[bug-reports]: #bug-reports
23+
24+
While bugs are unfortunate, they're a reality in software. We can't fix what we
25+
don't know about, so please report liberally. If you're not sure if something
26+
is a bug or not, feel free to file a bug anyway.
27+
28+
If you have the chance, before reporting a bug, please search existing issues,
29+
as it's possible that someone else has already reported your error. This doesn't
30+
always work, and sometimes it's hard to know what to search for, so consider
31+
this extra credit. We won't mind if you accidentally file a duplicate report.
32+
33+
Sometimes, a backtrace is helpful, and so including that is nice. To get
34+
a backtrace, set the `RUST_BACKTRACE` environment variable to a value
35+
other than `0`. The easiest way to do this is to invoke `chalk` like this:
36+
37+
```bash
38+
$ RUST_BACKTRACE=1 chalk ...
39+
```
40+
41+
## Running and Debugging
42+
[running-and-debugging]: #running-and-debugging
43+
There is a repl mainly for debugging purposes which can be run by `cargo run`. Some basic examples are in [libstd.chalk](https://github.com/rust-lang/chalk/blob/master/libstd.chalk):
44+
```bash
45+
$ cargo run
46+
?- load libstd.chalk
47+
?- Vec<Box<i32>>: Clone
48+
Unique; substitution [], lifetime constraints []
49+
```
50+
51+
More logging can be enabled by setting the `CHALK_DEBUG` environment variable. Set `CHALK_DEBUG=1` to see `info!(...)` output, and `CHALK_DEBUG=2` to see `debug!(...)` output as well.
52+
53+
## Pull Requests
54+
[pull-requests]: #pull-requests
55+
56+
Pull requests are the primary mechanism we use to change Rust. GitHub itself
57+
has some [great documentation][pull-request-documentation] on using the Pull Request feature.
58+
We use the "fork and pull" model [described here][development-models], where
59+
contributors push changes to their personal fork and create pull requests to
60+
bring those changes into the source repository.
61+
62+
Please make pull requests against the `master` branch.
63+
64+
[pull-request-documentation]: https://help.github.com/articles/about-pull-requests/
65+
[development-models]: https://help.github.com/articles/about-collaborative-development-models/
66+
67+
## Writing Documentation
68+
[writing-documentation]: #writing-documentation
69+
70+
Documentation improvements are very welcome. Documentation pull requests
71+
function in the same way as other pull requests.
72+
73+
You can find documentation style guidelines in [RFC 1574][rfc1574].
74+
75+
[rfc1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text

book/src/rust_ir.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

book/src/types.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Representing and manipulating Rust types
22

3+
## Intermediate representations
4+
5+
Intermediate representations (IR) are used to represent parts of Rust programs such as traits and impls.
6+
7+
Chalk contains three levels of IR:
8+
9+
- The **AST**. This is used purely for writing test cases
10+
with a Rust-like syntax. This is consumed by **lowering** code, which
11+
takes AST and products **Rust IR** (the next bullet point).
12+
- The **Rust IR**. This is a "HIR-like" notation that defines the
13+
interesting properties of things like traits, impls, and structs.
14+
It is an input to the **rules** code, which produces
15+
- The **Chalk IR**. This is most "Prolog-like" of the various IRs. It
16+
contains the definition of **types** as well as prolog-like concepts
17+
such as goals (things that must be proven true) and clauses (things
18+
that are assumed to be true).
19+
20+
321
## Goal of the chalk-ir crate
422

523
To have an ergonomic, flexible library that can abstractly represent
@@ -44,8 +62,8 @@ Chalk as of today to match this document:
4462
* Extract `TypeName` into something opaque to chalk-ir.
4563
* Dyn type equality should probably be driven by entailment.
4664
* Projections need to be renamed to aliases.
47-
* The variant we use for impl traits should be removed and folded into type aliases.
65+
* The variant we use for impl traits should be removed and folded into type aliases.
4866
* Remove placeholders and projection placeholders from apply and create placeholder types.
4967
* Move `Error` from a `TypeName` to its own variant.
5068
* Introduce `GeneratorWitness` into chalk
51-
* Complete transition from `ForAll` to `Fn` in chalk
69+
* Complete transition from `ForAll` to `Fn` in chalk

book/src/types/how_to_control_repr.md

Lines changed: 0 additions & 68 deletions
This file was deleted.

book/src/types/role_of_interner.md

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Most everything in the IR is parameterized by the [`Interner`] trait:
55
[`Interner`]: http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html
66

77
```rust,ignore
8-
trait Interner: Copy + Clone + Debug + Eq + Ord {
8+
trait Interner: Copy + Clone + Debug + Eq + Ord {
99
..
1010
}
1111
```
@@ -16,3 +16,72 @@ the interner is defined by the embedded and can be used to control
1616
other things in memory. For example, the `Interner` trait could be
1717
used to intern all the types, as rustc does, or it could be used to
1818
`Box` them instead, as the chalk testing harness currently does.
19+
20+
### Controlling representation with `Interner`
21+
22+
The purpose of the [`Interner`] trait is to give control over how
23+
types and other bits of chalk-ir are represented in memory. This is
24+
done via an "indirection" strategy. We'll explain that strategy here
25+
in terms of [`Ty`] and [`TyData`], the two types used to represent
26+
Rust types, but the same pattern is repeated for many other things.
27+
28+
[`Interner`]: http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html
29+
[`Ty`]: http://rust-lang.github.io/chalk/chalk_ir/struct.Ty.html
30+
[`TyData`]: http://rust-lang.github.io/chalk/chalk_ir/enum.TyData.html
31+
32+
Types are represented by a [`Ty<I>`] type and the [`TyData<I>`] enum.
33+
There is no *direct* connection between them. The link is rather made
34+
by the [`Interner`] trait, via the [`InternedTy`] associated type:
35+
36+
[`Ty<I>`]: http://rust-lang.github.io/chalk/chalk_ir/struct.Ty.html
37+
[`TyData<I>`]: http://rust-lang.github.io/chalk/chalk_ir/enum.TyData.html
38+
[`InternedTy`]: http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#associatedtype.InternedType
39+
40+
```rust,ignore
41+
struct Ty<I: Interner>(I::InternedTy);
42+
enum TyData<I: Interner> { .. }
43+
```
44+
45+
The way this works is that the [`Interner`] trait has an associated
46+
type [`InternedTy`] and two related methods, [`intern_ty`] and [`ty_data`]:
47+
48+
[`intern_ty`]: http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#tymethod.intern_ty
49+
[`ty_data`]: http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#tymethod.ty_data
50+
51+
```rust,ignore
52+
trait Interner {
53+
type InternedTy;
54+
55+
fn intern_ty(&self, data: &TyData<Self>) -> Self::InternedTy;
56+
fn ty_data(data: &Self::InternedTy) -> &TyData<Self>;
57+
}
58+
```
59+
60+
However, as a user you are not meant to use these directly. Rather,
61+
they are encapsulated in methods on the [`Ty`] and [`TyData`] types:
62+
63+
```rust,ignore
64+
impl<I: Interner> Ty<I> {
65+
fn data(&self) -> &TyData<I> {
66+
I::lookup_ty(self)
67+
}
68+
}
69+
```
70+
71+
and
72+
73+
```rust,ignore
74+
impl<I: Interner> TyData<I> {
75+
fn intern(&self, I: &I) -> Ty<I> {
76+
Ty(i.intern_ty(self))
77+
}
78+
}
79+
```
80+
81+
Note that there is an assumption here that [`ty_data`] needs no
82+
context. This effectively constrains the [`InternedTy`] representation
83+
to be a `Box` or `&` type. To be more general, at the cost of some
84+
convenience, we could make that a method as well, so that one would
85+
invoke `ty.data(i)` instead of just `ty.data()`. This would permit us
86+
to use (for example) integers to represent interned types, which might
87+
be nice (e.g., to permit using generational indices).

book/src/what_is_chalk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ Likewise, lowering tests use the [`lowering_success!` and
206206
## More Resources
207207

208208
* [Chalk Source Code](https://github.com/rust-lang/chalk)
209-
* [Chalk Glossary](https://github.com/rust-lang/chalk/blob/master/GLOSSARY.md)
209+
* [Chalk Glossary](glossary.md)
210210

211211
[goals-and-clauses]: ./clauses/goals_and_clauses.html
212212
[HIR]: https://rustc-dev-guide.rust-lang.org/hir.html

book/src/what_is_chalk/crates.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ other programs:
1717

1818
The following crate is an implementation detail, used internally by `chalk-solve`:
1919

20-
* The `chalk-engine` crate, which defines the actual engine that solves logical predicate. This
20+
* The `chalk-engine` crate, which defines the actual engine that solves logical predicate. This
2121
engine is quite general and not really specific to Rust.
2222
* The `chalk-derive` crate defines custom derives for the `chalk_ir::fold::Fold` trait and other
2323
such things.
@@ -35,3 +35,42 @@ define a kind of "minimal embedding" of chalk.
3535
`chalk-rust-ir` by a process called "lowering'.
3636
* Finally, the main `chalk` crate, along with the testing crate in the
3737
`tests` directory, define the actual entry points.
38+
39+
## The chalk-solve crate
40+
41+
| The `chalk-solve` crate | |
42+
|---|--- |
43+
| Purpose: | to solve a given goal |
44+
| Depends on IR: | chalk-ir and rust-ir |
45+
| Context required: | `RustIrDatabase` |
46+
47+
The `chalk-solve` crate exposes a key type called `Solver`. This is a
48+
solver that, given a goal (expressed in chalk-ir) will solve the goal
49+
and yield up a `Solution`. The solver caches intermediate data between
50+
invocations, so solving the same goal twice in a row (or solving goals
51+
with common subgoals) is faster.
52+
53+
The solver is configured by a type that implements the
54+
`RustIrDatabase` trait. This trait contains some callbacks that
55+
provide needed context for the solver -- notably, the solver can ask:
56+
57+
- **What are the program clauses that might solve given rule?** This
58+
is answered by the code in the chalk-solve crate.
59+
- **Is this trait coinductive?** This is answered by the chalk-ir.
60+
61+
62+
## The chalk-engine crate
63+
64+
| The `chalk-engine` crate | |
65+
|---|--- |
66+
| Purpose: | define the base solving strategy |
67+
| IR: | none |
68+
| Context required: | `Context` trait |
69+
70+
For the purposes of chalk, the `chalk-engine` crate is effectively
71+
encapsulated by `chalk-solve`. It defines the base SLG engine. It is
72+
written in a very generic style that knows next to nothing about Rust
73+
itself. The engine can be configured via the traits defined in
74+
`chalk_engine::context::Context`, which contain (for example)
75+
associated types that define what a goal or clause is, as well as
76+
functions that operate on those things.

book/src/what_is_chalk/repl.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# REPL
2+
3+
There is a repl mainly for debugging purposes which can be run by `cargo run`. Some basic examples are in [libstd.chalk](https://github.com/rust-lang/chalk/blob/master/libstd.chalk):
4+
```bash
5+
$ cargo run
6+
?- load libstd.chalk
7+
?- Vec<Box<i32>>: Clone
8+
Unique; substitution [], lifetime constraints []
9+
```

0 commit comments

Comments
 (0)