DanielKeep / rust-error-type

MIT License
20 stars 1 forks source link

Multiple Errors #2

Open dbrgn opened 8 years ago

dbrgn commented 8 years ago

How do I define multiple error structs using your macro in a single module?

For example, when I copy your error declaration (line 6-24) in tests/quickie.rs and change the name, I get the following compilation errors:

   Compiling error-type v0.1.2 (file:///mnt/data/Projects/rust-error-type)
<error_type macros>:13:9: 15:43 error: duplicate definition of type or module `ErrorDisplay` [E0428]
<error_type macros>:13 + } } } pub trait ErrorDisplay {
<error_type macros>:14 fn error_fmt ( & self , & mut :: std:: fmt:: Formatter ) -> :: std:: result::
<error_type macros>:15 Result < (  ) , :: std:: fmt:: Error > ; } pub trait ErrorDescription < 'a > {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:26:1: 44:2 note: in this expansion of error_type! (defined in <error_type macros>)
<error_type macros>:13:9: 15:43 help: run `rustc --explain E0428` to see a detailed explanation
<error_type macros>:13:9: 15:43 note: first definition of type or module `ErrorDisplay` here
<error_type macros>:13 + } } } pub trait ErrorDisplay {
<error_type macros>:14 fn error_fmt ( & self , & mut :: std:: fmt:: Formatter ) -> :: std:: result::
<error_type macros>:15 Result < (  ) , :: std:: fmt:: Error > ; } pub trait ErrorDescription < 'a > {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:6:1: 24:2 note: in this expansion of error_type! (defined in <error_type macros>)
<error_type macros>:15:44: 16:41 error: duplicate definition of type or module `ErrorDescription` [E0428]
<error_type macros>:15 Result < (  ) , :: std:: fmt:: Error > ; } pub trait ErrorDescription < 'a > {
<error_type macros>:16 fn error_desc ( & self ) -> & 'a str ; } pub trait ErrorCause < 'a > {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:26:1: 44:2 note: in this expansion of error_type! (defined in <error_type macros>)
<error_type macros>:15:44: 16:41 help: run `rustc --explain E0428` to see a detailed explanation
<error_type macros>:15:44: 16:41 note: first definition of type or module `ErrorDescription` here
<error_type macros>:15 Result < (  ) , :: std:: fmt:: Error > ; } pub trait ErrorDescription < 'a > {
<error_type macros>:16 fn error_desc ( & self ) -> & 'a str ; } pub trait ErrorCause < 'a > {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:6:1: 24:2 note: in this expansion of error_type! (defined in <error_type macros>)
<error_type macros>:16:42: 18:12 error: duplicate definition of type or module `ErrorCause` [E0428]
<error_type macros>:16 fn error_desc ( & self ) -> & 'a str ; } pub trait ErrorCause < 'a > {
<error_type macros>:17 fn error_cause ( & self ) -> :: std:: option:: Option < & 'a :: std:: error::
<error_type macros>:18 Error > ; } impl :: std:: error:: Error for $ err_name {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:26:1: 44:2 note: in this expansion of error_type! (defined in <error_type macros>)
<error_type macros>:16:42: 18:12 help: run `rustc --explain E0428` to see a detailed explanation
<error_type macros>:16:42: 18:12 note: first definition of type or module `ErrorCause` here
<error_type macros>:16 fn error_desc ( & self ) -> & 'a str ; } pub trait ErrorCause < 'a > {
<error_type macros>:17 fn error_cause ( & self ) -> :: std:: option:: Option < & 'a :: std:: error::
<error_type macros>:18 Error > ; } impl :: std:: error:: Error for $ err_name {
<error_type macros>:7:39: 9:49 note: in this expansion of error_type_impl! (defined in <error_type macros>)
tests/quickie.rs:6:1: 24:2 note: in this expansion of error_type! (defined in <error_type macros>)
error: aborting due to 3 previous errors
Could not compile `error-type`.
DanielKeep commented 8 years ago

Unfortunately, you can't. The problem is that the macro uses traits to dispatch things like Display to the individual error cases. These traits often have to be implemented on non-local types; thus, the traits themselves must be local. This in turn means the macro has to define the traits anywhere it wants to use them, but it has no way of "hiding" them from other invocations of the macro.

Hence the above errors.

Without the ability to either construct identifiers or hide items, there's not a great deal I can really do about this. One solution would be to completely rewrite the macro from the ground-up to not use trait dispatch, but I don't have the time for that at the moment.

The simplest workaround is probably to just put each macro invocation in a little module and pull the error type out with use a use in the parent module:

pub use error1::Error;
mod error1 { error_type! { ... } }
dbrgn commented 8 years ago

OK, I guess I'll live with that module workaround for now :)

DanielKeep commented 8 years ago

I'll leave this open as a reminder that this could theoretically be improved. :)

dbrgn commented 8 years ago

Yeah, would definitely be nice.