|
1 | 1 | # Well known traits |
2 | 2 |
|
3 | | -Not all traits can be encoded in Rust's type system: special traits |
4 | | -like `Sized`, `Drop` or `Unsize` need additional compiler support in order to |
5 | | -function properly. To address this, chalk introduces a notion of `WellKnownTrait`s: |
6 | | -a subset of rustc's trait lang items that need special handling in trait system logic. |
7 | | - |
8 | | -As an example, consider the following two aspects of `Sized` logic: |
9 | | - 1) In order to prove that a struct implements `Sized`, we need to prove |
10 | | - that the last field of that struct is `Sized`. |
11 | | - 2) Structs need all of their fields, except, maybe, the last one to be `Sized`. |
12 | | - |
13 | | -Neither of those aspects are expressable in Rust, so chalk generates |
14 | | -special clauses used to encode them. These examples illustrate two main |
15 | | -places that deal with well known traits: |
16 | | -1) [`chalk-solve\clauses\builtin_traits`][builtin_traits_mod], which generates |
17 | | - requirements for proving that a given type implements a well known trait. |
| 3 | +For most traits, the question of whether some type T implements the trait is determined by |
| 4 | +looking solely at the impls that exist for the trait. But there are some well-known traits |
| 5 | +where we have "built-in" impls that are never expressly written in the compiler, they are |
| 6 | +built-in to the language itself. In some cases, these impls also encode complex conditions |
| 7 | +that an ordinary impl cannot express. To address this, chalk has a notion of a `WellKnownTrait` |
| 8 | +-- basically, a trait which is inherent to the language and where we will generate custom logic. |
| 9 | + |
| 10 | +As an example, consider the logic for `Sized` in regards to structs: A struct can have |
| 11 | +at most one `!Sized` field, and it must be the last. And the last field isn't `Sized`, |
| 12 | +then neither is the struct itself. |
| 13 | + |
| 14 | +Chalk has two main places that deal with well known trait logic: |
| 15 | +1) [`chalk-solve\clauses\builtin_traits`][builtin_traits_mod], which generates built-in implementations |
| 16 | +for well-known traits. |
18 | 17 | 2) [well-formedness](wf.md) checks, some of which need to know about well known traits. |
19 | 18 |
|
20 | 19 | [builtin_traits_mod]: https://github.com/rust-lang/chalk/blob/master/chalk-solve/src/clauses/builtin_traits.rs |
21 | 20 |
|
22 | 21 | # Auto traits |
23 | 22 |
|
24 | | -Auto traits are another kind of well known traits. |
25 | | -The idea is that the type implements an auto trait if all data owned by that type implements it, |
26 | | -with an ability to opt-out via special syntax: |
27 | | -```rust,ignore |
28 | | -impl !AutoTrait for Foo {} |
29 | | -``` |
30 | | -Common examples of auto trais are `Send` and `Sync`. Since this semantic is not expressable with |
31 | | -"regular" impls, it needs special support in chalk too. |
| 23 | +Auto traits, while not exactly well known traits, do also have special logic. |
| 24 | +The idea is that the type implements an auto trait if all data owned by that type implements it, |
| 25 | +with an ability to specifically opt-out or opt-in. Additionally, auto traits are [coinductive][coinductive_section]. |
| 26 | +Some common examples of auto traits are `Send` and `Sync`. |
| 27 | + |
| 28 | +[coinductive_section]: ../engine/logic/coinduction.html#coinduction-and-refinement-strands |
32 | 29 |
|
33 | 30 | # Current state |
34 | 31 | | Type | Copy | Clone | Sized | Unsize | Drop | Fn | Unpin | Generator | auto traits | |
35 | 32 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | |
36 | | -| tuple types | ✅ | ✅ | ✅ | ✅ | 🗿 | 🗿 | 🗿 | 🗿 | ❌ | |
37 | | -| structs | 🗿 | 🗿 | ✅ | ✅ | 🗿 | 🗿 | 🗿 | 🗿 | ✅ | |
38 | | -| scalar types | 📚 | 📚 | ✅ | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | ❌ | |
39 | | -| trait objects | 🗿 | 🗿 | 🗿 | ✅ | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | |
40 | | -| functions | ✅ | ✅ | ✅ | 🗿 | 🗿 | ❌ | 🗿 | 🗿 | ❌ | |
41 | | -| arrays❌ | ❌ | ❌ | ❌ | ❌ | 🗿 | 🗿 | 🗿 | 🗿 | ❌ | |
42 | | -| slices❌ | ❌ | ❌ | 🗿 | ❌ | 🗿 | 🗿 | 🗿 | 🗿 | ❌ | |
43 | | -| closures❌ | ❌ | ❌ | ❌ | 🗿 | 🗿 | ❌ | 🗿 | 🗿 | ❌ | |
44 | | -| generators❌ | 🗿 | 🗿 | ❌ | 🗿 | 🗿 | 🗿 | ❌ | ❌ | ❌ | |
45 | | -| gen. witness❌ | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | 🗿 | ❌ | |
| 33 | +| tuple types | ✅ | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | |
| 34 | +| structs | ⚬ | ⚬ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ | |
| 35 | +| scalar types | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | |
| 36 | +| trait objects | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| 37 | +| functions ptrs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ❌ | |
| 38 | +| arrays❌ | ❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | |
| 39 | +| slices❌ | ❌ | ❌ | ⚬ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | |
| 40 | +| closures❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ❌ | |
| 41 | +| generators❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ⚬ | ❌ | ❌ | ❌ | |
| 42 | +| gen. witness❌ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | |
46 | 43 | | ----------- | | | | | | | | | | |
47 | | -| well-formedness | ✅ | 🗿 | ✅ | 🗿 | ✅ | 🗿 | 🗿 | 🗿 | 🗿 | |
| 44 | +| well-formedness | ✅ | ⚬ | ✅ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | |
48 | 45 |
|
49 | 46 | legend: |
50 | | -🗿 - not applicable |
| 47 | +⚬ - not applicable |
51 | 48 | ✅ - implemented |
52 | 49 | 📚 - implementation provided in libcore |
53 | 50 | ❌ - not implemented |
54 | | -❌ in the column type means that type is not yet in chalk |
55 | 51 |
|
56 | | -The list of types not yet in chalk is not full, but auto traits/`WellKnownTrait`s |
57 | | -implementation for them is fairly trivial, so it is not listed here. |
| 52 | +❌ after a type name means that type is not yet in chalk |
0 commit comments