Ever since fail and assert got turned into macros, failing with a string
message has become quite line-noisy:
fail!(~"cause")
And including additional informations in the fail message makes the line
quite heavy, even though it should be encouraged for better failure
messages:
fail!(fmt!("failed because of %?", cause))
For context: fail takes a ~str because it needs to own the string, so
that it can be send to the platform thread and displayed during task
failure. assert has the same requirement for its optional second
argument, but currently accepts a &str because it performs a copy
internally.
A discussion on IRC resulted in these possible options:
1. Rewrite fail!() and assert!() to accept both ~str or &'static str:
fail!(): unchanged
fail!(~"cause"): unchanged
(not possible now) -> fail!("cause")
fail!(fmt!("failed because of %?", cause)): unchanged
...etc
Pro: No unnecessary copy, 100% backwards compatible.
Con: Kinda hard to implement, fail!(fmt!()) still heavy.
2. Turn fail and assert into diverging functions:
fail!() -> fail()
fail!(~"cause") -> fail_owned(~"cause")
(not possible now) -> fail_static("cause")
fail!(fmt!("failed because of %?", cause)) -> fail_owned(fmt!("failed
because of %?", cause))
...etc
Pro: No macros necessary.
Con: Users need to remember different function signatures for failing,
fail_owned(fmt!()) even more heavy.
3. Rewrite fail!() and assert!() to pass arguments to fmt!():
fail!(): unchanged
fail!(~"cause") -> fail!("s", ~"cause")
(not possible now) -> fail!("cause")
fail!(fmt!("failed because of %?, cause)) -> fail!("failed because of
%?", cause)
...etc
Pro: Easy formatted message per default, common case fail!("static str")
needs no '~' sigil, failure macros work similar to logging macros.
Con: Heavier syntax if you have a ~str already, always copies string.
(however, fmt!() could get an optimisation so that fmt!("...") expands
to ~"...", and fmt!("s", s) to s)
4. (1 + 3) Rewrite fail!() and assert!() to accept ~str and &'static str
if 1 argument, pass arguments to fmt!() if more than 1:
fail!(): unchanged
fail!(~"cause"): unchanged
(not possible now) -> fail!("cause")
fail!(fmt!("failed because of %?, cause)) -> fail!("failed because of
%?", cause)
Pro: All of 1 and 3.
Con: Even harder to implement than 1, quite complex.
Personally I think 3 is the easiest to implement option, and nice even
without the fmt! optimisation. I already locally implemented the
necessary changes that would allow switching to it after an snapshot,
but I wanted to ask what others think.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev