Skip to content

new chapter with examples of diagnostic translation PRs #1621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2,025 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
2025 commits
Select commit Hold shift + click to select a range
2b87b31
remove stray markup
tshepang Jul 18, 2022
5c8febd
Fix link to clippy sync docs
fasterthanlime Jul 19, 2022
bac43d0
Link to rendered book directly
fasterthanlime Jul 19, 2022
d5201cd
Debuginfo tests now also support revisions.
luqmana Jul 20, 2022
bcc1166
rust-analyzer is now a subtree
fasterthanlime Jul 25, 2022
c7637de
Add documentation about Microsoft provided debuggers and CodeView/PDB…
ridwanabdillahi Jul 25, 2022
e5e5a9b
Document how to build a cross-compiler
bstrie Jul 22, 2022
30a4d2b
Add instructions to fix build errors in std after adding a new target
Urgau Jul 29, 2022
c0b491e
Fix the link to `Lazy<T>`
JohnTitor Jul 26, 2022
18fa8fb
Fix the link to `ProcMacro` trait
JohnTitor Jul 26, 2022
bbbd60d
Fix the link to `ResolverAstLowering`
JohnTitor Jul 26, 2022
637ebaa
Fix the link to clippy docs
JohnTitor Jul 26, 2022
7955bb3
Prefer relative links
JohnTitor Jul 26, 2022
ea7e58a
minor fixes
tshepang Jul 30, 2022
67af5ca
revamp doc-build chapter
tshepang Jul 19, 2022
6f97f45
Update src/building/compiler-documenting.md
tshepang Jul 22, 2022
d9596c6
summary of chapter
tshepang Jul 30, 2022
3389074
try address review comments
tshepang Jul 30, 2022
3678b50
accept review suggestion
tshepang Jul 31, 2022
04f3cf0
address review comment
tshepang Jul 31, 2022
2557089
make date-check more lightweight (#1394)
tshepang Aug 2, 2022
5c4b673
date-check: be more strict
tshepang Aug 2, 2022
e305a42
note is now too old to be relevant
tshepang Aug 7, 2022
6964f75
date-check: rustc_codegen_ssa is still alive
tshepang Aug 7, 2022
4b2f038
Add bootstrapping diagram
camelid Aug 9, 2022
c1c84d6
Add colors to diagram
camelid Aug 9, 2022
81a4d04
Add color for downloaded nodes
camelid Aug 9, 2022
df17432
Fix legend colors in dark mode
camelid Aug 9, 2022
1dee5f8
update date-check format on github issue (#1416)
tshepang Aug 9, 2022
f979af6
move references down to avoid clutter (#1420)
tshepang Aug 9, 2022
af80d31
add gdb tips for symbol-mangling-version
chenyukang Aug 10, 2022
4c39d33
Update src/compiler-debugging.md
jyn514 Aug 10, 2022
24de0fa
fix/improve compiler-debugging
tshepang Aug 10, 2022
452b5ab
date-check: crates-io
tshepang Aug 11, 2022
d3daa1f
Improve the "Diagnostic items" chapter (#1427)
tshepang Aug 13, 2022
04e1702
Update the date reference around Git submodule bug (#1430)
tshepang Aug 17, 2022
8ee1ff5
fix lifetime name (#1431)
tshepang Aug 17, 2022
47c8189
remove incorrect info (#1435)
tshepang Aug 17, 2022
2512667
Update slug style to use _ instead of - (#1426)
est31 Aug 17, 2022
9334d59
fix incorrect #[note] syntax
CleanCut Aug 18, 2022
0a80e53
more syntax fixes
CleanCut Aug 18, 2022
f3fe248
Add missing lifetime (#1439)
CleanCut Aug 19, 2022
0a61352
diagnostics: fix outdated use of string slugs (#1436)
davidtwco Aug 19, 2022
c2371da
Document changes introduced by kind-less SessionDiagnostics
Xiretza Aug 19, 2022
e81b583
fix quick-edit link (#1441)
tshepang Aug 22, 2022
18fc34b
do not offer option to run code (#1442)
tshepang Aug 22, 2022
1e7fe14
update thir output (#1445)
tshepang Aug 24, 2022
bedc610
make date-check more easy to use
tshepang Aug 14, 2022
b0a0a4f
address review comment
tshepang Aug 19, 2022
9c9882c
update parallel-rustc.md
SparrowLii Aug 15, 2022
a240e52
Correct some statements in parallel-rustc.md
SparrowLii Aug 16, 2022
1be023c
correct typo in parallel-rustc.md
SparrowLii Aug 16, 2022
d7832db
Update some statements
SparrowLii Aug 25, 2022
8ba0403
A few corrections
SparrowLii Aug 26, 2022
94a29d4
we got 3 (#1447)
tshepang Aug 26, 2022
20e571f
Updates LLVM prereqs since upgrade to C++17.
red1bluelost Aug 27, 2022
2bf1b9a
Updates text to refer to LLVM documentation.
red1bluelost Aug 27, 2022
daca468
typo
tshepang Aug 27, 2022
b5a632f
Refine the lintstore section (#1429)
tshepang Aug 27, 2022
2a9f8fb
Update the stabilization guide to refer to the new placeholder system
est31 Aug 23, 2022
c0c957c
Remove a dangling link on "The `#[test]` attribute"
JohnTitor Aug 29, 2022
04892c1
Fix the link to `Parser` struct
JohnTitor Aug 29, 2022
6b0a155
Update for removal of RLS (#1450)
ehuss Sep 2, 2022
8593238
Add reference for updating Windows PATH and fix typo
Samyak2 Aug 30, 2022
5be5475
Document multipart_suggestion derive on SessionSubdiagnostic
Xiretza Aug 24, 2022
a5363fb
Fix typo (#1459)
eholk Sep 9, 2022
5d8825e
Add symbol-addition to the how-to for new features (#1457)
ssbr Sep 11, 2022
f29e38c
"symbol names" => ABI
jyn514 Sep 10, 2022
c3232c4
Remove the diagram of all outputs generated by x.py
jyn514 Sep 10, 2022
6b3a5fb
Rewrite the section on passing flags to subcommands
jyn514 Sep 10, 2022
a605591
Say "bootstrap" instead of "rustbuild"; the latter is not explained a…
jyn514 Sep 10, 2022
290ecb9
fix typos and formatting
jyn514 Sep 12, 2022
f1609a3
Explain the new valtree system for type level constants. (#1097)
oli-obk Sep 13, 2022
b21b0bb
remove stray **
tshepang Sep 14, 2022
39612f9
Link from "implementing to new features" to mcp.md (#1465)
pnkfelix Sep 15, 2022
1f8cda6
Add a note about building `rust-analyzer-proc-macro-srv` (#1467)
WaffleLapkin Sep 19, 2022
f587d6e
Update stability guide to use CURRENT_RUSTC_VERSION (#1468)
SUPERCILEX Sep 19, 2022
f349ee1
Fix some typos
JohnTitor Sep 19, 2022
b8b984f
Update some actions versions
JohnTitor Sep 19, 2022
03752ab
Remove unmaintained action
JohnTitor Sep 19, 2022
27c2aa6
Update mdbook and its extensions versions
JohnTitor Sep 20, 2022
1c79085
UPDATE - Diagnostic docs to reflect renamed traits and macros in rust…
JhonnyBillM Sep 9, 2022
7743f0f
don't refer to the compile-time interpreter as "Miri" (#1471)
RalfJung Sep 26, 2022
ed11720
Update r-a config suggestions
Veykril Oct 1, 2022
1370793
Link to the correct page in "about this guide"
jyn514 Sep 3, 2022
de71812
Update about-this-guide.md
jyn514 Oct 2, 2022
882921a
fix typo and make paragraph consistent (#1474)
Joshument Oct 3, 2022
b8228e9
Rename typeck to hir_analysis (#1475)
mejrs Oct 4, 2022
d3ce60f
Update running tests with the new flags (#1476)
pietroalbini Oct 5, 2022
57a38ad
diagnostic structs: derive on enum (#1477)
davidtwco Oct 5, 2022
0932ad6
fix very minor punctuation typo
Joshument Oct 5, 2022
9a86c04
.gitattributes: Mark minified javascript as binary to filter greps
joshtriplett Oct 7, 2022
509ee50
Use llvm subdomain for compiler-explorer link
dkm Oct 8, 2022
7518c34
Update debugging.md
dkm Oct 8, 2022
e68dfb8
Add missing prerequisite for some Linux distros (#1481)
scarvalhojr Oct 11, 2022
a8ccc26
typo and grammar (#1484)
tshepang Oct 18, 2022
736fcb9
fix some links (#1490)
lcnr Oct 22, 2022
0a2f713
miri is no longer a submodule but a subtree. (#1488)
luqmana Oct 22, 2022
a262476
Update rust-analyzer suggestions (#1487)
Veykril Oct 24, 2022
6686b1e
Update diagnostics to flat fluent message paths
Noratrieb Oct 21, 2022
51a37ad
Update `traits/resolution.md` (#1494)
compiler-errors Oct 25, 2022
7f426da
Update for highfive transition.
ehuss Oct 26, 2022
bd8eeff
Remove `--bless` from pre-push hook suggestion
ChrisDenton Oct 27, 2022
88bd6ca
add note for err annotation formatting
Rageking8 Oct 27, 2022
94ecbac
trans -> codegen (#1500)
spastorino Oct 31, 2022
03fe2d4
UPDATE - mention of Diagnostic derive on enums
JhonnyBillM Oct 31, 2022
a6c35fc
Fixes some typos (#1502)
jonathanCogan Nov 2, 2022
43e4117
align code blocks with their paragraphs
tshepang Nov 4, 2022
2bdb02c
replace tabs with spaces (#1504)
tshepang Nov 5, 2022
0872241
Update query.md
Noratrieb Oct 14, 2022
090bd54
Update some more things and improve wording
Noratrieb Nov 5, 2022
63b45c3
Remove implementation details
Noratrieb Nov 5, 2022
d0dc6c9
trans -> codegen
lcnr Nov 7, 2022
01a51b2
Document multiple alternative suggestions on diagnostic structs (#1486)
Xiretza Nov 8, 2022
7354b42
Consistent ordered list indexing
RCoder01 Nov 8, 2022
39c10de
extract regions
lcnr Nov 7, 2022
36e15ae
Update src/type-inference.md
lcnr Nov 9, 2022
6f3d5e4
date-check: updating-llvm (#1424)
tshepang Nov 20, 2022
f98f1e5
updating-llvm: keep a calm tone (#1449)
tshepang Nov 20, 2022
32bc13e
Fix a broken design docs link about unused substs bug
JohnTitor Nov 20, 2022
0bd5bd1
Update path for `try_mark_green` implementation
ghassanachi Nov 22, 2022
2889c29
Triage some date-check items (#1513)
camelid Nov 26, 2022
e85c4c4
do an actual link to detect if it breaks in future (#1517)
tshepang Nov 27, 2022
af134d2
Link directly to the section on `--keep-stage`
jyn514 Nov 25, 2022
fa3ffbf
Don't use "incremental" to refer to `--keep-stage`
jyn514 Nov 26, 2022
96462f2
Fix broken link
jyn514 Nov 27, 2022
c4e632e
Typo (#1520)
smoelius Dec 3, 2022
a7cd864
clarify subtree tool policy (#1518)
RalfJung Dec 3, 2022
e269950
Remove duplicate paragraph (#1523)
anirudh24seven Dec 3, 2022
d3564ba
Fix small inaccuracy in monomorph page
nameEqualsJared Dec 5, 2022
d147c52
Remove TyS
oli-obk Dec 6, 2022
b145e1e
fix: Fix broken links
JohnTitor Dec 3, 2022
3b98da0
chore: Update `actions/github-script` to v6
JohnTitor Dec 3, 2022
9f3efe6
share same link
tshepang Dec 9, 2022
1211eeb
Replace NoLandingPad with another alive MIR pass
momvart Dec 13, 2022
1cf62dd
Remove todo note
momvart Dec 13, 2022
4c516b0
Replace NoLandingPad with another alive Visitor
momvart Dec 13, 2022
55c2c09
typo
tshepang Dec 14, 2022
58077bf
Add documentation for LLVM KCFI support (#1529)
rcvalle Dec 14, 2022
a213de4
Add -Ztrack-diagnostics information
Nov 5, 2022
8b42eb5
Apply feedback
Dec 17, 2022
54e6f5b
Fix rustc_borrowck crate name typo (#1535)
dmezh Dec 25, 2022
ba1db24
Add more rebasing help
jyn514 Dec 29, 2022
586474f
Use `origin` consistently and add an example of rebasing over the wro…
jyn514 Dec 29, 2022
e6fd600
Replace `$TARGET` with `host`
jyn514 Nov 25, 2022
8fa9ede
Remove initial section on submodules
jyn514 Dec 8, 2022
fd9a461
Remove unnecessary detail in building chapter
jyn514 Dec 8, 2022
f111b88
Move "create a config.toml" after the section explaning x.py
jyn514 Dec 8, 2022
51fc2ec
Move information about dependencies to the rust-lang/rust readme
jyn514 Dec 8, 2022
ef12db3
Update sentence about LLVM to match the new defaults
jyn514 Dec 8, 2022
664346d
Give help for when you update a submodule by accident
jyn514 Dec 31, 2022
b3e2a6e
fix typo
jyn514 Dec 31, 2022
da0a4a0
Add a section for how to review code more easily (#1538)
jyn514 Jan 2, 2023
d89d417
fix rebase link
oskgo Jan 9, 2023
e67f3b8
Fix incorrect links (#1549)
mu001999 Jan 10, 2023
e799c10
add full name for ICE (#1552)
gftea Jan 11, 2023
ec0d134
Change `src/test` to `tests` (#1547)
albertlarsan68 Jan 12, 2023
0dc2b03
Link to the youtube recording of my talk, not the summary (#1554)
jyn514 Jan 12, 2023
de053e2
Update incremental-compilation-in-detail.md (#1553)
gftea Jan 14, 2023
7352353
fix examples for rustc 1.68.0-nightly (935dc0721 2022-12-19) (#1556) …
gftea Jan 14, 2023
ea33f70
Update asm.md (#1560)
gftea Jan 17, 2023
7313897
Update resolution.md (#1561)
gftea Jan 17, 2023
7d3c1c8
Correct tests misplacement (#1564)
albertlarsan68 Jan 20, 2023
042c49c
rustc_typeck exists no more
tshepang Jan 15, 2023
757ad6d
accept review suggestion
tshepang Jan 17, 2023
5ecd75a
fix review suggestion
tshepang Jan 17, 2023
b6cc460
Update hir.md
pourplusquoi Jan 25, 2023
0e18184
bumpt date-check examples to current month (#1566)
tshepang Jan 26, 2023
21c77d7
there are still no locale bundles (#1567)
tshepang Jan 26, 2023
f4f78f7
version 5 is now not supported (#1568)
tshepang Jan 27, 2023
0bcdb56
add section for the new trait solver
lcnr Jan 10, 2023
61771df
fix line lengths
lcnr Jan 10, 2023
15bd9e4
Update src/solve/canonicalization.md
lcnr Jan 12, 2023
9656b8c
review
lcnr Jan 12, 2023
7eaff60
Update src/solve/canonicalization.md
lcnr Jan 13, 2023
167d22c
line length
lcnr Jan 13, 2023
71766d9
review
lcnr Jan 27, 2023
c166632
update datecheck
lcnr Jan 27, 2023
566124f
Use ephemeral PAT for linkcheck
JohnTitor Jan 27, 2023
54cfdd7
Update ast-validation.md
dbelik Dec 4, 2022
4a1d549
Apply suggestions from code review
dbelik Dec 10, 2022
e359ee2
New infcx usage (#1571)
Noratrieb Jan 30, 2023
472188e
extend bootstrap related documentations
onur-ozkan Jan 20, 2023
ba809ff
fix incorrect position of topic
onur-ozkan Jan 31, 2023
c42c13e
fix wrong heading level (#1573)
tshepang Jan 31, 2023
c97f571
Update rustfmt path
zephaniahong Feb 1, 2023
98cc718
Add section on comparing types
Noratrieb Jan 28, 2023
5db974f
Expand section basedd on review comments
Noratrieb Jan 30, 2023
49c93f6
Add param_env and wording
Noratrieb Feb 2, 2023
d8c298d
Update explnation about benchmarks
JohnTitor Feb 2, 2023
d30be86
Address the change in https://github.com/rust-lang/rust/pull/107256
JohnTitor Feb 2, 2023
e0074c1
Address the change in https://github.com/rust-lang/rust/pull/97287
JohnTitor Feb 2, 2023
860162a
Address the change in https://github.com/rust-lang/rust/pull/106718
JohnTitor Feb 2, 2023
bf4cdde
Address the change in https://github.com/rust-lang/rust/pull/99715
JohnTitor Feb 2, 2023
d579acb
Fix broken relative links
JohnTitor Feb 2, 2023
5c65222
Use host symlink for custom rustup toolchain
aDotInTheVoid Feb 3, 2023
2d1e71a
update bootstrap guide (#1583)
onur-ozkan Feb 4, 2023
0591410
Fixed small grammar mistake in monomorph.md (#1585)
Ciel-MC Feb 5, 2023
7e9449a
Do not add accept header on linkcheck
JohnTitor Feb 5, 2023
ed5b175
Replace settings.json with x.py setup note (#1588)
clubby789 Feb 8, 2023
33ea559
update examples for rustc 1.69.0-nightly (e1eaa2d5d 2023-02-06) (#1590)
Hiroki6 Feb 9, 2023
df5aee0
Improve git submodule help (#1587)
jyn514 Feb 9, 2023
41a96ab
Add a citation file
JohnTitor Jan 10, 2023
2ab6fbc
Add Neovim configuration information (#1545)
RossSmyth Feb 14, 2023
5eb8171
Fix a typo (#1597)
tshepang Feb 14, 2023
82257c2
use actual names (#1594)
tshepang Feb 14, 2023
c9e4cb7
typo (#1600)
tshepang Feb 15, 2023
77aaf99
Add sample CodeLLDB launch.json (#1482)
AE1020 Feb 15, 2023
fb4cc6f
howto run the examples (#1593)
tshepang Feb 15, 2023
d0ee17f
avoid code duplication by including files in docs (#1598)
tshepang Feb 15, 2023
74afdfc
Add link to vscode settings in Rust repo (#1591)
clubby789 Feb 15, 2023
4a86a8d
Typo
mikysett Feb 15, 2023
df7970b
Typo
mikysett Feb 15, 2023
fdacc77
remove stray text (#1604)
tshepang Feb 17, 2023
2c113b3
have checkboxes only point to date-check lines in files (#1603)
tshepang Feb 17, 2023
c80a26f
make use of the symlink, to ease things (#1608)
tshepang Feb 17, 2023
ed87804
rustc_codegen_ssa feels permanent enough not to need date-check
tshepang Feb 17, 2023
4e8110c
address review comment
tshepang Feb 17, 2023
1f4d6ac
accept review suggestion
tshepang Feb 17, 2023
91d8bbe
Bump dependencies to fix CI (#1610)
camelid Feb 18, 2023
1a72161
Explain what the rest of the backend agnostic page is about
camelid Feb 17, 2023
64f1af1
lower-case "Compiler" in headings, for consistency (and looks)
tshepang Feb 17, 2023
6f536e4
impl review suggestion
tshepang Feb 18, 2023
8715e8f
fix and clarify llvm bugfix policy (#1611)
tshepang Feb 18, 2023
b328f82
add Dev Desktops note
tshepang Feb 18, 2023
727941f
fmt
tshepang Feb 18, 2023
5173d1f
accept review suggestion
tshepang Feb 18, 2023
84b9f4d
Vetting deps datecheck (#1614)
tshepang Feb 18, 2023
51dca6a
enable AND search (#1607)
tshepang Feb 18, 2023
99b6b92
llvm 13 is now not supported (#1612)
tshepang Feb 18, 2023
1efd0ad
bootstrap now creates a usable toolchain when building stage0 std
the8472 Feb 18, 2023
095f27d
new solver: write canonicalization chapter (#1595)
lcnr Feb 20, 2023
110275f
keep "grey area" lint summary green (#1619)
tshepang Feb 21, 2023
ea01bf5
typo (#1617)
tshepang Feb 21, 2023
d01441d
typo (#1616)
tshepang Feb 21, 2023
a7d9603
diagnostics: small fixes/improvements (#1618)
tshepang Feb 21, 2023
9d76913
this remains true (#1620)
tshepang Feb 21, 2023
b06dab8
Fixed typing errors (#1622)
MikaT-code Feb 26, 2023
2d0681e
update error code docs to reflect recent changes (#1625)
Ezrashaw Mar 3, 2023
b684e35
Fixed typing error (#1623)
MikaT-code Mar 3, 2023
62f03c2
Making the sentence more clear (#1624)
MikaT-code Mar 3, 2023
82e50a6
Add detail to contributing guide (#1628)
apiraino Mar 3, 2023
4597bb4
Update explnation about `Body.basic_blocks`
JohnTitor Mar 3, 2023
d1d6ce8
Update date reference about infer context variables
JohnTitor Mar 3, 2023
7e50a6a
Remove mention to lexer/parser refactoring
JohnTitor Mar 3, 2023
78c3edc
new chapter with examples of diagnostic translation PRs
tshepang Mar 6, 2023
0650847
accept review suggestions
tshepang Mar 7, 2023
425b628
address review comment
tshepang Mar 8, 2023
d95acf2
improve
tshepang Mar 12, 2023
ca3e018
update location of .ftl files
tshepang Apr 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add section for the new trait solver
  • Loading branch information
lcnr authored and compiler-errors committed Jan 27, 2023
commit 0bcdb56e3a5f7f2f105cf7600cbac0617c2910c4
4 changes: 4 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@
- [Lowering to logic](./traits/lowering-to-logic.md)
- [Goals and clauses](./traits/goals-and-clauses.md)
- [Canonical queries](./traits/canonical-queries.md)
- [Next-gen trait solving](./solve/trait-solving.md)
- [The solver](./solve/the-solver.md)
- [Canonicalization](./solve/canonicalization.md)
- [Coinduction](./solve/coinduction.md)
- [Type checking](./type-checking.md)
- [Method Lookup](./method-lookup.md)
- [Variance](./variance.md)
Expand Down
8 changes: 8 additions & 0 deletions src/solve/canonicalization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Canonicalization

While the exact approach to canonicalization for this solver will differ slightly
wrt to lifetimes, please visit [the relevant chalk chapter][chalk] for now.

As of the 10th January canonicalization is not yet fully implemented for the solver.

[chalk]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalization
201 changes: 201 additions & 0 deletions src/solve/coinduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Coinduction

The trait solver may use coinduction when proving goals. Coinduction is fairly subtle so we're giving it its own chapter.

## Coinduction and induction

With induction, we recursively apply proofs until we end up with a finite proof tree. Consider the example of `Vec<Vec<Vec<u32>>>: Debug` which results in the following tree.

- `Vec<Vec<Vec<u32>>>: Debug`
- `Vec<Vec<u32>>: Debug`
- `Vec<u32>: Debug`
- `u32: Debug`

This tree is finite. But not all goals we would want to hold have finite proof trees, consider the following example:

```rust
struct List<T> {
value: T,
next: Option<Box<List<T>>>,
}
```

For `List<T>: Send` to hold all its fields have to recursively implement `Send` as well. This would result in the following proof tree:

- `List<T>: Send`
- `T: Send`
- `Option<Box<List<T>>>: Send`
- `Box<List<T>>: Send`
- `List<T>: Send`
- `T: Send`
- `Option<Box<List<T>>>: Send`
- `Box<List<T>>: Send`
- ...

This tree would be infinitely large which is exactly what coinduction is about.

> To **inductively** prove a goal you need to provide a finite proof tree for it.
> To **coinductively** prove a goal the provided proof tree may be infinite.

## Why is coinduction correct

When checking whether some trait goals holds, we're asking "does there exist an `impl`
which satisfies this bound". Even if are infinite chains of nested goals, we still have a
unique `impl` which should be used.

## How to implement coinduction

While our implementation can not check for coninduction by trying to construct an infinite
tree as that would take infinite ressources, it still makes sense to think of coinduction
from this perspective.

As we cannot check for infinite trees, we instead search for patterns for which we know that
they would result in an infinite proof tree. The currently pattern we detect are (canonical)
cycles. If `T: Send` relies on `T: Send` then it's pretty clear that this will just go on forever.

With cycles we have to be careful with caching. Due to canonicalization of regions and inference
variables we also have to rerun queries until the provisional result returned when hitting the cycle
is equal to the final result.

TODO: elaborate here. We use the same approach as chalk for coinductive cycles. Note that the treatment
for inductive cycles currently differs by simply returning `Overflow`. See [the relevant chapters][chalk]
in the chalk book.

[chalk]: https://rust-lang.github.io/chalk/book/recursive/inductive_cycles.html


## Future work

We currently only consider auto-traits, `Sized`, and `WF`-goals to be coinductive.
In the future we pretty much intend for all goals to be coinductive.
Lets first elaborate on why allowing more coinductive proofs is even desirable.

### Recursive data types already rely on coinduction...

...they just tend to avoid them in the trait solver.

```rust
enum List<T> {
Nil,
Succ(T, Box<List<T>>),
}

impl<T: Clone> Clone for List<T> {
fn clone(&self) -> Self {
match self {
List::Nil => List::Nil,
List::Succ(head, tail) => List::Succ(head.clone(), tail.clone()),
}
}
}
```

We are using `tail.clone()` in this impl. For this we have to prove `Box<List<T>>: Clone` which requires `List<T>: Clone` but that relies on the currently impl which we are currently checking. By adding that requirement to the `where`-clauses of the impl, which is what we would do with [perfect derive], we move that cycle into the trait solver and [get an error][ex1].

### Recursive data types

We also need coinduction to reason about recursive types containing projections, e.g. the following currently fails to compile even though it should be valid.
```rust
use std::borrow::Cow;
pub struct Foo<'a>(Cow<'a, [Foo<'a>]>);
```
This issue has been known since at least 2015, see [#23714](https://github.com/rust-lang/rust/issues/23714) if you want to know more.

### Explicitly checked implied bounds

When checking an impl, we assume that the types in the impl headers are well-formed. This means that when using instantiating the impl we have to prove that's actually the case. [#100051](https://github.com/rust-lang/rust/issues/100051) shows that this is not the case. To fix this, we have to add `WF` predicates for the types in impl headers. Without coinduction for all traits, this even breaks `core`.

```rust
trait FromResidual<R> {}
trait Try: FromResidual<<Self as Try>::Residual> {
type Residual;
}

struct Ready<T>(T);
impl<T> Try for Ready<T> {
type Residual = Ready<()>;
}
impl<T> FromResidual<<Ready<T> as Try>::Residual> for Ready<T> {}
```

When checking that the impl of `FromResidual` is well formed we get the following cycle:

The impl is well formed if `<Ready<T> as Try>::Residual` and `Ready<T>` are well formed.
- `wf(<Ready<T> as Try>::Residual)` requires
- `Ready<T>: Try`, which requires because of the super trait
- `Ready<T>: FromResidual<Ready<T> as Try>::Residual>`, which has an impl which requires **because of implied bounds**
- `wf(<Ready<T> as Try>::Residual)` :tada: **cycle**

### Issues when extending coinduction to more goals

There are some additional issues to keep in mind when extending coinduction.
The issues here are not relevant for the current solver.

#### Implied super trait bounds

Our trait system currectly treats super traits, e.g. `trait Trait: SuperTrait`, by 1) requiring that `SuperTrait` has to hold for all types which implement `Trait`, and 2) assuming `SuperTrait` holds if `Trait` holds.

Relying on 2) while proving 1) is unsound. This can only be observed in case of coinductive cycles. Without a cycles, whenever we rely on 2) we must have also proven 1) without relying on 2) for the used impl of `Trait`.

```rust
trait Trait: SuperTrait {}

impl<T: Trait> Trait for T {}

// Keeping the current setup for coinduction
// would allow this compile. Uff :<
fn sup<T: SuperTrait>() {}
fn requires_trait<T: Trait>() { sup::<T>() }
fn generic<T>() { requires_trait::<T>() }
```
This is not really fundamental to coinduction but rather an existing property which is made unsound because of it.

##### Possible solutions

The easiest way to solve this would be to completely remove 2) and always elaborate
`T: Trait` to `T: Trait` and `T: SuperTrait` outside of the trait solver.
This would allow us to also remove 1), but as we still have to prove ordinary `where`-bounds on traits,
that's just additional work.

While one could imagine ways to disable cyclic uses of 2) when checking 1), at least the ideas of myself - @lcnr -
are all far to complex to be reasonable.

#### `normalizes_to` goals and progress

A `normalizes_to` goal represents the requirement that `<T as Trait>::Assoc` normalizes to some `U`. This is achieved by defacto first normalizing `<T as Trait>::Assoc` and then equating the resulting type with `U`. It should be a mapping as each projection should normalize to exactly one type. By simply allowing infinite proof trees, we would get the following behavior:

```rust
trait Trait {
type Assoc;
}

impl Trait for () {
type Assoc = <() as Trait>::Assoc;
}
```

If we now compute `normalizes_to(<() as Trait>::Assoc, Vec<u32>)`, we would resolve the impl and get the associated type `<() as Trait>::Assoc`. We then equate that with the expected type, causing us to check `normalizes_to(<() as Trait>::Assoc, Vec<u32>)` again. This just goes on forever, resulting in an infinite proof tree.

This means that `<() as Trait>::Assoc` would be equal to any other type which is unsound.

##### How to solve this

**WARNING: THIS IS SUBTLE AND MIGHT BE WRONG**

Unlike trait goals, `normalizes_to` has to be *productive*[^1]. A `normalizes_to` goal is productive once the projection normalizes to a rigid type constructor, so `<() as Trait>::Assoc` normalizing to `Vec<<() as Trait>::Assoc>` would be productive.

A `normalizes_to` goal has two kinds of nested goals. Nested requirements needed to actually normalize the projection, and the equality between the normalized projection and the expected type. Only the equality has to be productive. A branch in the proof tree is productive if it is either finite, or contains at least one `normalizes_to` where the alias is resolved to a rigid type constructor.

Alternatively, we could simply always treat the equate branch of `normalizes_to` as inductive. Any cycles should result in infinite types, which aren't supported anyways and would only result in overflow when deeply normalizing for codegen.

experimentation and examples: https://hackmd.io/-8p0AHnzSq2VAE6HE_wX-w?view

Another attempt at a summary.
- in projection eq, we must make progress with constraining the rhs
- a cycle is only ok if while equating we have a rigid ty on the lhs after norm at least once
- cycles outside of the recursive `eq` call of `normalizes_to` are always fine

[^1]: related: https://coq.inria.fr/refman/language/core/coinductive.html#top-level-definitions-of-corecursive-functions

[perfect derive]: https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive
[ex1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0a9c3830b93a2380e6978d6328df8f72
16 changes: 16 additions & 0 deletions src/solve/the-solver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# The solver

Also consider reading the documentation for [the recursive solver in chalk][chalk]
as it is very similar to this implementation and also talks about limitations of this
approach.

[chalk]: https://rust-lang.github.io/chalk/book/recursive.html

The basic structure of the solver is a pure function
`fn evaluate_goal(goal: Goal<'tcx>) -> Response`.
While the actual solver is not fully pure to deal with overflow and cycles, we are
going to defer that for now.

To deal with inference variables and to improve caching, we use [canonicalization](/canonicalization.html).

TODO: write the remaining code for this as well.
99 changes: 99 additions & 0 deletions src/solve/trait-solving.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Trait solving (new)

This chapter describes how trait solving works with the new WIP solver located in
[`rustc_trait_selection/solve`][solve]. Feel free to also look at the docs for
[the current solver](../traits/resolution.hmtl) and [the chalk solver](./chalk.html)
can be found separately.

## Core concepts

The goal of the trait system is to check whether a given trait bound is satisfied.
Most notably when typechecking the body of - potentially generic - functions.
For example:

```rust
fn uses_vec_clone<T: Clone>(x: Vec<T>) -> (Vec<T>, Vec<T>) {
(x.clone(), x)
}
```
Here the call to `x.clone()` requires us to prove that `Vec<T>` implements `Clone` given
the assumption that `T: Clone` is true. We can assume `T: Clone` as that will be proven by
callers of this function.

The concept of "prove the `Vec<T>: Clone` with the assumption `T: Clone`" is called a [`Goal`].
Both `Vec<T>: Clone` and `T: Clone` are represented using [`Predicate`]. There are other
predicates, most notably equality bounds on associated items: `<Vec<T> as IntoIterator>::Item == T`.
See the `PredicateKind` enum for an exhaustive list. A `Goal` is represented as the `predicate` we
have to prove and the `param_env` in which this predicate has to hold.

We prove goals by checking whether each possible [`Candidate`] applies for the given goal by
recursively proving its nested goals. For a list of possible candidates with examples, look at
[`CandidateSource`]. The most important candidates are `Impl` candidates, i.e. trait implementations
written by the user, and `ParamEnv` candidates, i.e. assumptions in our current environment.

Looking at the above example, to prove `Vec<T>: Clone` we first use `impl<T: Clone> Clone for Vec<T>`.
To use this impl we have to prove the nested goal that `T: Clone` holds. This can use the
assumption `T: Clone` from the `ParamEnv` which does not have any nested goals.
Therefore `Vec<T>: Clone` holds.

The trait solver can either return success, ambiguity or an error as a [`CanonicalResponse`].
For success and ambiguity it also returns constraints inference and region constraints.

## Requirements

Before we dive into the new solver lets first take the time to go through all of our requirements
on the trait system. We can then use these to guide our design later on.

TODO: elaborate on these rules and get more precise about their meaning.
Also add issues where each of these rules have been broken in the past
(or still are).

### 1. The trait solver has to be *sound*

This means that we must never return *success* for goals for which no `impl` exists. That would
simply be unsound by assuming a trait is implemented even though it is not.

### 2. If type checker solves generic goal concrete instantiations of that goal have the same result

Pretty much: If we successfully typecheck a generic function concrete instantiations of that function
should also typeck. We should not get errors post-monomorphization. We can however get overflow.

### 3. Trait goals in empty environments are proven by a unique impl.

If a trait goal holds with an empty environment, there is a unique `impl`,
either user-defined or builtin, which is used to prove that goal.

This is necessary for codegen to select a unique method.
An exception here are *marker traits* which are allowed to overlap.

### 4. Normalization in empty environments results in a unique type

Normalization for alias types/consts has a unique result. Otherwise we can easily implement
transmute in safe code.

### 5. During coherence trait solving has to be complete

During coherence we never return *error* for goals which can be proven. This allows overlapping
impls which would break rule 3.

### 6. Trait solving must be (free) lifetime agnostic

Trait solving during codegen should have the same result as during typeck. As we erase
all free regions during codegen we must not rely on them during typeck. A noteworthy example
is special behavior for `'static`.

### 7. Removing ambiguity makes strictly more things compile

We *should* not rely on ambiguity for things to compile. Not doing that will cause future improvements to be breaking changes.

### 8. semantic equality implies structural equality

Two types being equal in the type system must mean that they have the same `TypeId`.


[solve]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/index.html
[`Goal`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/struct.Goal.html
[`Predicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Predicate.html
[`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/assembly/struct.Candidate.html
[`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/trait_goals/enum.CandidateSource.html
[`CanonicalResponse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/type.CanonicalResponse.html