[Rust] 매크로 디버깅

매크로는 간단할 때는 괜찮지만, 복잡도가 증가할수록 디버깅 난이도가 급상승하는 녀석이다.

매크로 디버깅에 유용한 테크닉 몇가지를 정리해본다.




매크로 펼쳐보기 (rustc nightly)

매크로를 디버깅하기 힘든 이유 중 하나는, 코드 수준에서 파악이 바로 되지 않고 컴파일러를 거친 뒤에야 평가되기 때문이다.
때로는 매크로의 결과물을 보며 개선을 하는 것이 훨씬 편할 때가 있다.

이런 매크로가 있다면

rustc의 nightly 기능을 이용해서 매크로 결과를 펼쳐볼 수 있다.

rustc +nightly -Zunpretty=expanded .\src\main.rs

이렇게.
근데 이건 소스코드간 관계가 복잡해질수록 보기도 불편하고 쓰기도 불편해진다.
이 경우에는 싱글소스라서 사용이 간단해보인 것이다.




매크로 펼쳐보기 (cargo-expand 사용)

이게 좀 범용적으로 많이 사용되는 수단이다.
먼저 해당 CLI를 설치한다.

그러고 저걸 실행하면

바로 엔트리포인트의 매크로를 평가해서 보여준다.
main.rs이 있으면 그걸 평가하고, lib.rs가 있으면 그걸 평가한다. 둘다 있으면 명시적으로 전달해줘야 한다.

그 외에 특정 부분만 평가해서 보고 싶다면 모듈명을 지정해서 expand 명령을 날려주면 된다.

이런 식이다.




매크로 추적하기 (nightly)

근데 매크로 호출의 깊이가 깊어진다면 단순히 최종 결과물을 보는것만으로는 파악이 힘들때가 많다.

이 코드의 경우만 해도 매크로가 2뎁스다.

아직 nightly이긴 하지만, rust는 그런 것에 대한 매크로 추적 기능을 제공한다.

먼저 nightly로 툴체인을 바꾸고

소스코드 위에다

#![feature(trace_macros)]

trace_macros!(true);

이거 2줄을 추가해서 trace를 활성화한다.


그리고 실행해보면

이런식으로 매크로가 어떤 단계를 거쳐서 확장되었는지를 로그로 출력해서 보여준다.



참조
https://veykril.github.io/tlborm/syntax-extensions/debugging.html
https://github.com/dtolnay/cargo-expand
https://stackoverflow.com/questions/28580386/how-do-i-see-the-expanded-macro-code-thats-causing-my-compile-error
https://stackoverflow.com/questions/30200374/how-do-i-debug-macros