デバッグ
rustc
は構文拡張全般をデバッグするためのツールをいくつか提供しています。さらに、宣言的マクロと手続き的マクロのそれぞれに合わせたより特化したツールも提供します。
普段は展開後のコードを見ることはないため、構文拡張の展開結果がよく分からなくなることがあります。
ありがたいことに、rustc
のunstableな -Zunpretty=expanded
引数を使って展開後のコードを見ることができます。
次のようなコードがあるとします:
// Shorthand for initializing a `String`.
// `String` 初期化の略記法
macro_rules! S {
($e:expr) => {String::from($e)};
}
fn main() {
let world = S!("World");
println!("Hello, {}!", world);
}
これを次のコマンドでコンパイルすると:
rustc +nightly -Zunpretty=expanded hello.rs
次のような結果が得られます(結果を整形しています):
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
// Shorthand for initializing a `String`.
// `String` 初期化の略記法
macro_rules! S { ($e : expr) => { String :: from($e) } ; }
fn main() {
let world = String::from("World");
{
::std::io::_print(
::core::fmt::Arguments::new_v1(
&["Hello, ", "!\n"],
&match (&world,) {
(arg0,) => [
::core::fmt::ArgumentV1::new(arg0, ::core::fmt::Display::fmt)
],
}
)
);
};
}
構文拡張のデバッグを支援する手段を提供しているのは rustc
だけではありません。
dtolnay氏がcargo-expand
という名前の素晴らしい cargo
プラグインを制作しています。これは基本的には前述した -Zunpretty=expanded
オプションの単なるラッパーです。
Playgroundを利用することもできます。右上にある TOOLS
ボタンをクリックすると、構文拡張を展開するオプションが選択できます。