1+ <!--
12# Or patterns in macro-rules
3+ -->
24
5+ # マクロ規則における OR パターン
6+
7+ <!--
38## Summary
9+ -->
10+
11+ ## 概要
412
13+ <!--
514- How patterns work in `macro_rules` macros changes slightly:
615 - `$_:pat` in `macro_rules` now matches usage of `|` too: e.g. `A | B`.
716 - The new `$_:pat_param` behaves like `$_:pat` did before; it does not match (top level) `|`.
817 - `$_:pat_param` is available in all editions.
18+ -->
19+
20+ - ` macro_rules ` におけるパターンの挙動がほんの少し変更されました:
21+ - `macro_rules` において、`$_:pat` で `|` を使ったパターンにもマッチするようになりました。例えば、`A | B` にマッチします。
22+ - 新しく導入された `$_:pat_param` は、かつての `$_:pat` と同じ挙動を再現します。すなわち、こちらは(トップレベルの)`|` にはマッチしません。
23+ - `$_:pat_param` は全てのエディションで使用可能です。
24+
925
26+
27+ <!--
1028## Details
29+ -->
30+
31+ ## 詳細
1132
33+ <!--
1234Starting in Rust 1.53.0, [patterns](https://doc.rust-lang.org/stable/reference/patterns.html)
1335are extended to support `|` nested anywhere in the pattern.
1436This enables you to write `Some(1 | 2)` instead of `Some(1) | Some(2)`.
1537Since this was simply not allowed before, this is not a breaking change.
38+ -->
1639
40+ Rust 1.53.0 から、[ パターン] ( https://doc.rust-lang.org/stable/reference/patterns.html ) 中のどこでも、` | ` をネストして使えるようになりました。
41+ これにより、` Some(1) | Some(2) ` でなく ` Some(1 | 2) ` と書くことができるようになりました。
42+ 今まではこうは書けなかったので、これは破壊的変更ではありません。
43+
44+ <!--
1745However, this change also affects [`macro_rules` macros](https://doc.rust-lang.org/stable/reference/macros-by-example.html).
1846Such macros can accept patterns using the `:pat` fragment specifier.
1947Currently, `:pat` does *not* match top level `|`, since before Rust 1.53,
2048not all patterns (at all nested levels) could contain a `|`.
2149Macros that accept patterns like `A | B`,
2250such as [`matches!()`](https://doc.rust-lang.org/1.51.0/std/macro.matches.html)
2351use something like `$($_:pat)|+`.
52+ -->
53+
54+ ところが、この変更は [ ` macro_rules ` マクロ] ( https://doc.rust-lang.org/stable/reference/macros-by-example.html ) にも影響します。
55+ ` macro_rules ` では、` :pat ` というフラグメント指定子で、パターンを受け付けることができます。
56+ 現在のところ、` :pat ` はトップレベルの ` | ` にマッチ* しません* 。
57+ なぜなら Rust 1.53 以前は、全てのパターンが(どのネストレベルにでも)` | ` を含むことができるわけではなかったからです。
58+ [ ` matches!() ` ] ( https://doc.rust-lang.org/1.51.0/std/macro.matches.html ) のように、
59+ ` A | B ` のようなパターンを受け付けるマクロを書くには、
60+ ` $($_:pat)|+ ` のような書き方をしなくてはなりませんでした。
2461
62+ <!--
2563Because this would potentially break existing macros, the meaning of `:pat` did
2664not change in Rust 1.53.0 to include `|`. Instead, that change happens in Rust 2021.
2765In the new edition, the `:pat` fragment specifier *will* match `A | B`.
66+ -->
2867
68+ 既存のマクロを壊す可能性があるため、Rust 1.53.0 では ` :pat ` が ` | ` を含むことができるようには変更されませんでした。
69+ 代わりに、Rust 2021 で変更がなされました。
70+ 新しいエディションでは、` :pat ` フラグメント指定子は ` A | B ` にマッチ* します* 。
71+
72+ <!--
2973`$_:pat` fragments in Rust 2021 cannot be followed by an explicit `|`. Since there are times
3074that one still wishes to match pattern fragments followed by a `|`, the fragment specified `:pat_param`
3175has been added to retain the older behavior.
76+ -->
77+
78+ Rust 2021 では、` $_:pat ` フラグメントに ` | ` そのものが後続することはできません。
79+ パターンフラグメントに ` | ` が後続するものにマッチさせたいような場合は、新しく追加された ` :pat_param ` が過去と同じ挙動を示すようになっています。
3280
81+ <!--
3382It's important to remember that editions are _per crate_, so the only relevant edition is the edition
3483of the crate where the macro is defined. The edition of the crate where the macro is used does not
3584change how the macro works.
85+ -->
3686
87+ ただし、エディションは<!-- --> _ クレートごとに_ <!-- --> 設定されることに注意してください。
88+ つまり、マクロが定義されているクレートのエディションだけが関係します。
89+ マクロを使用する方のクレートのエディションは、マクロの挙動に影響しません。
90+
91+ <!--
3792## Migration
93+ -->
94+
95+ ## 移行
3896
97+ <!--
3998A lint, `rust_2021_incompatible_or_patterns`, gets triggered whenever there is a use `$_:pat` which
4099will change meaning in Rust 2021.
100+ -->
41101
102+ ` $_:pat ` が使われている場所のうち、Rust 2021 で意味が変わるようなものに対しては、` rust_2021_incompatible_or_patterns ` というリントが発生します。
103+
104+ <!--
42105You can automatically migrate your code to be Rust 2021 Edition compatible or ensure it is already compatible by
43106running:
107+ -->
108+
109+ コードを自動的に Rust 2021 エディションに適合するよう自動移行するか、既に適合するものであることを確認するためには、以下のように実行すればよいです:
44110
45111``` sh
46112cargo fix --edition
47113```
48114
115+ <!--
49116If you have a macro which relies on `$_:pat` not matching the top level use of `|` in patterns,
50117you'll need to change each occurrence of `$_:pat` to `$_:pat_param`.
118+ -->
119+
120+ あなたのマクロが、` $_:pat ` がトップレベルの ` | ` にマッチしないという挙動に依存している場合は、
121+ ` $_:pat ` を ` $_:pat_param ` に書き換える必要があります。
51122
123+ <!--
52124For example:
125+ -->
53126
127+ 例えば以下のようになります。
128+
129+ <!--
54130```rust
55131macro_rules! my_macro {
56132 ($x:pat | $y:pat) => {
@@ -69,4 +145,25 @@ macro_rules! my_macro {
69145 // TODO: implementation
70146 }
71147}
72- ```
148+ ```
149+ -->
150+
151+ ``` rust
152+ macro_rules! my_macro {
153+ ($ x : pat | $ y : pat ) => {
154+ // TODO: 実装
155+ }
156+ }
157+
158+ // Rust 2018 では、`$x:pat` が `|` にマッチしないので、以下のマクロは正常に動きます:
159+ my_macro! (1 | 2 );
160+
161+ // 一方 Rust 2021 では、`$_:pat` フラグメントは `|` にもマッチし、
162+ // `|` が後続してはいけなくなりました。
163+ // Rust 2021 でもマクロが動作するためには、マクロを以下のように変更しなくてはなりません:
164+ macro_rules! my_macro {
165+ ($ x : pat_param | $ y : pat ) => { // <- この行を変えた
166+ // TODO: 実装
167+ }
168+ }
169+ ```
0 commit comments