Files
mercator_service/proc_macro_hack/index.html

92 lines
9.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
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="../dark.css"><link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle"><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="shortcut icon" href="../favicon.ico"><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'><img src='../rust-logo.png' alt='logo'></div></a><p class='location'>Crate proc_macro_hack</p><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><script>window.sidebarCurrent = {name: 'proc_macro_hack', ty: 'mod', relpath: '../'};</script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></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><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='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-498' title='goto source code'>[src]</a></span><span class='in-band'>Crate <a class="mod" href=''>proc_macro_hack</a></span></h1><div class='docblock'><p>As of 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">&gt; 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">extern</span> <span class="kw">crate</span> <span class="ident">proc_macro</span>;
<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">&gt; 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">&gt; 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>
</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><script>window.rootPath = "../";window.currentCrate = "proc_macro_hack";</script><script src="../aliases.js"></script><script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>