ControlFlow
tweaks - Add #[must_use]
and methods to convert to Result
#444
Labels
ACP-accepted
API Change Proposal is accepted (seconded with no objections)
api-change-proposal
A proposal to add or alter unstable APIs in the standard libraries
T-libs-api
Proposal
Problem statement
The ControlFlow docs recommend that
ControlFlow
can be used in Visitor patterns, but there are a couple of rough edges I noted when implementing my own visitor:?
after a method call, and fail to propagate aControlFlow::Break
, resulting in bugs.ControlFlow
(with variantsContinue
andBreak
) is an abstraction with semantics related to execution of an algorithm, and not greatly suited to an external interface. In one interface, I wanted to map it to a more semantic type:Result
. But I noticed that whilstControlFlow
has utility methodsbreak_value()
andcontinue_value()
to map to anOption
, it does not have any forResult
.Motivating examples or use cases
My personal experience with this was implementing a visitor pattern for a validator (more specifically, it was an intepreter / validator / visitor-runner combination).
The main issue stemmed from the fact
ControlFlow
wasn't#[must_use]
. The interpreter logic covered about 500 lines, and I missed a couple of?
after some method calls, which resulted in bugs. Thankfully I caught these in tests and made sure to plaster a#[must_use]
on every method which returned aControlFlow
. But ideally the compiler would have helped me out.Trimmed down example code demonstrating the problems follows. It could be argued that just using
Result
here might have been easier, but I thinkControlFlow
does represent the semantics better - particularly if you think about this as an Interpreter/Visitor rather than as a Validator.The example also includes a cheeky note on do yeet:
Solution sketch
#[must_use]
toControlFlow
to avoid these problems.continue_ok(self) -> Result<C, B>
andbreak_ok(self) -> Result<B, C>
(name suggestions courtesy of @NoraCodes in this comment)Alternatives
#[must_use]
#[must_use]
to all their methods/functions... but like withResult
, it feels that the 99% use case is to expect thatControlFlow
should always be handled, to avoid missing aBreak
. So I think it makes sense to put it on the type, and avoid this class of error.continue_ok
andbreak_ok
:Links and related work
ControlFlow
enum, for use withtry_fold
and inTry
rust#75744yeet
expressions (feature(yeet_expr)
) rust#96373What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution:
The text was updated successfully, but these errors were encountered: