@@ -82,8 +82,9 @@ An API may define a contract that goes beyond the type checking enforced by the
82
82
compiler. For example, slices support an indexing operation, with the contract
83
83
that the supplied index must be in bounds.
84
84
85
- Contracts can be complex. For example, the ` RefCell ` type requires that
86
- ` borrow_mut ` not be called until all existing borrows have been relinquished.
85
+ Contracts can be complex and involve more than a single function invocation. For
86
+ example, the ` RefCell ` type requires that ` borrow_mut ` not be called until all
87
+ existing borrows have been relinquished.
87
88
88
89
### For contract violations, fail the task.
89
90
@@ -114,13 +115,22 @@ contracts. However, here are some rough guidelines:
114
115
patterns where the client does not want to check inputs before hand, but would
115
116
rather attempt the operation and then find out whether the inputs were invalid.
116
117
118
+ * When a contract violation is the * only* kind of error a function may encounter
119
+ -- i.e., there are no obstructions to its success other than "bad" inputs --
120
+ using ` Result ` or ` Option ` instead is especially warranted. Clients can then use
121
+ ` unwrap ` to assert that they have passed valid input, or re-use the error
122
+ checking done by the API for their own purposes.
123
+
117
124
* When in doubt, use loose contracts and instead return a ` Result ` or ` Option ` .
118
125
119
126
## Obstructions
120
127
121
128
An operation is * obstructed* if it cannot be completed for some reason, even
122
- though the operation's contract has been satisfied. Obstructed operations must
123
- still leave the relevant data structures in a coherent state.
129
+ though the operation's contract has been satisfied. Obstructed operations may
130
+ have (documented!) side effects -- they are not required to roll back after
131
+ encountering an obstruction. However, they should leave the data structures in
132
+ a "coherent" state (satisfying their invariants, continuing to guarantee safety,
133
+ etc.).
124
134
125
135
Obstructions may involve external conditions (e.g., I/O), or they may involve
126
136
aspects of the input that are not covered by the contract.
@@ -138,7 +148,8 @@ obstructions in a fine-grained way.
138
148
If there are multiple ways an operation might be obstructed, or there is useful
139
149
information about the obstruction (such as where in the input a parse error
140
150
occurred), prefer to use ` Result ` . For operations with a single obvious
141
- obstruction (like popping from an empty stack), use ` Option ` .
151
+ obstruction that can provide no additional information (e.g. popping from an
152
+ empty stack), use ` Option ` .
142
153
143
154
(Currently, ` Option ` does not interact well with other error-handling
144
155
infrastructure like ` try! ` , but this will likely be improved in the future.)
@@ -156,7 +167,7 @@ intended as assertions. If there is no other way to check in advance for the
156
167
validity of invoking an operation ` foo ` , however, the API may provide a
157
168
` foo_catch ` variant that returns a ` Result ` .
158
169
159
- The main examples in ` libstd ` providing both variants are:
170
+ The main examples in ` libstd ` that * currently * provide both variants are:
160
171
161
172
* Channels, which are the primary point of failure propagation between tasks. As
162
173
such, calling ` recv() ` is an _ assertion_ that the other end of the channel is
@@ -177,6 +188,8 @@ The main examples in `libstd` providing both variants are:
177
188
> Note: the ` try_ ` prefix would be replaced by a ` _catch ` catch if this RFC is
178
189
> accepted.
179
190
191
+ (Note: it is unclear whether these APIs will continue to provide both variants.)
192
+
180
193
# Drawbacks
181
194
182
195
The main drawbacks of this proposal are:
@@ -203,3 +216,20 @@ As was
203
216
however, mixing what might be seen as contract violations with obstructions can
204
217
make it much more difficult to write obstruction-robust code; see the linked
205
218
comment for more detail.
219
+
220
+ ## Naming
221
+
222
+ There are numerous possible suffixes for a ` Result ` -producing variant:
223
+
224
+ * ` _catch ` , as proposed above. As
225
+ [ @kballard points out] ( https://github.com/rust-lang/rfcs/pull/236#issuecomment-55344336 ) ,
226
+ this name connotes exception handling, which could be considered
227
+ misleading. However, since it effectively prevents further unwinding, catching
228
+ an exception may indeed be the right analogy.
229
+
230
+ * ` _result ` , which is straightforward but not as informative/suggestive as some
231
+ of the other proposed variants.
232
+
233
+ * ` try_ ` prefix. Also connotes exception handling, but has an unfortunately
234
+ overlap with the common use of ` try_ ` for nonblocking variants (which is in
235
+ play for ` recv ` in particular).
0 commit comments