我正在处理一个程序宏,我发现编译器在程序宏发生恐慌时没有提供有关proc-macro crates的信息。我试图覆盖panic!
来打印位置:
macro_rules! std_panic {
($($args:tt)+) => {{
panic!($($args)*);
}};
}
/// panic! with location reporting.
macro_rules! panic {
($($args:tt)+) => {{
std_panic!("{}\n --> {}:{}:{}", format_args!($($args)*), file!(), line!(), column!());
}};
}
但是编译器失败了
error: recursion limit reached while expanding the macro `std_panic`
--> src/lib.rs:30:9
|
30 | std_panic!("{}\n --> {}:{}:{}", format_args!($($args)*), file!(), line!(), column!());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
54 | _ => unimplemented!("handling tuple struct"),
in this macro invocation
|
= help: consider adding a `#![recursion_limit="131072"]` attribute to your crate
我将限制设置为65536
以证明这与递归扩展有关。
根据the macros chapter of The Rust Programming Language, first edition,panic!
无法看到我自己的std_panic!
,因此应使用标准库中的panic!
。
我也试过
#![feature(no_std)]
#![no_std]
#[macro_use(panic)]
extern crate std;
但它没有用。
答案 0 :(得分:4)
是,您可以覆盖标准库中的宏:
macro_rules! panic {
($($arg:tt),*) => {};
}
fn main() {
panic!("Exit");
println!("Or not...");
}
否,您无法再调用刚刚被遮蔽的宏。
宏在使用地点扩展。在您的示例中,当您尝试使用panic!
时,它会扩展为std_panic!
,而panic!
会扩展为panic!
。此时,您的拥有 do_foo
就是范围内的。
这个更简单的示例显示,宏调用的任何do_foo
恰好在范围中扩展宏。请注意,宏甚至没有定义macro_rules! foo {
() => { do_foo() };
}
fn main() {
{
fn do_foo() { println!("1") }
foo!();
}
{
fn do_foo() { println!("2") }
foo!();
}
}
:
panic!
我没有办法急切地扩展std_panic
class myTabBarController: UITabBarController {
override func viewDidLoad() {
UITabBar.appearance().backgroundImage = UIImage(named: "secretTab.png")
}
内部的 class myTabBarController: UITabBarController {
override func viewDidLoad() {
self.tabBar.clipsToBounds = true
self.tabBarController?.tabBar.autoresizesSubviews = false
UITabBar.appearance().backgroundImage = UIImage(named: "secretTab.png")
}
。
另见: