aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/posts/2021-10-02/rust-where-are-primitive-types-from
diff options
context:
space:
mode:
Diffstat (limited to 'public/posts/2021-10-02/rust-where-are-primitive-types-from')
-rw-r--r--public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html36
1 files changed, 12 insertions, 24 deletions
diff --git a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
index 8bcb923..5b1f86a 100644
--- a/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
+++ b/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html
@@ -55,8 +55,7 @@
Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。
</p>
- <pre class="highlight" language="rust" linenumbering="unnumbered">
- <code>#![allow(non_camel_case_types)]
+ <pre class="highlight" language="rust" linenumbering="unnumbered"><code>#![allow(non_camel_case_types)]
#![allow(dead_code)]
struct bool;
@@ -75,8 +74,7 @@ struct u128;
struct usize;
struct f32;
struct f64;
-struct str;</code>
- </pre>
+struct str;</code></pre>
<p>
では、普段単に<code>bool</code>と書いたとき、この<code>bool</code>は一体どこから来ているのか。rustc のソースを追ってみた。
@@ -111,34 +109,29 @@ struct str;</code>
<code>rustc</code>はセルフホストされている (=<code>rustc</code>自身が Rust で書かれている) ので、<code>bool</code>や<code>char</code>などで適当に検索をかけてもノイズが多すぎて話にならない。 しかし、お誂え向きなことに<code>i128</code>/<code>u128</code>というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って<code>git grep</code>してみる。
</p>
- <pre class="monospaced highlight">
- <code>$ git grep &quot;\bi128\b&quot; | wc # i128
+ <pre class="monospaced highlight"><code>$ git grep &quot;\bi128\b&quot; | wc # i128
165 1069 15790
$ git grep &quot;\bu128\b&quot; | wc # u128
293 2127 26667
$ git grep &quot;\bbool\b&quot; | wc # cf. bool の結果
-3563 23577 294659</code>
- </pre>
+3563 23577 294659</code></pre>
<p>
165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。
</p>
- <pre class="monospaced highlight">
- <code>$ git grep &quot;\bi128\b&quot;
+ <pre class="monospaced highlight"><code>$ git grep &quot;\bi128\b&quot;
...
rustc_resolve/src/lib.rs: table.insert(sym::i128, Int(IntTy::I128));
-...</code>
- </pre>
+...</code></pre>
<p>
<code>rustc_resolve</code>というのはいかにも名前解決を担いそうなクレート名である。該当箇所を見てみる。
</p>
- <pre class="highlight" language="rust" linenumbering="unnumbered">
- <code>/// Interns the names of the primitive types.
+ <pre class="highlight" language="rust" linenumbering="unnumbered"><code>/// Interns the names of the primitive types.
///
/// All other types are defined somewhere and possibly imported, but the primitive ones need
/// special handling, since they have no place of origin.
@@ -169,8 +162,7 @@ table.insert(sym::u64, Uint(UintTy::U64));
table.insert(sym::u128, Uint(UintTy::U128));
Self { primitive_types: table }
}
-}</code>
- </pre>
+}</code></pre>
<p>
これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、
@@ -186,8 +178,7 @@ Self { primitive_types: table }
とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。
</p>
- <pre class="highlight" language="rust" linenumbering="unnumbered">
- <code> /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
+ <pre class="highlight" language="rust" linenumbering="unnumbered"><code> /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
/// (略)
fn resolve_ident_in_lexical_scope(
&amp;mut self,
@@ -207,8 +198,7 @@ return Some(LexicalScopeBinding::Item(binding));
}
None
-}</code>
- </pre>
+}</code></pre>
<p>
関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。<code>if ns == TypeNS</code>のブロック内では、<code>primitive_type_table</code>(上記の<code>PrimitiveTypeTable::new()</code>で作られた変数) に含まれている識別子 (<code>bool</code>、<code>i32</code>など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。
@@ -226,15 +216,13 @@ None
動作がわかったところで、例として次のコードを考える。
</p>
- <pre class="highlight" language="rust" linenumbering="unnumbered">
- <code>#![allow(non_camel_case_types)]
+ <pre class="highlight" language="rust" linenumbering="unnumbered"><code>#![allow(non_camel_case_types)]
struct bool;
fn main() {
let _: bool = bool;
-}</code>
- </pre>
+}</code></pre>
<p>
ここで<code>main()</code>の<code>bool</code>は<code>struct bool</code>として解決される。なぜなら、プリミティブ型の判定をする前に<code>bool</code>という名前の別の型が見つかるからだ。