Counterpoint: we have an implicit From::from
in the translation of ?
's return
path. What's different between yeet
and return
that yeet
should do an implicit conversion but return
shouldn't?
Should <Result<T, E> as Try>::from_output
accept any Into<T>
instead of just T
? This would make the type conversion done by the Try
implementation uniform between the Break
and Continue
cases, and not impact return
from a normal function.
(Adding a blanket conversion for Result
's Ok
type when Into::into
ing the whole is breaking anyway, so the non-try
and the try
case are fairly disjoint.)
I'm quite split here; at a gut level I agree that introducing an implicit conversion here isn't desirable, but I'm having a hard time articulating why I'm perfectly fine with the implicit conversion for Result
's Err
variant.
Perhaps it's how much it saves? ?
doing conversion saves multiple instances of .map_err(Into::into)
per function, whereas return
doing conversion saves a single .into()
per return Ok(_)
, which are much rarer (typically only the tail return, even).
Perhaps it's convention? Result
's Err
type conventionally implements Error
and only implements From
for wrapping a source error, and typically only heap allocates the source error if its an "unexpected" errors likely to just be yote up the stack where stack size overhead is more costly to program execution than a presumed cold allocation.
Perhaps it's familiarity? IIRC try!
was added essentially the version after I started using Rust, ?
has been available longer than not, and the From::from
conversion of the yote error has been there from the beginning. On the flip side, a lack of implicit conversions in normal program execution is a selling point of Rust over C++, though it's not as big of a focus with the shift in marketing focus from C++ domains to more general development empowerment (notably application development, not just systems development, for all the good that distinction is(n't) worth).
Separately, I think a significant chunk of want for an implicit conversion on return
is probably better served by more specific features which provide coercions, e.g. enum dyn Trait
or other anonymous-enum-adjacent features would likely coerce from their constituent types, removing the needed .into()
from using -> Box<dyn Trait>
instead.