1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
//! I thought Rust doesn't have reflection...?
//! ==========================================
//!
//! *This crate explores what it could look like to tackle the 80% use case of
//! custom derive macros through a programming model that resembles compile-time
//! reflection.*
//!
//! # Motivation
//!
//! My existing [**`syn`**] and [**`quote`**] libraries approach the problem space
//! of procedural macros in a super general way and are a good fit for maybe 95% of
//! use cases. However, the generality comes with the cost of operating at a
//! relatively low level of abstraction. The macro author is responsible for the
//! placement of every single angle bracket, lifetime, type parameter, trait bound,
//! and phantom data. There is a large amount of domain knowledge involved and very
//! few people can reliably produce robust macros with this approach.
//!
//! The design explored here focuses on what it would take to make all the edge
//! cases disappear -- such that if your macro works for the most basic case, then
//! it also works in every tricky case under the sun.
//!
//! [**`syn`**]: https://github.com/dtolnay/syn
//! [**`quote`**]: https://github.com/dtolnay/quote
//!
//! # Programming model
//!
//! The idea is that we expose *what looks like* a boring straightforward [runtime
//! reflection] API such as you might recognize if you have used [reflection in
//! Java] or [reflection in Go].
//!
//! The macro author expresses the logic of their macro in terms of this API, using
//! types like `reflect::Value` to retrieve function arguments and access fields of
//! data structures and invoke functions and so forth. Importantly, there is no such
//! thing as a generic type or phantom data in this model. Everything is just a
//! `reflect::Value` with a type that is conceptually its monomorphized type at
//! runtime.
//!
//! Meanwhile the library is tracking the control flow and function invocations to
//! build up a fully general and robust procedural implementation of the author's
//! macro. The resulting code will have all the angle brackets and lifetimes and
//! bounds and phantom types in the right places without the macro author thinking
//! about any of that.
//!
//! The reflection API is *just* a means for defining a procedural macro. The
//! library boils it all away and emits clean Rust source code free of any actual
//! runtime reflection. Note that this is **not** a statement about compiler
//! optimizations -- we are not relying on the Rust compiler to do heroic
//! optimizations on shitty generated code. Literally the source code authored
//! through the reflection API will be what a seasoned macro author would have
//! produced simply using `syn` and `quote`.
//!
//! [runtime reflection]: https://en.wikipedia.org/wiki/Reflection_(computer_programming)
//! [reflection in Java]: https://docs.oracle.com/javase/tutorial/reflect/member/fieldValues.html
//! [reflection in Go]: https://blog.golang.org/laws-of-reflection
//!
//! # Demo
//!
//! This project contains a proof of concept of a compile-time reflection API for
//! defining custom derives.
//!
//! The [`tests/debug/`] directory demonstrates a working compilable implementation
//! of `#[derive(Debug)]` for structs with named fields.
//!
//! [`tests/debug/`]: https://github.com/dtolnay/reflect/blob/master/tests/debug/mod.rs
//!
//! We begin with a DSL declaration of the types and functions that will be required
//! at runtime. There may be additional `extern crate` blocks here if we need to use
//! types from outside the standard library. For example Serde's
//! `#[derive(Serialize)]` macro would want to list the `serde` crate, the
//! `Serialize` and `Serializer` types, and whichever of their methods will possibly
//! be invoked at runtime.
//!
//! ```
//! extern crate reflect;
//!
//! reflect::library! {
//!     extern crate std {
//!         mod fmt {
//!             type Formatter;
//!             type Result;
//!             type DebugStruct;
//!
//!             trait Debug {
//!                 fn fmt(&self, &mut Formatter) -> Result;
//!             }
//!
//!             impl Formatter {
//!                 fn debug_struct(&mut self, &str) -> DebugStruct;
//!             }
//!
//!             impl DebugStruct {
//!                 fn field(&mut self, &str, &Debug) -> &mut DebugStruct;
//!                 fn finish(&mut self) -> Result;
//!             }
//!         }
//!     }
//! }
//! #
//! # fn main() {}
//! ```
//!
//! Next, the macro entry point is an ordinary `proc_macro_derive` function just as
//! it would be for a derive macro defined any other way.
//!
//! Once again the reflection API is *just* a means for defining a procedural macro.
//! Despite what it may look like below, everything written here executes at compile
//! time. The `reflect` library spits out generated code in an output `TokenStream`
//! that is compiled into the macro user's crate. This token stream contains no
//! vestiges of runtime reflection.
//!
//! ```
//! # extern crate reflect;
//! #
//! # reflect::library! {
//! #     extern crate std {
//! #         mod fmt {
//! #             type Formatter;
//! #             type Result;
//! #
//! #             trait Debug {
//! #                 fn fmt(&self, &mut Formatter) -> Result;
//! #             }
//! #         }
//! #     }
//! # }
//! #
//! extern crate proc_macro;
//! use self::proc_macro::TokenStream;
//!
//! # macro_rules! ignore {
//! #     ($($tt:tt)*) => {};
//! # }
//! # ignore! {
//! #[proc_macro_derive(MyDebug)]
//! # }
//! pub fn derive(input: TokenStream) -> TokenStream {
//!     reflect::derive(input, |ex| {
//!         ex.make_trait_impl(RUNTIME::std::fmt::Debug, ex.target_type(), |block| {
//!             block.make_function(RUNTIME::std::fmt::Debug::fmt, debug_fmt);
//!         });
//!     })
//! }
//! #
//! # fn debug_fmt(f: reflect::MakeFunction) -> reflect::Value {
//! #     unimplemented!()
//! # }
//! #
//! # fn main() {}
//! ```
//!
//! The following looks like a function that does runtime reflection. It receives
//! function arguments which have the type `reflect::Value` and can pass them
//! around, pull out their fields, inspect attributes, invoke methods, and so forth.
//!
//! ```
//! use reflect::*;
//!
//! fn debug_fmt(f: MakeFunction) -> Value {
//!     let receiver = f.arg(0);
//!     let formatter = f.arg(1);
//!
//!     match receiver.data() {
//!         Data::Struct(receiver) => match receiver {
//!             Struct::Unit(receiver) => unimplemented!(),
//!             Struct::Tuple(receiver) => unimplemented!(),
//!             Struct::Struct(receiver) => {
//!                 /* implemented below */
//! # unimplemented!()
//!             }
//!         },
//!         Data::Enum(receiver) => receiver.match_variant(|variant| match variant {
//!             Variant::Unit(variant) => unimplemented!(),
//!             Variant::Tuple(variant) => unimplemented!(),
//!             Variant::Struct(variant) => unimplemented!(),
//!         }),
//!     }
//! }
//! ```
//!
//! In the case of a struct with named fields we use reflection to loop over fields
//! of the struct and invoke methods of the standard library `Formatter` API to
//! append each field value into the debug output.
//!
//! Refer to the [`DebugStruct`] example code in the standard library API
//! documentation for what this is supposed to do at runtime.
//!
//! Paths beginning with `RUNTIME::` refer to library signatures declared by the
//! `library! { ... }` snippet above.
//!
//! [`DebugStruct`]: https://doc.rust-lang.org/std/fmt/struct.DebugStruct.html
//!
//! ```
//! # extern crate reflect;
//! #
//! # use reflect::*;
//! #
//! # reflect::library! {
//! #     extern crate std {
//! #         mod fmt {
//! #             type Formatter;
//! #             type Result;
//! #             type DebugStruct;
//! #
//! #             trait Debug {
//! #                 fn fmt(&self, &mut Formatter) -> Result;
//! #             }
//! #
//! #             impl Formatter {
//! #                 fn debug_struct(&mut self, &str) -> DebugStruct;
//! #             }
//! #
//! #             impl DebugStruct {
//! #                 fn field(&mut self, &str, &Debug) -> &mut DebugStruct;
//! #                 fn finish(&mut self) -> Result;
//! #             }
//! #         }
//! #     }
//! # }
//! #
//! # fn debug_fmt<'a>(
//! #     receiver: StructStruct<Value>,
//! #     formatter: Value,
//! #     type_name: Value,
//! # ) -> Value {
//! let builder = RUNTIME::std::fmt::Formatter::debug_struct
//!     .INVOKE(formatter, type_name)
//!     .reference_mut();
//!
//! for field in receiver.fields() {
//!     RUNTIME::std::fmt::DebugStruct::field.INVOKE(
//!         builder,
//!         field.get_name(),
//!         field.get_value(),
//!     );
//! }
//!
//! RUNTIME::std::fmt::DebugStruct::finish.INVOKE(builder)
//! # }
//! #
//! # fn main() {}
//! ```
//!
//! # Robustness and how things go wrong
//!
//! I mentioned above about how implementing robust macros simply using `syn` and
//! `quote` is quite challenging.
//!
//! The example I like to use is taking a single struct field and temporarily
//! wrapping it in a new struct. This is a real life use case drawn from how
//! `serde_derive` handles `serialize_with` attributes. Conceptually:
//!
//! ```
//! # macro_rules! ignore {
//! #     ($($tt:tt)*) => {}
//! # }
//! #
//! # ignore! {
//! let input: DeriveInput = syn::parse(...).unwrap();
//!
//! // Pull out one of the field types.
//! let type_of_field_x: syn::Type = /* ... */;
//!
//! quote! {
//!     // Very not robust.
//!     struct Wrapper<'a> {
//!         x: &'a #type_of_field_x,
//!     }
//!
//!     Wrapper { x: &self.x }
//! }
//! # }
//! ```
//!
//! Making the `quote!` part of this simply generate compilable code for all
//! possible values of `type_of_field_x` is extremely involved. The macro author
//! needs to consider and handle all of the following in order to make this work
//! reliably:
//!
//! - Lifetime parameters used by `type_of_field_x`,
//! - Type parameters used by `type_of_field_x`,
//! - Associated types used by `type_of_field_x`,
//! - Where-clauses on `input` that constrain any of the above,
//! - Similarly, trait bounds on type parameters of `input`,
//! - Where-clauses or bounds affecting any *other* fields of `input`,
//! - Type parameter defaults on `input` that need to be stripped.
//!
//! In contrast, the `reflect` library will be able to get it right every single
//! time with much less thought from the macro author. Possibly as trivial as:
//!
//! ```
//! # macro_rules! ignore {
//! #     ($($tt:tt)*) => {}
//! # }
//! #
//! # ignore! {
//! let wrapper: reflect::Type = reflect::new_struct_type();
//!
//! wrapper.instantiate(vec![input.get_field("x").reference()])
//! # }
//! ```
//!
//! # Remaining work
//!
//! In its current state the proof of concept generates just barely working code for
//! our simple `Debug` derive. The `reflect` library needs more work to produce
//! robust code in the presence of lifetimes and generic parameters, and for library
//! signatures involving more complicated types.
//!
//! Crucially all remaining work should happen without touching the code of our
//! `Debug` derive. The promise of `reflect` is that if the macro works for the most
//! basic cases (which the code above already does) then it also works in all the
//! edge cases. From here it is `reflect`'s responsibility to compile the dead
//! simple reflection-like `reflect::Value` object manipulations into a fully
//! general and robust procedural macro.

#![doc(html_root_url = "https://docs.rs/reflect/0.0.9")]
#![allow(unused_variables, dead_code)]
#![allow(
    clippy::enum_glob_use,
    clippy::for_loops_over_fallibles,
    clippy::items_after_statements,
    clippy::large_enum_variant,
    clippy::manual_assert,
    clippy::match_same_arms,
    clippy::missing_panics_doc,
    clippy::module_name_repetitions,
    clippy::must_use_candidate,
    clippy::needless_pass_by_value,
    clippy::new_without_default,
    clippy::return_self_not_must_use,
    clippy::trivially_copy_pass_by_ref,
    clippy::unused_self,
    clippy::wildcard_imports
)]

#[doc(hidden)]
pub use reflect_internal::*;

pub mod runtime;

mod attr;
mod compiler;
mod data;
mod derive;
mod execution;
mod field;
mod function;
mod generics;
mod ident;
mod index;
mod map;
mod module;
mod node;
mod path;
mod print;
mod signature;
mod ty;
mod value;
mod wip;

pub use crate::data::{
    Data, Enum, Struct, StructStruct, StructVariant, TupleStruct, TupleVariant, UnitStruct,
    UnitVariant, Variant,
};
pub use crate::derive::derive;
pub use crate::execution::Execution;
pub use crate::field::{Field, Fields};
pub use crate::function::Function;
pub use crate::generics::{GenericArguments, Generics};
pub use crate::module::Module;
pub use crate::path::Path;
pub use crate::signature::Signature;
pub use crate::ty::Type;
pub use crate::value::Value;
pub use crate::wip::{MakeFunction, MakeImpl};

use crate::compiler::{CompleteFunction, CompleteImpl, Program};
use crate::execution::{StaticBorrow, Tracker, WIP};
use crate::field::Accessor;
use crate::generics::{
    GenericArgument, GenericConstraint, GenericParam, Lifetime, TraitBound, TypeParamBound,
};
use crate::ident::Ident;
use crate::index::{InvokeRef, MacroInvokeRef, Push, ValueRef};
use crate::node::ValueNode;
use crate::print::Print;
use crate::runtime::{RuntimeFunction, RuntimeType};
use crate::signature::Receiver;
use crate::ty::TypeNode;
use crate::wip::{Invoke, MacroInvoke, WipFunction, WipImpl};