Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #ifndef RUST_HIR_MAP_H
20 : #define RUST_HIR_MAP_H
21 :
22 : #include "optional.h"
23 : #include "rust-system.h"
24 : #include "rust-location.h"
25 : #include "rust-mapping-common.h"
26 : #include "rust-canonical-path.h"
27 : #include "rust-ast-full-decls.h"
28 : #include "rust-hir-full-decls.h"
29 : #include "rust-lang-item.h"
30 : #include "rust-privacy-common.h"
31 : #include "libproc_macro_internal/proc_macro.h"
32 : #include "rust-proc-macro.h"
33 : #include "optional.h"
34 :
35 : namespace Rust {
36 : namespace Analysis {
37 :
38 : class NodeMapping
39 : {
40 : public:
41 1757141 : NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId,
42 : LocalDefId localDefId)
43 1681132 : : crateNum (crateNum), nodeId (nodeId), hirId (hirId),
44 1681132 : localDefId (localDefId)
45 : {}
46 :
47 : static NodeMapping get_error ();
48 :
49 : CrateNum get_crate_num () const;
50 : NodeId get_nodeid () const;
51 : HirId get_hirid () const;
52 : LocalDefId get_local_defid () const;
53 : DefId get_defid () const;
54 :
55 : static DefId get_defid (CrateNum crate_num, LocalDefId local_defid);
56 :
57 : std::string as_string () const;
58 :
59 : bool is_equal (const NodeMapping &other) const
60 : {
61 : return get_crate_num () == other.get_crate_num ()
62 : && get_nodeid () == other.get_nodeid ()
63 : && get_hirid () == other.get_hirid ()
64 : && get_local_defid () == other.get_local_defid ();
65 : }
66 :
67 : private:
68 : CrateNum crateNum;
69 : NodeId nodeId;
70 : HirId hirId;
71 : LocalDefId localDefId;
72 : };
73 :
74 : enum class InsertionPolicy
75 : {
76 : FORBID_DUPLICATES,
77 : ALLOW_DUPLICATES,
78 : };
79 :
80 : template <typename Id, typename Item,
81 : const InsertionPolicy insertion_policy
82 : = InsertionPolicy::ALLOW_DUPLICATES>
83 20628 : class Mapping
84 : {
85 : std::unordered_map<Id, Item> storage;
86 :
87 : public:
88 106558 : tl::optional<Item &> lookup (Id id)
89 : {
90 106558 : auto it = storage.find (id);
91 106558 : if (it == storage.cend ())
92 50572 : return tl::nullopt;
93 55986 : return it->second;
94 : }
95 :
96 13314 : tl::optional<const Item &> lookup (Id id) const
97 : {
98 13314 : auto it = storage.find (id);
99 13314 : if (it == storage.cend ())
100 0 : return tl::nullopt;
101 13314 : return it->second;
102 : }
103 :
104 37875 : void insert (Id id, Item item)
105 : {
106 : if (insertion_policy == InsertionPolicy::FORBID_DUPLICATES)
107 : {
108 5232 : auto it = storage.find (id);
109 5232 : rust_assert (it == storage.end ());
110 : }
111 :
112 42963 : storage.insert ({id, item});
113 5232 : }
114 :
115 : // Required for CrateMappings::lookup_crate_name. Should we make mappings a
116 : // bimap instead ?
117 608 : const decltype (storage) &get_storage () const { return storage; }
118 : };
119 :
120 : class CrateMappings
121 : {
122 : std::map<CrateNum, AST::Crate *> ast_crate;
123 :
124 : CrateNum crate_num_itr;
125 :
126 : CrateNum current_crate_num;
127 :
128 : std::map<NodeId, CrateNum> crate_node_to_crate_num;
129 :
130 : public:
131 : CrateMappings ();
132 :
133 : CrateNum get_next_crate_num (const std::string &name);
134 : void set_current_crate (CrateNum crateNum);
135 : CrateNum get_current_crate () const;
136 :
137 : tl::optional<CrateNum> lookup_crate_num (NodeId node_id) const;
138 : const std::string &get_current_crate_name () const;
139 : tl::optional<CrateNum>
140 : lookup_crate_name (const std::string &crate_name) const;
141 : tl::optional<NodeId> crate_num_to_nodeid (const CrateNum &crate_num) const;
142 : bool node_is_crate (NodeId node_id) const;
143 :
144 : AST::Crate &insert_ast_crate (std::unique_ptr<AST::Crate> &&crate,
145 : CrateNum crate_num);
146 :
147 : AST::Crate &get_ast_crate (CrateNum crateNum);
148 :
149 : AST::Crate *get_ast_crate_by_node_id_raw (NodeId id);
150 :
151 : Mapping<CrateNum, std::vector<CustomDeriveProcMacro>,
152 : InsertionPolicy::FORBID_DUPLICATES>
153 : derives;
154 : Mapping<CrateNum, std::vector<BangProcMacro>,
155 : InsertionPolicy::FORBID_DUPLICATES>
156 : bangs;
157 : Mapping<CrateNum, std::vector<AttributeProcMacro>,
158 : InsertionPolicy::FORBID_DUPLICATES>
159 : attributes;
160 :
161 : Mapping<CrateNum, std::string, InsertionPolicy::FORBID_DUPLICATES>
162 : crate_names;
163 : };
164 :
165 : struct ProcMacroDefinitionMappings
166 : {
167 : Mapping<NodeId, CustomDeriveProcMacro, InsertionPolicy::FORBID_DUPLICATES>
168 : derives;
169 : Mapping<NodeId, BangProcMacro, InsertionPolicy::FORBID_DUPLICATES> bangs;
170 : Mapping<NodeId, AttributeProcMacro, InsertionPolicy::FORBID_DUPLICATES>
171 : attributes;
172 : };
173 :
174 : struct ProcMacroInvocationsMappings
175 : {
176 : Mapping<NodeId, CustomDeriveProcMacro, InsertionPolicy::FORBID_DUPLICATES>
177 : derives;
178 : Mapping<NodeId, BangProcMacro, InsertionPolicy::FORBID_DUPLICATES> bangs;
179 : Mapping<NodeId, AttributeProcMacro, InsertionPolicy::FORBID_DUPLICATES>
180 : attributes;
181 : };
182 :
183 10314 : struct ProcMacroMappings
184 : {
185 : ProcMacroDefinitionMappings definitions;
186 : ProcMacroInvocationsMappings invocations;
187 : };
188 :
189 : enum class InsertLocation
190 : {
191 : YES,
192 : NO,
193 : };
194 :
195 : template <typename Item,
196 : InsertionPolicy policy = InsertionPolicy::FORBID_DUPLICATES,
197 : InsertLocation insert_location = InsertLocation::NO>
198 : class PtrMapping
199 : {
200 : std::unordered_map<HirId, Item *> storage;
201 :
202 : public:
203 : tl::optional<Item *> lookup (HirId id);
204 : void insert (Item *item);
205 : };
206 :
207 10314 : class ASTMappings
208 : {
209 : public:
210 : Mapping<NodeId, Privacy::ModuleVisibility> module_visibility;
211 : };
212 :
213 : class HIRMappings
214 : {
215 : public:
216 : PtrMapping<HIR::Item> items;
217 : PtrMapping<HIR::TraitItem> trait_items;
218 : PtrMapping<HIR::ExternBlock> extern_blocks;
219 : PtrMapping<HIR::Module> modules;
220 : PtrMapping<HIR::Expr, InsertionPolicy::ALLOW_DUPLICATES, InsertLocation::YES>
221 : exprs;
222 : PtrMapping<HIR::PathExprSegment, InsertionPolicy::FORBID_DUPLICATES,
223 : InsertLocation::YES>
224 : path_expr_segments;
225 : PtrMapping<HIR::GenericParam, InsertionPolicy::FORBID_DUPLICATES,
226 : InsertLocation::YES>
227 : generic_params;
228 : PtrMapping<HIR::Type> types;
229 : PtrMapping<HIR::Stmt> stmts;
230 : PtrMapping<HIR::FunctionParam, InsertionPolicy::ALLOW_DUPLICATES>
231 : function_params;
232 : PtrMapping<HIR::SelfParam> self_params;
233 : PtrMapping<HIR::StructExprField> struct_expr_fields;
234 : PtrMapping<HIR::Pattern> patterns;
235 : };
236 :
237 : class Mappings
238 : {
239 : public:
240 : static Mappings &get ();
241 : ~Mappings ();
242 :
243 : CrateMappings crate;
244 : ProcMacroMappings pmacro;
245 : ASTMappings ast;
246 : HIRMappings hir;
247 :
248 : NodeId get_next_node_id ();
249 237184 : HirId get_next_hir_id ()
250 : {
251 237184 : return get_next_hir_id (crate.get_current_crate ());
252 : }
253 : HirId get_next_hir_id (CrateNum crateNum);
254 : LocalDefId get_next_localdef_id ()
255 : {
256 : return get_next_localdef_id (crate.get_current_crate ());
257 : }
258 : LocalDefId get_next_localdef_id (CrateNum crateNum);
259 :
260 : AST::Crate &get_ast_crate_by_node_id (NodeId id);
261 :
262 : HIR::Crate &insert_hir_crate (std::unique_ptr<HIR::Crate> &&crate);
263 : HIR::Crate &get_hir_crate (CrateNum crateNum);
264 : bool is_local_hirid_crate (HirId crateNum);
265 :
266 : void insert_defid_mapping (DefId id, HIR::Item *item);
267 : tl::optional<HIR::Item *> lookup_defid (DefId id);
268 : void insert_defid_mapping (DefId id, HIR::TraitItem *item);
269 : tl::optional<HIR::TraitItem *> lookup_trait_item_defid (DefId id);
270 :
271 : void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
272 : HIR::Item *item);
273 : tl::optional<HIR::Item *> lookup_local_defid (CrateNum crateNum,
274 : LocalDefId id);
275 :
276 : void insert_hir_enumitem (HIR::Enum *parent, HIR::EnumItem *item);
277 : std::pair<HIR::Enum *, HIR::EnumItem *> lookup_hir_enumitem (HirId id);
278 :
279 : void insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block);
280 :
281 : // std::pair<hir_extern_item, parent hirid>
282 : tl::optional<std::pair<HIR::ExternalItem *, HirId>>
283 : lookup_hir_extern_item (HirId id);
284 :
285 : void insert_hir_impl_block (HIR::ImplBlock *item);
286 : tl::optional<HIR::ImplBlock *> lookup_hir_impl_block (HirId id);
287 : tl::optional<HIR::ImplBlock *> lookup_impl_block_type (HirId id);
288 :
289 : void insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item);
290 : // Optional<ImpItem, ParentImpl Hir id>
291 : tl::optional<std::pair<HIR::ImplItem *, HirId>>
292 : lookup_hir_implitem (HirId id);
293 :
294 : void walk_local_defids_for_crate (CrateNum crateNum,
295 : std::function<bool (HIR::Item *)> cb);
296 :
297 : void insert_node_to_hir (NodeId id, HirId ref);
298 : tl::optional<HirId> lookup_node_to_hir (NodeId id);
299 : tl::optional<NodeId> lookup_hir_to_node (HirId id);
300 :
301 : void insert_location (HirId id, location_t locus);
302 : location_t lookup_location (HirId id);
303 :
304 : tl::optional<HIR::Stmt *> resolve_nodeid_to_stmt (NodeId id);
305 :
306 : std::set<HirId> &get_hirids_within_crate (CrateNum crate)
307 : {
308 : return hirNodesWithinCrate[crate];
309 : }
310 :
311 21262 : void insert_impl_item_mapping (HirId impl_item_id, HIR::ImplBlock *impl)
312 : {
313 21262 : rust_assert (hirImplItemsToImplMappings.find (impl_item_id)
314 : == hirImplItemsToImplMappings.end ());
315 21262 : hirImplItemsToImplMappings[impl_item_id] = impl;
316 21262 : }
317 :
318 86573 : HIR::ImplBlock *lookup_associated_impl (HirId impl_item_id)
319 : {
320 86573 : auto lookup = hirImplItemsToImplMappings.find (impl_item_id);
321 86573 : rust_assert (lookup != hirImplItemsToImplMappings.end ());
322 86573 : return lookup->second;
323 : }
324 :
325 : void iterate_impl_items (
326 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
327 :
328 : template <typename Callback>
329 3225 : void iterate_inherent_impl_items (const std::string &name, Callback &&cb)
330 : {
331 3225 : auto items = hirInherentImplItemMappings.find (name);
332 3225 : if (items == hirInherentImplItemMappings.end ())
333 : return;
334 :
335 9298 : for (auto &item : items->second)
336 7192 : if (!cb (item.first, item.second))
337 : return;
338 : }
339 :
340 : void insert_adt_impl_mapping (DefId adt_id, HIR::ImplBlock *impl);
341 :
342 : void build_impl_indexes ();
343 :
344 : void iterate_adt_impl_items (
345 : DefId adt_id,
346 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
347 :
348 : void insert_trait_impl_mapping (DefId trait_id, HIR::ImplBlock *impl);
349 :
350 : void iterate_trait_impl_items (
351 : DefId trait_id,
352 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
353 :
354 : void
355 : iterate_trait_impl_blocks (DefId trait_id,
356 : std::function<bool (HirId, HIR::ImplBlock *)> cb);
357 :
358 480 : template <typename Callback> void iterate_trait_impl_blocks (Callback &&cb)
359 : {
360 2426 : for (auto it = hirTraitImplBlockMappings.begin ();
361 2426 : it != hirTraitImplBlockMappings.end (); ++it)
362 1946 : if (!cb (it->first, it->second))
363 480 : return;
364 : }
365 :
366 : void iterate_trait_impl_blocks_for_item (
367 : const std::string &name, std::function<bool (HirId, HIR::ImplBlock *)> cb);
368 :
369 : void iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb);
370 :
371 : void iterate_trait_items (
372 : std::function<bool (HIR::TraitItem *item, HIR::Trait *)> cb);
373 :
374 4518 : bool is_impl_item (HirId id) { return lookup_hir_implitem (id).has_value (); }
375 :
376 : void insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait);
377 :
378 4037 : HIR::Trait *lookup_trait_item_mapping (HirId trait_item_id)
379 : {
380 4037 : auto lookup = hirTraitItemsToTraitMappings.find (trait_item_id);
381 4037 : rust_assert (lookup != hirTraitItemsToTraitMappings.end ());
382 4037 : return lookup->second;
383 : }
384 :
385 : void insert_canonical_path (NodeId id, const Resolver::CanonicalPath path)
386 : {
387 : if (auto p = lookup_canonical_path (id))
388 : {
389 : // if we have already stored a canonical path this is ok so long as
390 : // this new path is equal or is smaller that the existing one but in
391 : // that case we ignore it.
392 : if (p->is_equal (path))
393 : return;
394 : else
395 : {
396 : rust_assert (p->size () >= path.size ());
397 : return;
398 : }
399 : }
400 :
401 : paths.emplace (id, std::move (path));
402 : }
403 :
404 : tl::optional<const Resolver::CanonicalPath &>
405 : lookup_canonical_path (NodeId id)
406 : {
407 : auto it = paths.find (id);
408 : if (it == paths.end ())
409 : return tl::nullopt;
410 :
411 : return it->second;
412 : }
413 :
414 : void insert_lang_item (LangItem::Kind item_type, DefId id);
415 : tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type);
416 :
417 : void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id);
418 : tl::optional<NodeId &> lookup_lang_item_node (LangItem::Kind item_type);
419 : NodeId get_lang_item_node (LangItem::Kind item_type);
420 : std::string &get_lang_item_identifier (LangItem::Kind item_type);
421 :
422 : // This will fatal_error when this lang item does not exist
423 : DefId get_lang_item (LangItem::Kind item_type, location_t locus);
424 :
425 : void insert_macro_def (AST::MacroRulesDefinition *macro);
426 :
427 : tl::optional<AST::MacroRulesDefinition *> lookup_macro_def (NodeId id);
428 : tl::optional<CrateNum> lookup_macro_def_crate (NodeId id);
429 :
430 : void insert_macro_invocation (AST::MacroInvocation &invoc,
431 : AST::MacroRulesDefinition *def);
432 : tl::optional<AST::MacroRulesDefinition *>
433 : lookup_macro_invocation (AST::MacroInvocation &invoc);
434 :
435 : void insert_exported_macro (AST::MacroRulesDefinition &def);
436 : std::vector<AST::MacroRulesDefinition> get_exported_macros ();
437 :
438 : void insert_glob_container (NodeId, AST::GlobContainer *);
439 : tl::optional<AST::GlobContainer *> lookup_glob_container (NodeId id);
440 :
441 : void insert_module_id (NodeId);
442 : bool is_module (NodeId id);
443 :
444 : void insert_extern_crate_id (NodeId);
445 : bool is_extern_crate (NodeId id);
446 :
447 : void insert_module_child (NodeId module, NodeId child);
448 : tl::optional<std::vector<NodeId> &> lookup_module_children (NodeId module);
449 :
450 : void insert_module_child_item (NodeId module, Resolver::CanonicalPath item);
451 : tl::optional<std::vector<Resolver::CanonicalPath> &>
452 : lookup_module_chidren_items (NodeId module);
453 : tl::optional<Resolver::CanonicalPath &>
454 : lookup_module_child (NodeId module, const std::string &item_name);
455 :
456 : void insert_child_item_to_parent_module_mapping (NodeId child_item,
457 : NodeId parent_module);
458 : tl::optional<NodeId> lookup_parent_module (NodeId child_item);
459 : bool node_is_module (NodeId query);
460 :
461 : void insert_ast_item (AST::Item *item);
462 : tl::optional<AST::Item *> lookup_ast_item (NodeId id);
463 :
464 : HIR::ImplBlock *lookup_builtin_marker ();
465 :
466 : tl::optional<HIR::TraitItem *>
467 : lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
468 :
469 : void insert_auto_trait (HIR::Trait *trait);
470 : std::vector<HIR::Trait *> &get_auto_traits ();
471 : void add_capture (NodeId closure, NodeId definition);
472 : tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);
473 :
474 : void add_derived_node (NodeId node_id);
475 : bool is_derived_node (NodeId node_id);
476 :
477 : void add_function_node (NodeId node_id);
478 : bool is_function_node (NodeId node_id);
479 :
480 : private:
481 : Mappings ();
482 :
483 : HirId hirIdIter;
484 : NodeId nodeIdIter;
485 : std::map<CrateNum, LocalDefId> localIdIter;
486 : HIR::ImplBlock *builtinMarker;
487 :
488 : std::map<CrateNum, HIR::Crate *> hir_crate_mappings;
489 : std::map<DefId, HIR::Item *> defIdMappings;
490 : std::map<DefId, HIR::TraitItem *> defIdTraitItemMappings;
491 : std::map<CrateNum, std::map<LocalDefId, HIR::Item *>> localDefIdMappings;
492 :
493 : std::map<HirId, HIR::Module *> hirModuleMappings;
494 : std::map<HirId, HIR::Item *> hirItemMappings;
495 : std::map<HirId, std::pair<HIR::Enum *, HIR::EnumItem *>> hirEnumItemMappings;
496 : std::map<HirId, HIR::Type *> hirTypeMappings;
497 : std::map<HirId, HIR::Expr *> hirExprMappings;
498 : std::map<HirId, HIR::Stmt *> hirStmtMappings;
499 : std::map<HirId, HIR::FunctionParam *> hirParamMappings;
500 : std::map<HirId, HIR::StructExprField *> hirStructFieldMappings;
501 : std::map<HirId, std::pair<HirId, HIR::ImplItem *>> hirImplItemMappings;
502 : std::map<HirId, HIR::SelfParam *> hirSelfParamMappings;
503 : std::map<HirId, HIR::ImplBlock *> hirImplItemsToImplMappings;
504 : std::map<HirId, HIR::ImplBlock *> hirImplBlockMappings;
505 : std::map<HirId, HIR::ImplBlock *> hirTraitImplBlockMappings;
506 : std::map<std::string,
507 : std::vector<std::pair<HIR::ImplItem *, HIR::ImplBlock *>>>
508 : hirInherentImplItemMappings;
509 : std::map<HirId, HIR::ImplBlock *> hirImplBlockTypeMappings;
510 : std::map<DefId, std::vector<HIR::ImplBlock *>> hirAdtImplMappings;
511 : std::set<HIR::ImplBlock *> hirIndexedAdtImpls;
512 : std::map<DefId, std::vector<HIR::ImplBlock *>> hirTraitImplMappings;
513 : std::map<std::string, std::vector<DefId>> hirTraitItemNameMappings;
514 : bool hirImplIndexesBuilt;
515 : std::map<HirId, HIR::TraitItem *> hirTraitItemMappings;
516 : std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
517 : std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
518 : std::map<HirId, HIR::PathExprSegment *> hirPathSegMappings;
519 : std::map<HirId, HIR::GenericParam *> hirGenericParamMappings;
520 : std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
521 : std::map<HirId, HIR::Pattern *> hirPatternMappings;
522 :
523 : // FIXME: Add documentation
524 : std::vector<HIR::Trait *> auto_traits;
525 :
526 : // We need to have two maps here, as lang-items need to be used for both AST
527 : // passes and HIR passes. Thus those two maps are created at different times.
528 : std::map<LangItem::Kind, DefId> lang_item_mappings;
529 : std::map<LangItem::Kind, NodeId> lang_item_nodes;
530 :
531 : std::map<NodeId, Resolver::CanonicalPath> paths;
532 : std::map<NodeId, location_t> locations;
533 : std::map<NodeId, HirId> nodeIdToHirMappings;
534 : std::map<HirId, NodeId> hirIdToNodeMappings;
535 :
536 : // all hirid nodes
537 : std::map<CrateNum, std::set<HirId>> hirNodesWithinCrate;
538 :
539 : // MBE macros
540 : std::map<NodeId, std::pair<AST::MacroRulesDefinition *, CrateNum>>
541 : macroMappings;
542 : std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations;
543 : std::vector<AST::MacroRulesDefinition> exportedMacros;
544 :
545 : // Low level visibility map for each DefId
546 : std::map<NodeId, Privacy::ModuleVisibility> visibility_map;
547 :
548 : // Module tree maps
549 :
550 : // Maps each module's node id to a list of its children
551 : // TODO: I think these are only used by the old resolved and can be removed
552 : std::map<NodeId, std::vector<NodeId>> module_child_map;
553 : std::map<NodeId, std::vector<Resolver::CanonicalPath>> module_child_items;
554 : std::map<NodeId, NodeId> child_to_parent_module_map;
555 :
556 : std::map<NodeId, AST::GlobContainer *> glob_containers;
557 : std::set<NodeId> module_ids;
558 : std::set<NodeId> extern_crate_ids;
559 :
560 : // AST mappings
561 : std::map<NodeId, AST::Item *> ast_item_mappings;
562 :
563 : // Closure AST NodeId -> vector of Definition node ids
564 : std::unordered_map<NodeId, std::vector<NodeId>> captures;
565 :
566 : std::set<NodeId> derived_nodes;
567 :
568 : std::set<NodeId> function_nodes;
569 : };
570 :
571 : } // namespace Analysis
572 : } // namespace Rust
573 :
574 : #include "rust-hir-map.hxx"
575 :
576 : #endif // RUST_HIR_MAP_H
|