-
Notifications
You must be signed in to change notification settings - Fork 111
Conversation
8af158e
to
eae591c
Compare
Fixes #44.
Works now, just have to fix the name for Inner. |
eae591c
to
82a27f3
Compare
Any idea about how to handle Inner? Ideally, it's name would be generated, but rust macros don't seem to support it. |
@Yamakaky I am not 100% sure why you need the outer newtype tuple struct. Is it due to conflicting implementations on If this cannot be avoided I see three options: a) wait until macros 1.1 is stable (which may even happen in the upcoming release if I read some comments correctly) pub mod $error_name {
pub struct Inner;
pub struct Outer;
}
pub mod $error_name2 {
pub struct Inner;
pub struct Outer;
} instead of pub struct Inner;
pub struct $error_name;
pub struct Inner; // conflict with previous definition
pub struct $error_name2; c) or last but not least, you could do some really crazy macro hacking like this until macros 1.1 are stable (that actually works) macro_rules! pop_unique_struct {
($body:tt) => {
pop_unique_struct_and_save!{
$body
Inner1
Inner2
Inner3
Inner4
Inner5
}
}
}
macro_rules! pop_unique_struct_and_save {
($captured_body:tt $ident:tt $( $tail:tt )*) => {
pub struct $ident $captured_body
macro_rules! pop_unique_struct {
($body:tt) => {
pop_unique_struct_and_save!{
$body
$( $tail )*
}
}
}
}
}
pop_unique_struct!{{ foo: u32 }}
pop_unique_struct!{{ bar: u32 }}
pop_unique_struct!{{ baz: u32 }}
fn main() {
let x1 = Inner1 { foo: 1 };
let x2 = Inner2 { bar: 1 };
let x3 = Inner3 { baz: 1 };
} PS: That last approach obviously only works for a finite amount of invocations... |
OMG what is this madness XD |
Yeah, I know it's quite ugly, but it works. ^^ The thing is you can't use macros in identifyer position yet. So if you need varying identifiers in the macro expansion, these must be fed into the macro invocation first. This trick uses higher order macros (macros defined by macros) to manage something like a global state and feed varying identifiers back into another macro. It's quite some madness indeed. If you want to go this route you'll probably need to store the last used identifier in a higher order macro, so you can still access it. That's definitely doable and I could help you. But it'll not be clean code in the sense of easily understandable. Off topic: If you want to see some more pushing the limits with higher order macro trickery you may want to check out my proof of concept to boost the macro recursion limit exponentially with HOMs and macro callbacks: https://github.com/colin-kiegel/enum-transform/blob/tailcall_optimization/src/tailcall_optimization.rs But back to your topic: avoiding the wrapper with conditional compilation might be the simplest approach if you don't run into overlapping implementations you don't want. |
Yeah, conditional compilation is simpler than meta-macros XD. |
Yes I would try If you fear too much boilerplate duo to conditional compilation, then maybe you can abstract it away like this: #[cfg(feature = "boxed-error")]
mod boxed_error {
pub type Box<T> = ::std::boxed::Box<T>;
pub fn new<T>(t: T) -> ::std::boxed::Box<T> { ::std::boxed::Box::new(t) }
}
#[cfg(not(feature = "boxed-error"))]
mod boxed_error {
pub type Box<T> = T;
pub fn new<T>(t: T) -> T { t }
} You can then always use |
Hm, on second thought using macros will likely interfere with this abstraction idea unless it is imported into the scope of the macro invocation. So maybe this abstraction is not such a good idea.. I am not sure. |
|
What do you mean by default feature? Boxed errors? |
Yes, boxed errors. |
Is this pull request abandoned? Will error-chain keep on inviting bloatware? |
What do you mean? |
@Yamakaky, What is the status of boxed errors feature of error-chain? This pull request remains open, but inactive, conflicted and with failed checks for about 3 months, leaving uncertainity about the future of the feature. |
Closed by #225 |
Downside : the type inference for
chain_err
is even stricter...