Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
procedural-macros
Search
cipepser
June 16, 2020
Technology
230
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
procedural-macros
cipepser
June 16, 2020
More Decks by cipepser
See All by cipepser
long-running-tasks
cipepser
3
710
layerx-fde-practices
cipepser
7
3.6k
NIKKEI Tech Talk#38
cipepser
0
1.3k
LayerXにおけるFDEについて
cipepser
4
4.2k
20250725-bet-ai-day
cipepser
4
740
Criterion-rs
cipepser
0
200
Practical Anonify
cipepser
2
940
Move for Libra written in Rust
cipepser
2
3.5k
How IBLT Works
cipepser
0
300
Other Decks in Technology
See All in Technology
E2Eってつらくないですか?E2Eの管理コストを下げる手段とその実践
akaboshinit
6
2.9k
Vue で書く 空間コンピューティング、TresJS と WebXR を使ったXR デバイスのフロントエンド開発
hiranuma
0
150
AIエージェント時代、Kaggleにどう取り組むか
takanao
2
470
慶應義塾大学 AI実践05 論文執筆の仕組み化
keio_smilab
PRO
6
3.4k
200人の配信コメント、 全部Jevが仕分けます 〜 マサカリガードを作ってみた 〜
katayamatg
1
510
スマートロックを支えるFlutter × ネイティブ連携の実践 / Flutter and Native Integration in Practice: Powering Smart Locks
bitkey
PRO
0
140
Oracle Database Security 詳細解説
oracle4engineer
PRO
1
220
企画からFlutter実装まで、1つの機能を一貫して開発したプロセスと成果物
khiroyuki1003
0
120
リアクションエンジニア ― 小さなリアクションから、話しかけやすい組織をつくる ―
ryuguyana
1
110
詳解 never 型 - ボトム型の性質を深掘り
nealle
0
140
続・ソフトウェアアーキテクトのための意思決定術: Decision Readiness, Revisited — When AI Changes the Economics of Software Architecture
snoozer05
PRO
1
120
Systems Manager AgentがインストールされたPCを紛失した時の対策を考えてみた
amarelo_n24
1
110
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
The Curious Case for Waylosing
cassininazir
1
600
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Raft: Consensus for Rubyists
vanstee
143
7.8k
Typedesign – Prime Four
hannesfritz
42
3.2k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
310
The agentic SEO stack - context over prompts
schlessera
0
990
Building Adaptive Systems
keathley
44
3.3k
Faster Mobile Websites
deanohume
310
32k
Color Theory Basics | Prateek | Gurzu
gurzu
1
510
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
Transcript
Procedural macros入門 cipepser 2020/6/16 下町.rs #2
自己紹介 • cipepser(さいぺ) • リードエンジニア@LayerX ◦ R&Dチーム • 経歴 ◦
SIerで証券系システムのネットワーク設計、構築 ◦ Fintech会社で新規事業の立ち上げ • 趣味プロジェクト ◦ コンパイラ ◦ 正規表現ジェネレータ ◦ protocol buffersデコーダ ◦ (多くがやりかけ...)
Anonifyをリリースしました ソースコード ホワイトペーパー https://github.com/LayerXcom/anonify https://layerx.co.jp/wp-content/uploads/2020/06/anonify.pdf ドキュメント https://layerxcom.github.io/anonify-book/ スライド https://speakerdeck.com/layerx/anonify TEE内のテストにProcedural
macrosを利用している
アジェンダ 1. Procedural macros概要 2. 通常のRustマクロ 3. Procedural macrosでよく利用される3つマクロたち 4.
Custom Attributeの実装
Procedural macros概要
Procedural macrosをざっくりと理解する • Rust edition 2018から使えるようになった • 通常のRustマクロ ◦ macro_rules!
◦ パターンマッチ • Procedural macros ◦ Function-like macros ▪ custom!(...) ◦ Derive macros ▪ #[derive(CustomDerive)] ◦ Attribute macros ▪ #[CustomAttribute]
通常のRustマクロ
macro_rules! vec { () => ( $crate::vec::Vec::new() ); ($elem:expr; $n:expr)
=> ( $crate::vec::from_elem($elem, $n) ); ($($x:expr),+ $(,)?) => ( <[_]>::into_vec(box [$($x),+]) ); } Proceduralでない通常のRustマクロはパターンマッチがベース https://github.com/rust-lang/rust/blob/master/src/liballoc/macros.rs • (pattern) => (template); • *, +による繰り返し ◦ 参照は$で対になっている必要がある • exprやtyなどのフラグメント型 vec![]: vec![“a”; 3]: vec![1,2,3]:
Procedural macrosでよく利用される 3つマクロたち
proc_macro • Procedural macrosの実装をサポートするラ イブラリ • Cargo.tomlのlibで有効化して使う • proc_macro2というwrapperもある ◦
build.rsやmain.rsのような別のコンテキストに proc_macroの機能を持ち込みたいときに使う • TokenStreamを操作する ◦ ASTを直接操作するわけではない ◦ Vec<TokenTree>をcloneしやすくしたもの ◦ TokenTree = lexical token https://doc.rust-lang.org/proc_macro/
syn • 文字列を入力に構文解析 • validなRustコードであることを保証 • Structsでもろもろ定義されている ◦ 次ページでItemFnを例にみてみます https://docs.rs/syn/1.0.31/syn/
例)synで関数名を取得する pub struct ItemFn { pub attrs: Vec<Attribute>, pub vis:
Visibility, pub sig: Signature, pub block: Box<Block>, } pub struct Signature { pub constness: Option<Token![const]>, pub asyncness: Option<Token![async]>, pub unsafety: Option<Token![unsafe]>, pub abi: Option<Abi>, pub fn_token: Token![fn], pub ident: Ident, pub generics: Generics, pub paren_token: token::Paren, pub inputs: Punctuated<FnArg, Token![,]>, pub variadic: Option<Variadic>, pub output: ReturnType, } 関数名を持つ
quote • synのデータ構造を受け取り、トークン列に 変換し直す • #varで補完 ◦ 例)取得した関数名を利用したいとき https://docs.rs/quote/1.0.7/quote/ let
f = parse_macro_input!(input as ItemFn); let f_ident = &f.sig.ident; let q = quote!( #f_ident .. };
Custom Attributeの実装
Attributeの復習 #[test] fn check() { let x = 1; assert_eq!(x,
1); } #[test]を付与することで、check()に 「cargo test時に実行される」という意味を付与
やること:Custom Attributeで、cargo runでテストを走らせます use utils::{test_case, run_inventory_tests}; #[test_case] fn check() {
let x = 1; assert_eq!(x, 1); } #[test_case] fn fail() { let x = 1; assert_eq!(x, 2); } fn main() { run_inventory_tests!(); } • #[test_case] attributeを自作 • cargo runで実行 ◦ ✖ cargo test
ディレクトリ構造とCargo.toml [lib] proc-macro = true [dependencies] proc-macro2 = "1.0" quote
= "1.0" syn = "1.0" main関数を実装 標準出力の調整など Procedural macrosを実装 proc-macroを有効化
#[proc_macro_attribute] pub fn test_case(_attr: TokenStream, input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as ItemFn); let f_ident = &f.sig.ident; let q = quote!( #f inventory::submit!( utils::TestCase( concat!(module_path!(), "::", stringify!(#f_ident)).to_string(), #f_ident ) ); ); q.into() } Attributeを実装する TokenStreamをItemFnとしてparse 失敗したらコンパイルエラー attributeの名前を関数名にする 関数(check()やfail())が展開される
pub struct TestCase(pub String, pub fn() -> ()); inventory::collect!(TestCase); #[macro_export]
macro_rules! run_inventory_tests { () => { utils::test_start(); let mut ntestcases: u64 = 0u64; let mut failurecases: Vec<String> = Vec::new(); for t in inventory::iter::<utils::TestCase>.into_iter() { utils::test(&mut ntestcases, &mut failurecases, t.1, &t.0); } utils::test_end(ntestcases, failurecases) }; } #[test_case] attrを付与した関数を集める submit!した関数たちを集めてくる utils::test内でt.0を実行する
custom attributesを使ってみる use utils::{test_case, run_inventory_tests}; #[test_case] fn check() { let
x = 1; assert_eq!(x, 1); } #[test_case] fn fail() { let x = 1; assert_eq!(x, 2); } fn main() { run_inventory_tests!(); } attrを設定 attrを設定 main関数内でテストを実行
`cargo test`ではなく、`cargo run`でテストを実行する 関数名(checkやfail)も出力できた
• Procedural macrosと通常のマクロを紹介 • Procedural macrosでよく利用される3つマクロたち ◦ proc_macroで、Procedural macrosが有効になる ◦
synで、文字列からRustコードに構文解析する ◦ quoteで、synのデータ構造からRustコードに変換し直す • Custom Attributeを実装した ◦ 自分でも動かしたい!という方は以下にソースコードを公開してます。 ◦ https://github.com/cipepser/rust-custom-attribute まとめ
References • proc_macro - Rust https://doc.rust-lang.org/proc_macro/ • O'Reilly Japan -
プログラミングRust https://www.oreilly.co.jp/books/9784873118550/ • Procedural Macros - The Rust Reference https://doc.rust-lang.org/reference/procedural-macros.html • D - マクロ - The Rust Programming Language https://doc.rust-jp.rs/book/second-edition/appendix-04-macros.html • proc_macro2 - Rust https://docs.rs/proc-macro2/1.0.18/proc_macro2/ • syn - Rust https://docs.rs/syn/1.0.31/syn/ • quote - Rust https://docs.rs/quote/1.0.7/quote/ • inventory - Rust https://docs.rs/inventory/0.1.6/inventory/ • Procedural Macros に入門していたずらしてみた - Don't Repeat Yourself https://yuk1tyd.hatenablog.com/entry/2018/12/25/192041 • Procedural macros 雑入門 - slideship.com https://slideship.com/users/@statiolake/presentations/2019/07/CZ9wX4Zi8R93MhxN7jRBK5/?p=2
ブロックチェーン技術をもとに、「新たな経済基盤」をつくりだす。 それは、信用や評価のあり方を変え、 業務や生産をはじめとした経済活動の摩擦を解消し、 この国の課題である生産性向上を実現する。 私たちは、そう信じて行動し続けます。 ブロックチェーンが実装された社会、 そこには、これまでの延⻑にはないまったく新しい可能性が広がっている。 LayerXは、デジタル社会への発展を後押しすることで、 経済史に新たな1ページを刻んでいきます。