Skip to content

Commit f011446

Browse files
committed
WIP
1 parent ed4c592 commit f011446

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

text/0000-extern-impl.md

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
- Feature Name: (fill me in with a unique ident, `my_awesome_feature`)
2+
- Start Date: (fill me in with today's date, YYYY-MM-DD)
3+
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
This RFC proposes a mechanism to allow `impl`s for a type or trait to be in a
10+
separate crate, while still meeting the soundness guarantees currently enforced
11+
by the orphan rule.
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
In order to guarantee coherence, Rust currently imposes the fairly strict orphan
17+
rule. That is:
18+
- only a crate defining a type can have inherent implementations for that type,
19+
or for any traits, and
20+
- only a crate defining a trait can implement that trait for any type
21+
22+
In other words, a crate is not allowed to have "third-party implementations" -
23+
it's not allowed to add new inherent implementations to a type, nor is it
24+
allowed to implement a foreign trait for a foreign type.
25+
26+
This raises a number of problems, but this RFC's principle concern is that of
27+
build performance and dependency graph scaling.
28+
29+
For example:
30+
31+
- It common for a to only use a crate for its type definitions, but not need any
32+
of it's implementations (for example, when mentioning a type in a function
33+
signature or another type definition). However, with the current orphan rule,
34+
this would require waiting for the full crate to compile, including all of its
35+
dependencies.
36+
- When introducing a new trait, it's useful to provide implementations for other
37+
external types. But this means the trait-definition crate takes on
38+
depdendencies on all those downstream dependencies whether they're needed or not.
39+
40+
~~What this RFC proposes is a mechanism which allows implementations to be
41+
delegated to "trusted" or "friendly" crates (typically defined in the same
42+
package), allowing downstream consumers to take on only the specific
43+
dependencies they need. Furthermore a "witness" mechanism makes sure that the
44+
coherence invariants currently enforced by the orphan rule are maintained.~~
45+
46+
Dependency graph dominator based coherence checking.
47+
48+
Status Quo:
49+
```mermaid
50+
graph LR
51+
MysqlUser --> DBTrait
52+
MongoUser --> DBTrait
53+
DBTrait --> Mysql
54+
DBTrait --> MongoDB
55+
DBTrait --> RocksDB
56+
```
57+
58+
Proposed:
59+
```mermaid
60+
graph LR
61+
MysqlUser --> DBMysql
62+
MongoUser --> DBMongo
63+
DBMysql --> Mysql
64+
DBMysql -->|impl| DBTrait
65+
DBMongo --> MongoDB
66+
DBMongo -->|impl| DBTrait
67+
DBRocks --> RocksDB
68+
DBRocks -->|impl| DBTrait
69+
```
70+
# Guide-level explanation
71+
[guide-level-explanation]: #guide-level-explanation
72+
73+
- defining crate and impl crate
74+
75+
`--extern impl:name=name.rlib`
76+
77+
- impl crate must directly depend on defining crate - re-exports don't count
78+
- defining crate & impl crate are considered the same (eg `pub(crate)` is visible to both)
79+
- impls in defining & impl must be coherent
80+
81+
# Reference-level explanation
82+
[reference-level-explanation]: #reference-level-explanation
83+
84+
- "Local" for coherence checking extended from "definitions in one crate" to "definitions from set of crates"
85+
- set of crates are impls for a definition which are downstream from dominator
86+
87+
Dominating crates:
88+
- crate dominates itself (so must be internally coherent)
89+
- impl crate dominates self and defining crate (so must be coherent)
90+
- least dominator for a set of impl crates must guarantee coherence
91+
92+
Defining crate is its own implementing crates, and must be internally coherent
93+
(ie, status quo)
94+
```mermaid
95+
graph TD
96+
D["`D
97+
also I0`"]
98+
```
99+
100+
Each impl crate dominates its defining crate(s) and must be coherent with them:
101+
```mermaid
102+
graph TD
103+
I1 -->|impl| D
104+
I2 -->|impl| D
105+
In["I..n"] -->|impl| D
106+
```
107+
108+
Least dominator of all impl crates for a given defining crate must check
109+
coherence of impls:
110+
```mermaid
111+
graph TD
112+
D["`D
113+
Defines types/traits`"]
114+
I1 -->|impl| D
115+
I2 -->|impl| D
116+
I3 -->|impl| D
117+
In["`I..n
118+
impls for types/traits in D`"] -->|impl| D
119+
C0 --> I1
120+
C1 --> I2
121+
C2["`C2
122+
must check for I1, I2 coherence`"]
123+
C2 --> C0
124+
C2 --> C1
125+
C3["C3 need not check"]
126+
C3 --> C2
127+
C4["C4 must check I1, I2, I3 coherence"]
128+
C4 --> C2
129+
C4 --> I3
130+
```
131+
132+
## Extra cases
133+
134+
Impl crates depend on each other
135+
```mermaid
136+
graph TD
137+
I1 -->|impl| D
138+
I2 -->|impl| D
139+
I2 --> I1
140+
```
141+
Impl crates use other crates (common)
142+
```mermaid
143+
graph TD
144+
I1 -->|impl| D
145+
I1 --> T
146+
```
147+
Impl crates implement multiple definition crates
148+
```mermaid
149+
graph TD
150+
I1 -->|impl| D0
151+
I1 -->|impl| D1
152+
```
153+
Impl crates define types and have their own impl crates
154+
```mermaid
155+
graph TD
156+
I1 -->|impl| D0
157+
I1 -->|impl| I2
158+
I2 -->|impl| D0
159+
```
160+
161+
162+
This is the technical portion of the RFC. Explain the design in sufficient detail that:
163+
164+
- Its interaction with other features is clear.
165+
- It is reasonably clear how the feature would be implemented.
166+
- Corner cases are dissected by example.
167+
168+
The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.
169+
170+
# Drawbacks
171+
[drawbacks]: #drawbacks
172+
173+
- Complexity
174+
- Ecosystem split
175+
176+
# Rationale and alternatives
177+
[rationale-and-alternatives]: #rationale-and-alternatives
178+
179+
- Features?
180+
- only work for small-scale projects
181+
182+
# Prior art
183+
[prior-art]: #prior-art
184+
185+
Discuss prior art, both the good and the bad, in relation to this proposal.
186+
A few examples of what this can include are:
187+
188+
- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had?
189+
- For community proposals: Is this done by some other community and what were their experiences with it?
190+
- For other teams: What lessons can we learn from what other communities have done here?
191+
- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background.
192+
193+
This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture.
194+
If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages.
195+
196+
Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC.
197+
Please also take into consideration that rust sometimes intentionally diverges from common language features.
198+
199+
# Unresolved questions
200+
[unresolved-questions]: #unresolved-questions
201+
202+
Intended for close coupled crates from same origin, but *could* be used for
203+
generic third-party impls.
204+
205+
Corresponding Cargo part
206+
- Multi-crate packages?
207+
- Namespaces
208+
- Some other abstraction?
209+
210+
# Future possibilities
211+
[future-possibilities]: #future-possibilities
212+
213+
- Transitiive impls
214+
- Total coherence check
215+
- All impl crates are checked against each other for publication, even if not
216+
used together
217+
- Or deliberately allow for conflicting impls in different impl crates, eg
218+
different algorithms for different use-cases for the same thing

0 commit comments

Comments
 (0)