You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- librustc_span/hygiene.rs - structures related to hygiene and expansion that are kept in global data (can be accessed from any Ident without any context)
242
+
- librustc_span/lib.rs - some secondary methods like macro backtrace using primary methods from hygiene.rs
243
+
- librustc_builtin_macros - implementations of built-in macros (including macro attributes and derives) and some other early code generation facilities like injection of standard library imports or generation of test harness.
244
+
- librustc_ast/config.rs - implementation of cfg/cfg_attr (they treated specially from other macros), should probably be moved into librustc_ast/ext.
245
+
- librustc_ast/tokenstream.rs + librustc_ast/parse/token.rs - structures for compiler-side tokens, token trees, and token streams.
246
+
- librustc_ast/ext - various expansion-related stuff
247
+
- librustc_ast/ext/base.rs - basic structures used by expansion
248
+
- librustc_ast/ext/expand.rs - some expansion structures and the bulk of expansion infrastructure code - collecting macro invocations, calling into resolve for them, calling their expanding functions, and integrating the results back into AST
249
+
- librustc_ast/ext/placeholder.rs - the part of expand.rs responsible for "integrating the results back into AST" basicallly, "placeholder" is a temporary AST node replaced with macro expansion result nodes
250
+
- librustc_ast/ext/builer.rs - helper functions for building AST for built-in macros in librustc_builtin_macros (and user-defined syntactic plugins previously), can probably be moved into librustc_builtin_macros these days
251
+
- librustc_ast/ext/proc_macro.rs + librustc_ast/ext/proc_macro_server.rs - interfaces between the compiler and the stable proc_macro library, converting tokens and token streams between the two representations and sending them through C ABI
252
+
- librustc_ast/ext/tt - implementation of macro_rules, turns macro_rules DSL into something with signature Fn(TokenStream) -> TokenStream that can eat and produce tokens, @mark-i-m knows more about this
253
+
- librustc_resolve/macros.rs - resolving macro paths, validating those resolutions, reporting various "not found"/"found, but it's unstable"/"expected x, found y" errors
254
+
- librustc_middle/hir/map/def_collector.rs + librustc_resolve/build_reduced_graph.rs - integrate an AST fragment freshly expanded from a macro into various parent/child structures like module hierarchy or "definition paths"
255
+
256
+
Primary structures:
257
+
- HygieneData - global piece of data containing hygiene and expansion info that can be accessed from any Ident without any context
258
+
- ExpnId - ID of a macro call or desugaring (and also expansion of that call/desugaring, depending on context)
259
+
- ExpnInfo/InternalExpnData - a subset of properties from both macro definition and macro call available through global data
260
+
- SyntaxContext - ID of a chain of nested macro definitions (identified by ExpnIds)
261
+
- SyntaxContextData - data associated with the given SyntaxContext, mostly a cache for results of filtering that chain in different ways
262
+
- Span - a code location + SyntaxContext
263
+
- Ident - interned string (Symbol) + Span, i.e. a string with attached hygiene data
264
+
- TokenStream - a collection of TokenTrees
265
+
- TokenTree - a token (punctuation, identifier, or literal) or a delimited group (anything inside ()/[]/{})
266
+
- SyntaxExtension - a lowered macro representation, contains its expander function transforming a tokenstream or AST into tokenstream or AST + some additional data like stability, or a list of unstable features allowed inside the macro.
267
+
- SyntaxExtensionKind - expander functions may have several different signatures (take one token stream, or two, or a piece of AST, etc), this is an enum that lists them
268
+
- ProcMacro/TTMacroExpander/AttrProcMacro/MultiItemModifier - traits representing the expander signatures (TODO: change and rename the signatures into something more consistent)
269
+
- Resolver - a trait used to break crate dependencies (so resolver services can be used in librustc_ast, despite librustc_resolve and pretty much everything else depending on librustc_ast)
270
+
- ExtCtxt/ExpansionData - various intermediate data kept and used by expansion infra in the process of its work
271
+
- AstFragment - a piece of AST that can be produced by a macro (may include multiple homogeneous AST nodes, like e.g. a list of items)
272
+
- Annotatable - a piece of AST that can be an attribute target, almost same thing as AstFragment except for types and patterns that can be produced by macros but cannot be annotated with attributes (TODO: Merge into AstFragment)
273
+
- MacResult - a "polymorphic" AST fragment, something that can turn into a different AstFragment depending on its context (aka AstFragmentKind - item, or expression, or pattern etc.)
274
+
- Invocation/InvocationKind - a structure describing a macro call, these structures are collected by the expansion infra (InvocationCollector), queued, resolved, expanded when resolved, etc.
275
+
276
+
TODO: how a crate transitions from the state "macros exist as written in source" to "all macros are expanded"
277
+
278
+
Expansion Heirarchies and Syntax Context
279
+
- Many AST nodes have some sort of syntax context, especially nodes from macros. The context consists of a chain of expansions leading to `ExpnId::root`. A non-macro-expanded node has syntax context 0 (`SyntaxContext::empty()`) which represents just the root node.
280
+
- There are 3 expansion heirarchies
281
+
- They all start at ExpnId::root, which is its own parent
282
+
283
+
284
+
285
+
286
+
287
+
239
288
240
289
# Discussion about hygiene
241
290
242
-
The rest of this chapter is a dump of a discussion between `mark-i-m` and
243
-
`petrochenkov` about Macro Expansion and Hygiene. I am pasting it here so that
244
-
it never gets lost until we can make it into a proper chapter.
245
291
246
292
```txt
247
293
248
-
Vadim Petrochenkov: Here's some preliminary data I prepared.
249
-
250
-
Vadim Petrochenkov: Below I'll assume #62771 and #62086 has landed.
251
-
252
-
Vadim Petrochenkov: Where to find the code: librustc_span/hygiene.rs -
253
-
structures related to hygiene and expansion that are kept in global data (can
254
-
be accessed from any Ident without any context) librustc_span/lib.rs - some
255
-
secondary methods like macro backtrace using primary methods from hygiene.rs
256
-
librustc_builtin_macros - implementations of built-in macros (including macro attributes
257
-
and derives) and some other early code generation facilities like injection of
258
-
standard library imports or generation of test harness. librustc_ast/config.rs -
259
-
implementation of cfg/cfg_attr (they treated specially from other macros),
260
-
should probably be moved into librustc_ast/ext. librustc_ast/tokenstream.rs +
261
-
librustc_ast/parse/token.rs - structures for compiler-side tokens, token trees,
262
-
and token streams. librustc_ast/ext - various expansion-related stuff
263
-
librustc_ast/ext/base.rs - basic structures used by expansion
264
-
librustc_ast/ext/expand.rs - some expansion structures and the bulk of expansion
265
-
infrastructure code - collecting macro invocations, calling into resolve for
266
-
them, calling their expanding functions, and integrating the results back into
267
-
AST librustc_ast/ext/placeholder.rs - the part of expand.rs responsible for
268
-
"integrating the results back into AST" basicallly, "placeholder" is a
269
-
temporary AST node replaced with macro expansion result nodes
270
-
librustc_ast/ext/builer.rs - helper functions for building AST for built-in macros
271
-
in librustc_builtin_macros (and user-defined syntactic plugins previously), can probably
272
-
be moved into librustc_builtin_macros these days librustc_ast/ext/proc_macro.rs +
273
-
librustc_ast/ext/proc_macro_server.rs - interfaces between the compiler and the
274
-
stable proc_macro library, converting tokens and token streams between the two
275
-
representations and sending them through C ABI librustc_ast/ext/tt -
276
-
implementation of macro_rules, turns macro_rules DSL into something with
277
-
signature Fn(TokenStream) -> TokenStream that can eat and produce tokens,
278
-
@mark-i-m knows more about this librustc_resolve/macros.rs - resolving macro
279
-
paths, validating those resolutions, reporting various "not found"/"found, but
280
-
it's unstable"/"expected x, found y" errors librustc_middle/hir/map/def_collector.rs +
281
-
librustc_resolve/build_reduced_graph.rs - integrate an AST fragment freshly
282
-
expanded from a macro into various parent/child structures like module
283
-
hierarchy or "definition paths"
284
-
285
-
Primary structures: HygieneData - global piece of data containing hygiene and
286
-
expansion info that can be accessed from any Ident without any context ExpnId -
287
-
ID of a macro call or desugaring (and also expansion of that call/desugaring,
288
-
depending on context) ExpnInfo/InternalExpnData - a subset of properties from
289
-
both macro definition and macro call available through global data
290
-
SyntaxContext - ID of a chain of nested macro definitions (identified by
291
-
ExpnIds) SyntaxContextData - data associated with the given SyntaxContext,
292
-
mostly a cache for results of filtering that chain in different ways Span - a
293
-
code location + SyntaxContext Ident - interned string (Symbol) + Span, i.e. a
294
-
string with attached hygiene data TokenStream - a collection of TokenTrees
295
-
TokenTree - a token (punctuation, identifier, or literal) or a delimited group
296
-
(anything inside ()/[]/{}) SyntaxExtension - a lowered macro representation,
297
-
contains its expander function transforming a tokenstream or AST into
298
-
tokenstream or AST + some additional data like stability, or a list of unstable
299
-
features allowed inside the macro. SyntaxExtensionKind - expander functions
300
-
may have several different signatures (take one token stream, or two, or a
301
-
piece of AST, etc), this is an enum that lists them
0 commit comments