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
Rustソースコードのざっくりとした歩き方 🦀
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
TaKO8Ki
August 30, 2023
Programming
7.3k
14
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rustソースコードのざっくりとした歩き方 🦀
https://techfeed.io/events/techfeed-experts-night-24
TaKO8Ki
August 30, 2023
More Decks by TaKO8Ki
See All by TaKO8Ki
RustのReturn-position impl trait in trait (RPITIT) の実装を雑に見てみる
tako8ki
1
1.1k
Rustで始めるコードファーストなOpenAPI定義の生成 🦀
tako8ki
1
3.3k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
750
How to contribute to Rust and what I have recently been working on
tako8ki
0
480
RustでTUIのSQLクライアントを作った
tako8ki
0
1.7k
A Ruby version manager written in Rust, which is 7 seconds faster than rbenv
tako8ki
1
1.9k
Other Decks in Programming
See All in Programming
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.9k
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
250
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.1k
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
260
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
170
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
980
ChromeでローカルLLM
ryu1013
0
130
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.4k
ActionController meets Protocol Buffers
sorah
0
270
Event is what happens
moro
2
460
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
130
SREの越境 / SRE Collaboration
y0hgi
2
310
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
410
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.1k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
480
The Pragmatic Product Professional
lauravandoore
37
7.5k
Are puppies a ranking factor?
jonoalderson
2
4k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Transcript
Rustソースコードのざっくり とした歩き方 🦀 Takayuki Maeda / TaKO8Ki
• Rust committer (member of compiler contributors team and diagnostic
working group) • Rust Foundation 2023 Fellow Takayuki Maeda / TaKO8Ki @TaKO8Ki @TaKOBKi
テーマ
rustcのコードをほとんど読んだことないRustacean がコントリビュートするための ざっくり入門編
セットアップ
セットアップ 「Rust Compiler Development Guide」という素晴らしいドキュメントがある。 ref:
https://rustc-dev-guide.rust-lang.org
とりあえずgit cloneしてみる。 $ git clone https://github.com/rust-lang/rust.git $ cd rust
セットアップ rustリポジトリのbuildにはx.pyというツールを使います。これで標準ライブラリ含めて 丸っとbuildできます。 ref: https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html
次にsetupしてみる。色々出てくるので最後compilerを選択する。 $ ./x.py setup
VSCodeユーザー向けに setting.jsonが自動的に追加される。 ref: Configuring rust-analyzer for rustc
その他サブコマンド (cargoと同じ感じ): $ ./x.py check $ ./x.py build $ ./x.py
test $ ./x.py fmt $ ./x.py clean
いよいよ、buildしてみる。 $ ./x.py build
buildしたcompilerをcargoやrustcで使う。 $ rustup toolchain link stage1 build/[your host]/stage1 $ cargo
+stage1 -vV $ rustc +stage1 -vV
準備が整ったのでとりあえずテストを実行してみる。 $ ./x.py test
セットアップ デバッグはどうやるのか? ref: https://rustc-dev-guide.rust-lang.org/compiler-debugging.html
backtraceが欲しい時は、 $ RUST_BACKTRACE=1 cargo +stage1 build
エラーの発生箇所が知りたい場合は、 $ RUSTFLAGS='-Z track-diagnostics' cargo +stage1 build
また、Rustではloggingにtracingというtokio organizationで開発されて いるcrateを使っている。 ref: Using tracing to debug the compiler
$ RUSTC_LOG=rustc_parse=debug cargo +stage1 build
セットアップ 基本は、修正 → UIテスト追加 → ./x.pyでテスト実行して壊れてないか確認 → プルリク の流れが多い。
コードを読んでみる
コードを読んでみる 全ては紹介しきれないので、まず、比較的優しい気がするparserを読んでみる。parse はparseがprefixとしてつくmethodやfunctionを目印に読んでいけばいい。 Rustのparserはトップダウンな再帰下降パーサー。 ref: https://rustc-dev-guide.rust-lang.org/overview.html#lexing-and-parsing
entry pointは、 - Parser::parse_crate_mod - Parser::parse_mod
parse_modを読み進めてみる。
parse_modを読み進めてみる。 上から順に見ていくと、 ここでloopでitemをparseしてそう
次にparse_itemに飛んでみる。
parse_item_を実行しているのでそっちに行ってみる。
parse_item_はこんな感じなのでそれっぽいparse_item_commonを見て みる。
parse_item_はこんな感じなのでそれっぽいparse_item_commonを見て みる。
まだコアの実装ぽいところにきて無さそうなので、parse_item_common_に ジャンプする。
まだコアの実装ぽいところにきて無さそうなので、parse_item_common_に ジャンプする。
なんかそれっぽくなってきた。 Parser::parse_item_commont_
なんかそれっぽくなってきた。 Parser::parse_item_commont_
拡大すると、なんか色々やってそうなmethodが見える。
ついにparse_item_kindに辿り着いた。
例えばここでenumをparseしてる。
せっかくなので、parse_item_enumも覗いてみる。
確かにmethodの下の方でコンマ区切りでEnum variantをparseしてそう。
では、ここで変更加えてbuildしてみる。 例えばこのエラーメッセージでリポジトリ 内を検索してみると
するとUIテスト用のファイルが見つかる。 tests/ui/structs-enums/issue-103869.rs
コードを読んでみる UIテストとは何か? > tests that check the stdout/stderr from the
compilation and/or running the resulting executable コンパイルによるstdout/stderrと 実行可能ファイルを実行した結果をチェックするためのテスト ref: https://rustc-dev-guide.rust-lang.org/tests/compiletest.html#test-suites
では適当なdebug用のcrateを作ってmain.rsに下記をコピペしてみる。
試しにstage1コンパイラでbuildしてみると、 $ cargo +stage1 build
こういうエラーが得られる。
こういうエラーが得られる。 さっきparse_item_enumで見つけたエ ラーがある
試しにエラーメッセージを変更してみる。 perhaps you meant to use `struct` here foobar
再度buildする。 $ ./x.py build
もう一度デバッグ用のcrateをbuildしてみると、確かにエラーが変わってる。
これであなたもRustコントリビューター 🦀
コードを読んでみる rustc_parseの他にもRustリポジトリにはさまざまなcrateがある。 - rustc_ast_lowering - rustc_ast_passes - rustc_hir - rustc_hir_typeck
- rustc_borrowck などなど。
コードを読んでみる 例えば rustc_ast_lowering はrustc_parseで作ったASTをHIRにloweringするため のcrate。lowerがprefixなmethod、functionが目印。
rustc_ast_loweringのentry pointは、 rustc_ast_lowring::lower_to_hir
同じように覗いてみると、
同じように覗いてみると、 ast_indexごとにlower_nodeを呼んでそう
lower_nodeの実装は、
ここまでくるとなんかいけそう
同じように下に読み進めていけば良さそう
コードを読んでみる 基本はこんな感じで下記のようなcrateなら読める。 - rustc_resolve - rustc_hir - rustc_hir_typeck rustc_borrwckとかは割と複雑で難しい。
実際にissueに取り組 んでみる
実際にissueに取り組んでみる 今回は自分が過去に取り組んだ比較的シンプルなissueを参考に見てみます。 “consider dereferencing here” help doesn’t account for
operator precedence of the deref operator · Issue #105429 · rust-lang/rust
issueを見ると、下記のソースコードが与えられた時に、
このようなエラーが得られるとあります。(現時点では修正済み)
正しくないのはこの箇所です。
実際はこのようにdereferenceする必要があります。
検索したり-Zフラグを使ってエラーの発生箇所を特定してみると、 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L778
検索したり-Zフラグを使ってエラーの発生箇所を特定してみると、 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L778
やる必要があるのは、dereferenceする対象がmethodのreceiverの際に 特別なハンドリングをすること。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L778
何から始めたらいいか分からないと仮定してまず、spanに定義ジャンプしてみ る。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L778
ありました。これがspan。ObligationCauseのspanというfieldから取れるっ ぽい。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs
obligationはここでも使われてる。codeという概念があるらしい。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs
obligation.causeのなかにエラー発生箇所のspanなどの情報が詰められて そう?なことが分かる。 今回のissueではintoなのでargはありませ んが、これは引数のことっぽい。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs
obligation.causeのなかにエラー発生箇所のspanなどの情報が詰められて そう?なことが分かる。 また、hir_idというのが取れると、それがどう いうNodeかチェックできるっぽい ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs
このNode enumの定義を見てみる。 ref: rustc_trait_selection/src/traits/error_reporting/suggestions.rs
このNode enumの定義を見てみる。
このNode enumの定義を見てみる。
このNode enumの定義を見てみる。
さらにExpr structに飛んでみる。
Exprはkindを持ってるので、これでmethodのreceiverかどうか判別できる のでは?
でもarg_hir_idはあるが、対象のexprがmethod callで対象がその receiverかどうか判別できないとダメそう。 試しにFunctionArgumentObligationを見に行ってみる。
それっぽいのがあるので、いけそう!
ということでこの実装をcall_hir_idを使って修正してみる。
None
call_hir_idを元にexprがmethod callかど うか判別できた
あとはmethod callでかつ対象がそのreceiverの時だけ()で 囲ってdereferenceすればいい
実際にissueに取り組んでみる あとはUIテストを書いて全てのテストにパスすることを確認して、プルリクの完成 Suggest dereferencing receiver arguments properly by TaKO8Ki
· Pull Request #105595 · rust-lang/rust
まとめ
© Money Forward, Inc. まとめ • 基本は「Rust Compiler Development Guide」を読めば大体のことが分
かる。 • 下に下に掘り下げていけば割と読める。 • 分からないことはある程度推測しながら身につけていけば、全体像が見え なくても修正を加えたりできる。
We are hiring!
None