Files
google-apis-rs/proc_macro_hack/index.html
2021-04-02 00:20:57 +08:00

110 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="API documentation for the Rust `proc_macro_hack` crate."><meta name="keywords" content="rust, rustlang, rust-lang, proc_macro_hack"><title>proc_macro_hack - Rust</title><link rel="stylesheet" type="text/css" href="../normalize.css"><link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../ayu.css" disabled ><script id="default-settings"></script><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../favicon.svg">
<link rel="alternate icon" type="image/png" href="../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../proc_macro_hack/index.html'><div class='logo-container rust-logo'><img src='../rust-logo.png' alt='logo'></div></a><p class="location">Crate proc_macro_hack</p><div class="block version"><p>Version 0.5.19</p></div><div class="sidebar-elems"><a id="all-types" href="all.html"><p>See all proc_macro_hack's items</p></a><p class="location"></p><div id="sidebar-vars" data-name="proc_macro_hack" data-ty="mod" data-relpath="../"></div></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<a id="settings-menu" href="../settings.html"><img src="../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class="fqn"><span class="in-band">Crate <a class="mod" href="">proc_macro_hack</a></span><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span><a class="srclink" href="../src/proc_macro_hack/lib.rs.html#1-591" title="goto source code">[src]</a></span></h1><div class="docblock"><p><a href="https://github.com/dtolnay/proc-macro-hack"><img src="https://img.shields.io/badge/github-8da0cb?style=for-the-badge&amp;labelColor=555555&amp;logo=github" alt="github" /></a><a href="https://crates.io/crates/proc-macro-hack"><img src="https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&amp;labelColor=555555&amp;logo=rust" alt="crates-io" /></a><a href="https://docs.rs/proc-macro-hack"><img src="https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&amp;labelColor=555555&amp;logoColor=white&amp;logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" alt="docs-rs" /></a></p>
<br>
<table><tr><td><hr>
<b>Note:</b> <i>As of Rust 1.45 this crate is superseded by native support
for #[proc_macro] in expression position. Only consider using this crate if
you care about supporting compilers between 1.31 and 1.45.</i>
<hr></td></tr></table>
<p>Since Rust 1.30, the language supports user-defined function-like procedural
macros. However these can only be invoked in item position, not in
statements or expressions.</p>
<p>This crate implements an alternative type of procedural macro that can be
invoked in statement or expression position.</p>
<h1 id="defining-procedural-macros" class="section-header"><a href="#defining-procedural-macros">Defining procedural macros</a></h1>
<p>Two crates are required to define a procedural macro.</p>
<h2 id="the-implementation-crate" class="section-header"><a href="#the-implementation-crate">The implementation crate</a></h2>
<p>This crate must contain nothing but procedural macros. Private helper
functions and private modules are fine but nothing can be public.</p>
<p><a href="https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack-impl">» example of an implementation crate</a></p>
<p>Just like you would use a #[proc_macro] attribute to define a natively
supported procedural macro, use proc-macro-hack's #[proc_macro_hack]
attribute to define a procedural macro that works in expression position.
The function signature is the same as for ordinary function-like procedural
macros.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">proc_macro</span>::<span class="ident">TokenStream</span>;
<span class="kw">use</span> <span class="ident">proc_macro_hack</span>::<span class="ident">proc_macro_hack</span>;
<span class="kw">use</span> <span class="ident">quote</span>::<span class="ident">quote</span>;
<span class="kw">use</span> <span class="ident">syn</span>::{<span class="ident">parse_macro_input</span>, <span class="ident">Expr</span>};
<span class="attribute">#[<span class="ident">proc_macro_hack</span>]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">add_one</span>(<span class="ident">input</span>: <span class="ident">TokenStream</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">TokenStream</span> {
<span class="kw">let</span> <span class="ident">expr</span> <span class="op">=</span> <span class="macro">parse_macro_input</span><span class="macro">!</span>(<span class="ident">input</span> <span class="kw">as</span> <span class="ident">Expr</span>);
<span class="ident">TokenStream</span>::<span class="ident">from</span>(<span class="macro">quote</span><span class="macro">!</span> {
<span class="number">1</span> <span class="op">+</span> (#<span class="ident">expr</span>)
})
}</pre></div>
<h2 id="the-declaration-crate" class="section-header"><a href="#the-declaration-crate">The declaration crate</a></h2>
<p>This crate is allowed to contain other public things if you need, for
example traits or functions or ordinary macros.</p>
<p><a href="https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack">» example of a declaration crate</a></p>
<p>Within the declaration crate there needs to be a re-export of your
procedural macro from the implementation crate. The re-export also carries a
#[proc_macro_hack] attribute.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">proc_macro_hack</span>::<span class="ident">proc_macro_hack</span>;
<span class="doccomment">/// Add one to an expression.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// (Documentation goes here on the re-export, not in the other crate.)</span>
<span class="attribute">#[<span class="ident">proc_macro_hack</span>]</span>
<span class="kw">pub</span> <span class="kw">use</span> <span class="ident">demo_hack_impl</span>::<span class="ident">add_one</span>;</pre></div>
<p>Both crates depend on <code>proc-macro-hack</code>:</p>
<pre><code class="language-toml">[dependencies]
proc-macro-hack = &quot;0.5&quot;
</code></pre>
<p>Additionally, your implementation crate (but not your declaration crate) is
a proc macro crate:</p>
<pre><code class="language-toml">[lib]
proc-macro = true
</code></pre>
<h1 id="using-procedural-macros" class="section-header"><a href="#using-procedural-macros">Using procedural macros</a></h1>
<p>Users of your crate depend on your declaration crate (not your
implementation crate), then use your procedural macros as usual.</p>
<p><a href="https://github.com/dtolnay/proc-macro-hack/tree/master/example">» example of a downstream crate</a></p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">demo_hack</span>::<span class="ident">add_one</span>;
<span class="kw">fn</span> <span class="ident">main</span>() {
<span class="kw">let</span> <span class="ident">two</span> <span class="op">=</span> <span class="number">2</span>;
<span class="kw">let</span> <span class="ident">nine</span> <span class="op">=</span> <span class="macro">add_one</span><span class="macro">!</span>(<span class="ident">two</span>) <span class="op">+</span> <span class="macro">add_one</span><span class="macro">!</span>(<span class="number">2</span> <span class="op">+</span> <span class="number">3</span>);
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;nine = {}&quot;</span>, <span class="ident">nine</span>);
}</pre></div>
<h1 id="limitations" class="section-header"><a href="#limitations">Limitations</a></h1>
<ul>
<li>
<p>Only proc macros in expression position are supported. Proc macros in
pattern position (<a href="https://github.com/dtolnay/proc-macro-hack/issues/20">#20</a>) are not supported.</p>
</li>
<li>
<p>By default, nested invocations are not supported i.e. the code emitted by
a proc-macro-hack macro invocation cannot contain recursive calls to the
same proc-macro-hack macro nor calls to any other proc-macro-hack macros.
Use <a href="https://docs.rs/proc-macro-nested"><code>proc-macro-nested</code></a> if you require support for nested invocations.</p>
</li>
<li>
<p>By default, hygiene is structured such that the expanded code can't refer
to local variables other than those passed by name somewhere in the macro
input. If your macro must refer to <em>local</em> variables that don't get named
in the macro input, use <code>#[proc_macro_hack(fake_call_site)]</code> on the
re-export in your declaration crate. <em>Most macros won't need this.</em></p>
</li>
<li>
<p>On compilers that are new enough to natively support proc macros in
expression position, proc-macro-hack does not automatically use that
support, since the hygiene can be subtly different between the two
implementations. To opt in to compiling your macro to native
<code>#[proc_macro]</code> on sufficiently new compilers, use
<code>#[proc_macro_hack(only_hack_old_rustc)]</code> on the re-export in your
declaration crate.</p>
</li>
</ul>
</div><h2 id="attributes" class="section-header"><a href="#attributes">Attribute Macros</a></h2>
<table><tr class="module-item"><td><a class="attr" href="attr.proc_macro_hack.html" title="proc_macro_hack::proc_macro_hack attr">proc_macro_hack</a></td><td class="docblock-short"></td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../" data-current-crate="proc_macro_hack"></div>
<script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>