Skip to content

Commit c113a60

Browse files
authored
Merge pull request #2507 from rust-lang/tshepang-misc
some improvements to "Invariants of the type system"
2 parents 6237eaf + 8df6a1d commit c113a60

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

src/doc/rustc-dev-guide/src/solve/invariants.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ FIXME: This file talks about invariants of the type system as a whole, not only
44

55
There are a lot of invariants - things the type system guarantees to be true at all times -
66
which are desirable or expected from other languages and type systems. Unfortunately, quite
7-
a few of them do not hold in Rust right now. This is either a fundamental to its design or
8-
caused by bugs and something that may change in the future.
7+
a few of them do not hold in Rust right now. This is either fundamental to its design or
8+
caused by bugs, and something that may change in the future.
99

10-
It is important to know about the things you can assume while working on - and with - the
10+
It is important to know about the things you can assume while working on, and with, the
1111
type system, so here's an incomplete and unofficial list of invariants of
1212
the core type system:
1313

@@ -29,14 +29,15 @@ If you have a some type and equate it to itself after replacing any regions with
2929
inference variables in both the lhs and rhs, the now potentially structurally different
3030
types should still be equal to each other.
3131

32-
Needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck.
33-
If this invariant is broken MIR typeck ends up failing with an ICE.
32+
This is needed to prevent goals from succeeding in HIR typeck and then failing in MIR borrowck.
33+
If this invariant is broken, MIR typeck ends up failing with an ICE.
3434

3535
### Applying inference results from a goal does not change its result ❌
3636

3737
TODO: this invariant is formulated in a weird way and needs to be elaborated.
3838
Pretty much: I would like this check to only fail if there's a solver bug:
39-
https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407 We should readd this check and see where it breaks :3
39+
<https://github.com/rust-lang/rust/blob/2ffeb4636b4ae376f716dc4378a7efb37632dc2d/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs#L391-L407>.
40+
We should readd this check and see where it breaks :3
4041

4142
If we prove some goal/equate types/whatever, apply the resulting inference constraints,
4243
and then redo the original action, the result should be the same.
@@ -75,8 +76,8 @@ the issue is that the invariant is broken, not that we incorrectly rely on it.
7576

7677
### The type system is complete ❌
7778

78-
The type system is not complete, it often adds unnecessary inference constraints, and errors
79-
even though the goal could hold.
79+
The type system is not complete.
80+
It often adds unnecessary inference constraints, and errors even though the goal could hold.
8081

8182
- method selection
8283
- opaque type inference
@@ -95,20 +96,21 @@ It is interesting that we allow some incompleteness in the trait solver while st
9596
#### Normalization must not change results
9697

9798
This invariant is relied on to allow the normalization of generic aliases. Breaking
98-
it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893)
99+
it can easily result in unsoundness, e.g. [#57893](https://github.com/rust-lang/rust/issues/57893).
99100

100101
#### Goals may still overflow after instantiation
101102

102-
As they start to hit the recursion limit. We also have diverging aliases which are scuffed. It's unclear how these should be handled :3
103+
This happens they start to hit the recursion limit.
104+
We also have diverging aliases which are scuffed.
105+
It's unclear how these should be handled :3
103106

104107
### Trait goals in empty environments are proven by a unique impl ✅
105108

106109
If a trait goal holds with an empty environment, there should be a unique `impl`,
107110
either user-defined or builtin, which is used to prove that goal. This is
108111
necessary to select unique methods and associated items.
109112

110-
We do however break this invariant in few cases, some of which are due to bugs,
111-
some by design:
113+
We do however break this invariant in a few cases, some of which are due to bugs, some by design:
112114
- *marker traits* are allowed to overlap as they do not have associated items
113115
- *specialization* allows specializing impls to overlap with their parent
114116
- the builtin trait object trait implementation can overlap with a user-defined impl:
@@ -117,11 +119,12 @@ some by design:
117119

118120
#### The type system is complete during the implicit negative overlap check in coherence ✅
119121

120-
For more on overlap checking: [coherence]
122+
For more on overlap checking, see [Coherence chapter].
121123

122-
During the implicit negative overlap check in coherence we must never return *error* for
123-
goals which can be proven. This would allow for overlapping impls with potentially different
124-
associated items, breaking a bunch of other invariants.
124+
During the implicit negative overlap check in coherence,
125+
we must never return *error* for goals which can be proven.
126+
This would allow for overlapping impls with potentially different associated items,
127+
breaking a bunch of other invariants.
125128

126129
This invariant is currently broken in many different ways while actually something we rely on.
127130
We have to be careful as it is quite easy to break:
@@ -147,8 +150,8 @@ This currently does not hold with the new solver: [trait-system-refactor-initiat
147150
Ideally we *should* not rely on ambiguity for things to compile.
148151
Not doing that will cause future improvements to be breaking changes.
149152

150-
Due to *incompleteness* this is not the case and improving inference can result in inference
151-
changes, breaking existing projects.
153+
Due to *incompleteness* this is not the case,
154+
and improving inference can result in inference changes, breaking existing projects.
152155

153156
### Semantic equality implies structural equality ✅
154157

@@ -166,4 +169,4 @@ Semantically different `'static` types need different `TypeId`s to avoid transmu
166169
for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`.
167170

168171

169-
[coherence]: ../coherence.md
172+
[coherence chapter]: ../coherence.md

0 commit comments

Comments
 (0)