Can I override a macro from the standard library using my own custom macro?

I am working on a procedural macro, and I found that the compiler does not provide information about proc-macro boxes with procedural macros. I tried to override panic!to print the location:

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!());
    }};
}

But the compiler does not work with

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

I set a limit for 65536to prove that this is due to recursive extension.

According to the macro chapter "Rust Programming Language", the first version , my own is panic!not displayed std_panic!, so it should use panic!from the standard library.

I also tried

#![feature(no_std)]
#![no_std]
#[macro_use(panic)]
extern crate std;

but that will not work.

+4
1

, :

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.

. :

+4

Source: https://habr.com/ru/post/1684391/


All Articles