they passed the compiler and did the same thing.
So are they the three identical forms to call a macro ?
If not, could you explain for me ? and which one should I prefer ?
They aren't quite the same. I'm not sure the exact details, but macros invoked with {} can be used as statements, where as macros invoked with [] or () are always expressions.
See Rust Playground for the difference, for example (there is a syntax error in second).
From memory, there's no difference between [], {}, or (). The compiler will group all tokens inside one the brackets as a single token tree which then gets given to the macro. So by the time the macro gets the token trees, the original type of brackets being used has been erased.
As @tom.prince mentioned, {} are slightly different in that the parser interprets curly braces as a block. So you can have something like error_chain!{} as a top level item, whereas if I used error_chain!() I'd need to put a semicolon at the end to turn it into a valid statement.