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 : #include "rust-hir-map.h"
20 : #include "optional.h"
21 : #include "rust-ast-full.h"
22 : #include "rust-ast.h"
23 : #include "rust-diagnostics.h"
24 : #include "rust-hir-full.h"
25 : #include "rust-item.h"
26 : #include "rust-macro-builtins.h"
27 : #include "rust-mapping-common.h"
28 : #include "rust-attribute-values.h"
29 : #include "rust-finalized-name-resolution-context.h"
30 :
31 : namespace Rust {
32 : namespace Analysis {
33 :
34 : NodeMapping
35 80252 : NodeMapping::get_error ()
36 : {
37 80252 : return NodeMapping (UNKNOWN_CRATENUM, UNKNOWN_NODEID, UNKNOWN_HIRID,
38 80252 : UNKNOWN_LOCAL_DEFID);
39 : }
40 :
41 : CrateNum
42 792654 : NodeMapping::get_crate_num () const
43 : {
44 792654 : return crateNum;
45 : }
46 :
47 : NodeId
48 2714693 : NodeMapping::get_nodeid () const
49 : {
50 2714693 : return nodeId;
51 : }
52 :
53 : HirId
54 5393816 : NodeMapping::get_hirid () const
55 : {
56 5393816 : return hirId;
57 : }
58 :
59 : LocalDefId
60 787014 : NodeMapping::get_local_defid () const
61 : {
62 787014 : return localDefId;
63 : }
64 :
65 : DefId
66 784137 : NodeMapping::get_defid () const
67 : {
68 784137 : return get_defid (get_crate_num (), get_local_defid ());
69 : }
70 :
71 : DefId
72 784137 : NodeMapping::get_defid (CrateNum crate_num, LocalDefId local_defid)
73 : {
74 784137 : return DefId{crate_num, local_defid};
75 : }
76 :
77 : std::string
78 227 : NodeMapping::as_string () const
79 : {
80 227 : std::ostringstream ss;
81 227 : ss << "["
82 227 : << "C: " << get_crate_num ();
83 227 : if (get_nodeid () != UNKNOWN_NODEID)
84 227 : ss << " Nid: " << get_nodeid ();
85 :
86 227 : if (get_hirid () != UNKNOWN_HIRID)
87 227 : ss << " Hid: " << get_hirid ();
88 :
89 227 : if (get_local_defid () != UNKNOWN_LOCAL_DEFID)
90 227 : ss << " Lid: " << get_local_defid ();
91 :
92 227 : ss << "]";
93 227 : return ss.str ();
94 227 : }
95 :
96 : // Mappings Class now
97 : static const HirId kDefaultNodeIdBegin = 1;
98 : static const HirId kDefaultHirIdBegin = 1;
99 : static const HirId kDefaultCrateNumBegin = 0;
100 :
101 5192 : CrateMappings::CrateMappings ()
102 5192 : : crate_num_itr (kDefaultCrateNumBegin), current_crate_num (UNKNOWN_CRATENUM)
103 5192 : {}
104 :
105 5192 : Mappings::Mappings ()
106 5192 : : hirIdIter (kDefaultHirIdBegin), nodeIdIter (kDefaultNodeIdBegin),
107 10384 : hirImplIndexesBuilt (false)
108 : {
109 5192 : Analysis::NodeMapping node (0, 0, 0, 0);
110 5192 : builtinMarker
111 10384 : = new HIR::ImplBlock (node, {}, {}, nullptr, nullptr, HIR::WhereClause ({}),
112 : BoundPolarity::RegularBound,
113 10384 : HIR::Visibility (HIR::Visibility::VisType::Public),
114 10384 : {}, {}, UNDEF_LOCATION);
115 5192 : }
116 :
117 10384 : Mappings::~Mappings () { delete builtinMarker; }
118 :
119 : Mappings &
120 22721349 : Mappings::get ()
121 : {
122 22726541 : static Mappings instance{};
123 22721349 : return instance;
124 : }
125 :
126 : CrateNum
127 5123 : CrateMappings::get_next_crate_num (const std::string &name)
128 : {
129 5123 : auto id = crate_num_itr;
130 5123 : crate_num_itr++;
131 10246 : crate_names.insert (id, name);
132 5123 : return id;
133 : }
134 :
135 : void
136 5243 : CrateMappings::set_current_crate (CrateNum crateNum)
137 : {
138 5243 : current_crate_num = crateNum;
139 5243 : }
140 :
141 : CrateNum
142 1965643 : CrateMappings::get_current_crate () const
143 : {
144 1965643 : return current_crate_num;
145 : }
146 :
147 : tl::optional<CrateNum>
148 106509 : CrateMappings::lookup_crate_num (NodeId node_id) const
149 : {
150 106509 : auto it = crate_node_to_crate_num.find (node_id);
151 106509 : if (it == crate_node_to_crate_num.end ())
152 53369 : return tl::nullopt;
153 :
154 53140 : return it->second;
155 : }
156 :
157 : const std::string &
158 13392 : CrateMappings::get_current_crate_name () const
159 : {
160 13392 : return crate_names.lookup (get_current_crate ()).value ();
161 : }
162 :
163 : tl::optional<CrateNum>
164 608 : CrateMappings::lookup_crate_name (const std::string &crate_name) const
165 : {
166 672 : for (const auto &it : crate_names.get_storage ())
167 : {
168 608 : if (it.second.compare (crate_name) == 0)
169 544 : return it.first;
170 : }
171 64 : return tl::nullopt;
172 : }
173 :
174 : tl::optional<NodeId>
175 20472 : CrateMappings::crate_num_to_nodeid (const CrateNum &crate_num) const
176 : {
177 20472 : auto it = ast_crate.find (crate_num);
178 20472 : if (it == ast_crate.end ())
179 0 : return tl::nullopt;
180 :
181 20472 : return it->second->get_node_id ();
182 : }
183 :
184 : bool
185 58515 : CrateMappings::node_is_crate (NodeId node_id) const
186 : {
187 58515 : return lookup_crate_num (node_id).has_value ();
188 : }
189 :
190 : NodeId
191 7216154 : Mappings::get_next_node_id ()
192 : {
193 7216154 : auto it = nodeIdIter;
194 7216154 : if (UNLIKELY (it > MAX_NODEID))
195 0 : rust_fatal_error (UNKNOWN_LOCATION, "out of node ids");
196 7216154 : nodeIdIter++;
197 7216154 : return it;
198 : }
199 :
200 : HirId
201 1906058 : Mappings::get_next_hir_id (CrateNum crateNum)
202 : {
203 1906058 : auto id = hirIdIter;
204 1906058 : hirIdIter++;
205 :
206 1906058 : auto it = hirNodesWithinCrate.find (crateNum);
207 1906058 : if (it == hirNodesWithinCrate.end ())
208 : {
209 5098 : hirNodesWithinCrate.insert ({crateNum, {}});
210 : }
211 :
212 1906058 : hirNodesWithinCrate[crateNum].insert (id);
213 1906058 : return id;
214 : }
215 :
216 : LocalDefId
217 301456 : Mappings::get_next_localdef_id (CrateNum crateNum)
218 : {
219 301456 : auto it = localIdIter.find (crateNum);
220 301456 : if (it == localIdIter.end ())
221 : {
222 4787 : localIdIter.insert ({crateNum, 1});
223 : }
224 :
225 301456 : it = localIdIter.find (crateNum);
226 301456 : rust_assert (it != localIdIter.end ());
227 :
228 301456 : LocalDefId id = it->second;
229 301456 : localIdIter[crateNum] = id + 1;
230 301456 : return id;
231 : }
232 :
233 : AST::Crate &
234 9707 : CrateMappings::get_ast_crate (CrateNum crateNum)
235 : {
236 9707 : auto it = ast_crate.find (crateNum);
237 9707 : rust_assert (it != ast_crate.end ());
238 9707 : return *it->second;
239 : }
240 :
241 : AST::Crate &
242 0 : Mappings::get_ast_crate_by_node_id (NodeId id)
243 : {
244 0 : return *crate.get_ast_crate_by_node_id_raw (id);
245 : }
246 :
247 : AST::Crate *
248 5098 : CrateMappings::get_ast_crate_by_node_id_raw (NodeId id)
249 : {
250 5098 : CrateNum crateNum = lookup_crate_num (id).value ();
251 5098 : auto it = ast_crate.find (crateNum);
252 5098 : rust_assert (it != ast_crate.end ());
253 5098 : return it->second;
254 : }
255 :
256 : AST::Crate &
257 5123 : CrateMappings::insert_ast_crate (std::unique_ptr<AST::Crate> &&crate,
258 : CrateNum crate_num)
259 : {
260 5123 : auto it = ast_crate.find (crate_num);
261 5123 : rust_assert (it == ast_crate.end ());
262 :
263 : // store it
264 5123 : crate_node_to_crate_num.insert ({crate->get_node_id (), crate_num});
265 5123 : ast_crate.insert ({crate_num, crate.release ()});
266 :
267 : // return the reference to it
268 5123 : it = ast_crate.find (crate_num);
269 5123 : rust_assert (it != ast_crate.end ());
270 5123 : return *it->second;
271 : }
272 :
273 : HIR::Crate &
274 0 : Mappings::get_hir_crate (CrateNum crateNum)
275 : {
276 0 : auto it = hir_crate_mappings.find (crateNum);
277 0 : rust_assert (it != hir_crate_mappings.end ());
278 0 : return *it->second;
279 : }
280 :
281 : bool
282 118920 : Mappings::is_local_hirid_crate (HirId crateNum)
283 : {
284 236293 : for (const auto &it : hir_crate_mappings)
285 : {
286 119136 : const auto &crate = it.second;
287 119136 : if (crate->get_mappings ().get_hirid () == crateNum)
288 118920 : return true;
289 : }
290 : return false;
291 : }
292 :
293 : HIR::Crate &
294 4822 : Mappings::insert_hir_crate (std::unique_ptr<HIR::Crate> &&crate)
295 : {
296 4822 : CrateNum crateNum = crate->get_mappings ().get_crate_num ();
297 4822 : auto it = hir_crate_mappings.find (crateNum);
298 4822 : rust_assert (it == hir_crate_mappings.end ());
299 :
300 4814 : insert_node_to_hir (crate->get_mappings ().get_nodeid (),
301 4814 : crate->get_mappings ().get_hirid ());
302 4814 : hir_crate_mappings.insert ({crateNum, crate.release ()});
303 :
304 4814 : it = hir_crate_mappings.find (crateNum);
305 4814 : rust_assert (it != hir_crate_mappings.end ());
306 4814 : return *it->second;
307 : }
308 :
309 : void
310 61960 : Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
311 : {
312 61960 : CrateNum crate_num = id.crateNum;
313 61960 : LocalDefId local_def_id = id.localDefId;
314 :
315 61960 : rust_assert (!lookup_defid (id));
316 61960 : rust_assert (!lookup_local_defid (crate_num, local_def_id));
317 61960 : rust_assert (!lookup_trait_item_defid (id));
318 :
319 61960 : defIdMappings[id] = item;
320 61960 : insert_local_defid_mapping (crate_num, local_def_id, item);
321 61960 : }
322 :
323 : tl::optional<HIR::Item *>
324 162707 : Mappings::lookup_defid (DefId id)
325 : {
326 162707 : auto it = defIdMappings.find (id);
327 162707 : if (it == defIdMappings.end ())
328 74183 : return tl::nullopt;
329 :
330 88524 : return it->second;
331 : }
332 :
333 : void
334 4211 : Mappings::insert_defid_mapping (DefId id, HIR::TraitItem *item)
335 : {
336 4211 : CrateNum crate_num = id.crateNum;
337 4211 : LocalDefId local_def_id = id.localDefId;
338 :
339 4211 : rust_assert (!lookup_defid (id));
340 4211 : rust_assert (!lookup_local_defid (crate_num, local_def_id));
341 4211 : rust_assert (!lookup_trait_item_defid (id));
342 :
343 4211 : defIdTraitItemMappings[id] = item;
344 4211 : }
345 :
346 : tl::optional<HIR::TraitItem *>
347 69148 : Mappings::lookup_trait_item_defid (DefId id)
348 : {
349 69148 : auto it = defIdTraitItemMappings.find (id);
350 69148 : if (it == defIdTraitItemMappings.end ())
351 68086 : return tl::nullopt;
352 :
353 1062 : return it->second;
354 : }
355 :
356 : void
357 1498 : Mappings::insert_hir_enumitem (HIR::Enum *parent, HIR::EnumItem *item)
358 : {
359 1498 : auto id = item->get_mappings ().get_hirid ();
360 1498 : auto result = lookup_hir_enumitem (id);
361 1498 : rust_assert (result.first == nullptr);
362 :
363 1498 : hirEnumItemMappings[id] = {parent, item};
364 1498 : insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
365 1498 : }
366 :
367 : std::pair<HIR::Enum *, HIR::EnumItem *>
368 69178 : Mappings::lookup_hir_enumitem (HirId id)
369 : {
370 69178 : auto it = hirEnumItemMappings.find (id);
371 69178 : if (it == hirEnumItemMappings.end ())
372 59979 : return {nullptr, nullptr};
373 :
374 9199 : return it->second;
375 : }
376 :
377 : void
378 3535 : Mappings::insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block)
379 : {
380 3535 : auto id = item->get_mappings ().get_hirid ();
381 3535 : rust_assert (!lookup_hir_extern_item (id));
382 :
383 3535 : hirExternItemMappings[id] = {item, parent_block};
384 3535 : insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
385 3535 : }
386 :
387 : tl::optional<std::pair<HIR::ExternalItem *, HirId>>
388 52186 : Mappings::lookup_hir_extern_item (HirId id)
389 : {
390 52186 : auto it = hirExternItemMappings.find (id);
391 52186 : if (it == hirExternItemMappings.end ())
392 45464 : return tl::nullopt;
393 :
394 6722 : return it->second;
395 : }
396 :
397 : void
398 14611 : Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
399 : {
400 14611 : auto id = item->get_mappings ().get_hirid ();
401 14611 : rust_assert (!lookup_hir_impl_block (id));
402 :
403 14611 : HirId impl_type_id = item->get_type ().get_mappings ().get_hirid ();
404 14611 : hirImplBlockMappings[id] = item;
405 14611 : if (item->has_trait_ref ())
406 13097 : hirTraitImplBlockMappings[id] = item;
407 : else
408 : {
409 7565 : for (auto &impl_item : item->get_impl_items ())
410 : {
411 6051 : if (impl_item->get_impl_item_type ()
412 : != HIR::ImplItem::ImplItemType::FUNCTION)
413 1665 : continue;
414 :
415 5910 : auto *function = static_cast<HIR::Function *> (impl_item.get ());
416 5910 : if (!function->is_method ())
417 1524 : continue;
418 :
419 8772 : auto name = function->get_function_name ().as_string ();
420 4386 : hirInherentImplItemMappings[name].emplace_back (impl_item.get (),
421 : item);
422 4386 : }
423 : }
424 14611 : hirImplBlockTypeMappings[impl_type_id] = item;
425 14611 : insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
426 14611 : }
427 :
428 : tl::optional<HIR::ImplBlock *>
429 16662 : Mappings::lookup_hir_impl_block (HirId id)
430 : {
431 16662 : auto it = hirImplBlockMappings.find (id);
432 16662 : if (it == hirImplBlockMappings.end ())
433 14611 : return tl::nullopt;
434 :
435 2051 : return it->second;
436 : }
437 :
438 : tl::optional<HIR::ImplBlock *>
439 522 : Mappings::lookup_impl_block_type (HirId id)
440 : {
441 522 : auto it = hirImplBlockTypeMappings.find (id);
442 522 : if (it == hirImplBlockTypeMappings.end ())
443 56 : return tl::nullopt;
444 :
445 466 : return it->second;
446 : }
447 :
448 : void
449 23033 : Mappings::insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item)
450 : {
451 23033 : auto id = item->get_impl_mappings ().get_hirid ();
452 23033 : rust_assert (!lookup_hir_implitem (id));
453 :
454 23033 : hirImplItemMappings[id]
455 23033 : = std::pair<HirId, HIR::ImplItem *> (parent_impl_id, item);
456 23033 : insert_node_to_hir (item->get_impl_mappings ().get_nodeid (), id);
457 23033 : }
458 :
459 : tl::optional<std::pair<HIR::ImplItem *, HirId>>
460 118650 : Mappings::lookup_hir_implitem (HirId id)
461 : {
462 118650 : auto it = hirImplItemMappings.find (id);
463 118650 : if (it == hirImplItemMappings.end ())
464 96470 : return tl::nullopt;
465 :
466 22180 : return std::make_pair (it->second.second, it->second.first);
467 : }
468 :
469 : void
470 61960 : Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
471 : HIR::Item *item)
472 : {
473 61960 : rust_assert (!lookup_local_defid (crateNum, id));
474 61960 : localDefIdMappings[crateNum][id] = item;
475 61960 : }
476 :
477 : tl::optional<HIR::Item *>
478 128131 : Mappings::lookup_local_defid (CrateNum crateNum, LocalDefId id)
479 : {
480 128131 : auto it = localDefIdMappings.find (crateNum);
481 128131 : if (it == localDefIdMappings.end ())
482 9617 : return tl::nullopt;
483 :
484 118514 : auto iy = it->second.find (id);
485 118514 : if (iy == it->second.end ())
486 118514 : return tl::nullopt;
487 :
488 0 : return iy->second;
489 : }
490 :
491 : void
492 0 : Mappings::walk_local_defids_for_crate (CrateNum crateNum,
493 : std::function<bool (HIR::Item *)> cb)
494 : {
495 0 : auto it = localDefIdMappings.find (crateNum);
496 0 : if (it == localDefIdMappings.end ())
497 : return;
498 :
499 0 : for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
500 : {
501 0 : if (!cb (iy->second))
502 0 : return;
503 : }
504 : }
505 :
506 : void
507 1479803 : Mappings::insert_node_to_hir (NodeId id, HirId ref)
508 : {
509 1479803 : nodeIdToHirMappings[id] = ref;
510 1479803 : hirIdToNodeMappings[ref] = id;
511 1479803 : }
512 :
513 : tl::optional<HirId>
514 716820 : Mappings::lookup_node_to_hir (NodeId id)
515 : {
516 716820 : auto it = nodeIdToHirMappings.find (id);
517 716820 : if (it == nodeIdToHirMappings.end ())
518 0 : return tl::nullopt;
519 :
520 716820 : return {it->second};
521 : }
522 :
523 : tl::optional<NodeId>
524 8050 : Mappings::lookup_hir_to_node (HirId id)
525 : {
526 8050 : auto it = hirIdToNodeMappings.find (id);
527 8050 : if (it == hirIdToNodeMappings.end ())
528 0 : return tl::nullopt;
529 :
530 8050 : return {it->second};
531 : }
532 :
533 : void
534 2138412 : Mappings::insert_location (HirId id, location_t locus)
535 : {
536 2138412 : locations[id] = locus;
537 2138412 : }
538 :
539 : location_t
540 1244884 : Mappings::lookup_location (HirId id)
541 : {
542 1244884 : auto it = locations.find (id);
543 1244884 : if (it == locations.end ())
544 : return UNDEF_LOCATION;
545 :
546 1121262 : return it->second;
547 : }
548 :
549 : tl::optional<HIR::Stmt *>
550 0 : Mappings::resolve_nodeid_to_stmt (NodeId id)
551 : {
552 0 : auto it = nodeIdToHirMappings.find (id);
553 0 : if (it == nodeIdToHirMappings.end ())
554 0 : return tl::nullopt;
555 :
556 0 : HirId resolved = it->second;
557 0 : return hir.stmts.lookup (resolved);
558 : }
559 :
560 : void
561 5874 : Mappings::iterate_impl_items (
562 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
563 : {
564 88118 : for (auto it = hirImplItemMappings.begin (); it != hirImplItemMappings.end ();
565 82244 : it++)
566 : {
567 82244 : auto id = it->first;
568 82244 : auto impl_item = it->second.second;
569 82244 : auto impl
570 82244 : = lookup_associated_impl (impl_item->get_impl_mappings ().get_hirid ());
571 82244 : if (!cb (id, impl_item, impl))
572 5874 : return;
573 : }
574 : }
575 :
576 : void
577 6087 : Mappings::insert_adt_impl_mapping (DefId adt_id, HIR::ImplBlock *impl)
578 : {
579 6087 : hirAdtImplMappings[adt_id].push_back (impl);
580 6087 : hirIndexedAdtImpls.insert (impl);
581 6087 : }
582 :
583 : void
584 4782 : Mappings::build_impl_indexes ()
585 : {
586 4782 : gcc_checking_assert (!hirImplIndexesBuilt);
587 4782 : if (hirImplIndexesBuilt)
588 : return;
589 4782 : hirImplIndexesBuilt = true;
590 :
591 4782 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
592 32487 : auto resolve_item = [&] (const HIR::Type &type) -> HIR::Item * {
593 27705 : auto node_id = nr_ctx.lookup (type.get_mappings ().get_nodeid (),
594 : Resolver2_0::Namespace::Types);
595 27705 : if (!node_id.has_value ())
596 : return nullptr;
597 :
598 25190 : auto hir_id = lookup_node_to_hir (node_id.value ());
599 25190 : gcc_checking_assert (hir_id.has_value ());
600 25190 : if (!hir_id.has_value ())
601 : return nullptr;
602 :
603 25190 : auto item = hir.items.lookup (hir_id.value ());
604 25190 : return item.has_value () ? item.value () : nullptr;
605 4782 : };
606 :
607 4782 : iterate_impl_blocks ([&] (HirId, HIR::ImplBlock *impl) -> bool {
608 14609 : HIR::Item *self_item = resolve_item (impl->get_type ());
609 14609 : if (self_item != nullptr)
610 : {
611 6088 : auto kind = self_item->get_item_kind ();
612 6088 : if (kind == HIR::Item::ItemKind::Struct
613 6088 : || kind == HIR::Item::ItemKind::Enum
614 9 : || kind == HIR::Item::ItemKind::Union)
615 6087 : insert_adt_impl_mapping (self_item->get_mappings ().get_defid (),
616 : impl);
617 : }
618 :
619 14609 : if (impl->has_trait_ref ())
620 : {
621 13096 : HIR::Item *trait_item = resolve_item (impl->get_trait_ref ());
622 13096 : if (trait_item != nullptr
623 13096 : && trait_item->get_item_kind () == HIR::Item::ItemKind::Trait)
624 13028 : insert_trait_impl_mapping (trait_item->get_mappings ().get_defid (),
625 : impl);
626 : }
627 14609 : return true;
628 : });
629 : }
630 :
631 : void
632 770 : Mappings::iterate_adt_impl_items (
633 : DefId adt_id,
634 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
635 : {
636 3341 : auto iterate_impl = [&] (HIR::ImplBlock *impl) {
637 6074 : for (auto &item : impl->get_impl_items ())
638 : {
639 3503 : HIR::ImplItem *impl_item = item.get ();
640 3503 : HirId id = impl_item->get_impl_mappings ().get_hirid ();
641 3503 : if (!cb (id, impl_item, impl))
642 2571 : return false;
643 : }
644 : return true;
645 770 : };
646 :
647 770 : auto adt_impls = hirAdtImplMappings.find (adt_id);
648 770 : if (adt_impls != hirAdtImplMappings.end ())
649 1706 : for (auto *impl : adt_impls->second)
650 939 : if (!iterate_impl (impl))
651 0 : return;
652 :
653 : // Impl self types which cannot be classified as a concrete ADT include
654 : // blanket implementations such as `impl<T> Trait for T`. They must remain
655 : // candidates for every ADT receiver.
656 3866 : for (auto &mapping : hirImplBlockMappings)
657 : {
658 3096 : HIR::ImplBlock *impl = mapping.second;
659 3096 : if (hirIndexedAdtImpls.find (impl) == hirIndexedAdtImpls.end ())
660 1632 : if (!iterate_impl (impl))
661 0 : return;
662 : }
663 : }
664 :
665 : void
666 13028 : Mappings::insert_trait_impl_mapping (DefId trait_id, HIR::ImplBlock *impl)
667 : {
668 13028 : hirTraitImplMappings[trait_id].push_back (impl);
669 13028 : }
670 :
671 : void
672 1571 : Mappings::iterate_trait_impl_blocks_for_item (
673 : const std::string &name, std::function<bool (HirId, HIR::ImplBlock *)> cb)
674 : {
675 1571 : auto traits = hirTraitItemNameMappings.find (name);
676 1571 : if (traits == hirTraitItemNameMappings.end ())
677 1571 : return;
678 :
679 2186 : for (auto trait_id : traits->second)
680 : {
681 1094 : auto impls = hirTraitImplMappings.find (trait_id);
682 1094 : if (impls == hirTraitImplMappings.end ())
683 3 : continue;
684 :
685 3574 : for (auto *impl : impls->second)
686 2483 : if (!cb (impl->get_mappings ().get_hirid (), impl))
687 0 : return;
688 : }
689 : }
690 :
691 : void
692 4211 : Mappings::insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait)
693 : {
694 4211 : rust_assert (hirTraitItemsToTraitMappings.find (trait_item_id)
695 : == hirTraitItemsToTraitMappings.end ());
696 4211 : hirTraitItemsToTraitMappings[trait_item_id] = trait;
697 :
698 4211 : auto item = hir.trait_items.lookup (trait_item_id);
699 4211 : rust_assert (item.has_value ());
700 4211 : if (item.value ()->get_item_kind () != HIR::TraitItem::TraitItemKind::FUNC)
701 1356 : return;
702 :
703 3251 : auto *function = static_cast<HIR::TraitItemFunc *> (item.value ());
704 3251 : if (!function->get_decl ().is_method ())
705 : return;
706 :
707 5710 : auto name = function->get_decl ().get_function_name ().as_string ();
708 2855 : hirTraitItemNameMappings[name].push_back (
709 2855 : trait->get_mappings ().get_defid ());
710 2855 : }
711 :
712 : void
713 1280 : Mappings::iterate_trait_impl_items (
714 : DefId trait_id,
715 : std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
716 : {
717 1280 : auto trait_impls = hirTraitImplMappings.find (trait_id);
718 1280 : if (trait_impls == hirTraitImplMappings.end ())
719 : return;
720 :
721 6261 : for (auto *impl : trait_impls->second)
722 14862 : for (auto &item : impl->get_impl_items ())
723 : {
724 9881 : HIR::ImplItem *impl_item = item.get ();
725 9881 : HirId id = impl_item->get_impl_mappings ().get_hirid ();
726 9881 : if (!cb (id, impl_item, impl))
727 1280 : return;
728 : }
729 : }
730 :
731 : void
732 71146 : Mappings::iterate_trait_impl_blocks (
733 : DefId trait_id, std::function<bool (HirId, HIR::ImplBlock *)> cb)
734 : {
735 71146 : auto trait_impls = hirTraitImplMappings.find (trait_id);
736 71146 : if (trait_impls == hirTraitImplMappings.end ())
737 : return;
738 :
739 322743 : for (auto *impl : trait_impls->second)
740 290628 : if (!cb (impl->get_mappings ().get_hirid (), impl))
741 71146 : return;
742 : }
743 :
744 : void
745 4782 : Mappings::iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb)
746 : {
747 19391 : for (auto it = hirImplBlockMappings.begin ();
748 19391 : it != hirImplBlockMappings.end (); it++)
749 : {
750 14609 : HirId id = it->first;
751 14609 : HIR::ImplBlock *impl_block = it->second;
752 14609 : if (!cb (id, impl_block))
753 4782 : return;
754 : }
755 : }
756 :
757 : void
758 0 : Mappings::iterate_trait_items (
759 : std::function<bool (HIR::TraitItem *, HIR::Trait *)> cb)
760 : {
761 0 : for (auto it = hirTraitItemMappings.begin ();
762 0 : it != hirTraitItemMappings.end (); it++)
763 : {
764 0 : HirId trait_item_id = it->first;
765 0 : HIR::TraitItem *trait_item = it->second;
766 0 : HIR::Trait *trait = lookup_trait_item_mapping (trait_item_id);
767 :
768 0 : if (!cb (trait_item, trait))
769 0 : return;
770 : }
771 : }
772 :
773 : void
774 1816 : Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
775 : {
776 1816 : auto outer_attrs = macro->get_outer_attrs ();
777 1816 : bool should_be_builtin
778 1816 : = std::any_of (outer_attrs.begin (), outer_attrs.end (),
779 1462 : [] (AST::Attribute attr) {
780 1462 : return attr.get_path ()
781 1462 : == Values::Attributes::RUSTC_BUILTIN_MACRO;
782 : });
783 1816 : if (should_be_builtin)
784 : {
785 198 : auto builtin
786 198 : = MacroBuiltin::builtins.lookup (macro->get_rule_name ().as_string ());
787 198 : if (!builtin.has_value ())
788 : {
789 2 : rust_error_at (macro->get_locus (),
790 : "cannot find a built-in macro with name %qs",
791 2 : macro->get_rule_name ().as_string ().c_str ());
792 2 : return;
793 : }
794 :
795 196 : auto transcriber = MacroBuiltin::builtin_transcribers.find (
796 196 : macro->get_rule_name ().as_string ());
797 196 : macro->set_builtin_transcriber (transcriber->second);
798 : }
799 :
800 1814 : auto it = macroMappings.find (macro->get_node_id ());
801 1814 : rust_assert (it == macroMappings.end ());
802 :
803 1814 : macroMappings[macro->get_node_id ()] = {macro, crate.get_current_crate ()};
804 1816 : }
805 :
806 : tl::optional<AST::MacroRulesDefinition *>
807 122141 : Mappings::lookup_macro_def (NodeId id)
808 : {
809 122141 : auto it = macroMappings.find (id);
810 122141 : if (it == macroMappings.end ())
811 1816 : return tl::nullopt;
812 :
813 120325 : return it->second.first;
814 : }
815 :
816 : tl::optional<CrateNum>
817 527 : Mappings::lookup_macro_def_crate (NodeId id)
818 : {
819 527 : auto it = macroMappings.find (id);
820 527 : if (it == macroMappings.end ())
821 0 : return tl::nullopt;
822 :
823 527 : return it->second.second;
824 : }
825 :
826 : void
827 61687 : Mappings::insert_macro_invocation (AST::MacroInvocation &invoc,
828 : AST::MacroRulesDefinition *def)
829 : {
830 61687 : auto it = macroInvocations.find (invoc.get_node_id ());
831 61687 : rust_assert (it == macroInvocations.end ());
832 :
833 61687 : macroInvocations[invoc.get_node_id ()] = def;
834 61687 : }
835 :
836 : tl::optional<AST::MacroRulesDefinition *>
837 123683 : Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc)
838 : {
839 123683 : auto it = macroInvocations.find (invoc.get_node_id ());
840 123683 : if (it == macroInvocations.end ())
841 61999 : return tl::nullopt;
842 :
843 61684 : return it->second;
844 : }
845 :
846 : void
847 50 : Mappings::insert_exported_macro (AST::MacroRulesDefinition &def)
848 : {
849 50 : exportedMacros.emplace_back (def);
850 50 : }
851 :
852 : std::vector<AST::MacroRulesDefinition>
853 4446 : Mappings::get_exported_macros ()
854 : {
855 4446 : return exportedMacros;
856 : }
857 :
858 : void
859 0 : Mappings::insert_module_child (NodeId module, NodeId child)
860 : {
861 0 : auto it = module_child_map.find (module);
862 0 : if (it == module_child_map.end ())
863 0 : module_child_map.insert ({module, {child}});
864 : else
865 0 : it->second.emplace_back (child);
866 0 : }
867 :
868 : tl::optional<std::vector<NodeId> &>
869 0 : Mappings::lookup_module_children (NodeId module)
870 : {
871 0 : auto it = module_child_map.find (module);
872 0 : if (it == module_child_map.end ())
873 0 : return tl::nullopt;
874 :
875 0 : return it->second;
876 : }
877 :
878 : void
879 8208 : Mappings::insert_glob_container (NodeId id, AST::GlobContainer *container)
880 : {
881 8208 : rust_assert (glob_containers.find (id) == glob_containers.end ());
882 :
883 : // Crates have different memory managements that regular items
884 8208 : if (container->get_glob_container_kind () == AST::GlobContainer::Kind::Crate)
885 5098 : glob_containers[id] = crate.get_ast_crate_by_node_id_raw (id);
886 : else
887 3110 : glob_containers[id] = container;
888 8208 : }
889 :
890 : void
891 13844 : Mappings::insert_module_id (NodeId id)
892 : {
893 13844 : module_ids.insert (id);
894 13844 : }
895 :
896 : bool
897 175140 : Mappings::is_module (NodeId id)
898 : {
899 175140 : return module_ids.find (id) != module_ids.end ();
900 : }
901 :
902 : void
903 174 : Mappings::insert_extern_crate_id (NodeId id)
904 : {
905 174 : extern_crate_ids.insert (id);
906 174 : }
907 :
908 : bool
909 88 : Mappings::is_extern_crate (NodeId id)
910 : {
911 88 : return extern_crate_ids.find (id) != extern_crate_ids.end ();
912 : }
913 :
914 : tl::optional<AST::GlobContainer *>
915 77485 : Mappings::lookup_glob_container (NodeId id)
916 : {
917 77485 : auto it = glob_containers.find (id);
918 77485 : if (it == glob_containers.end ())
919 25310 : return tl::nullopt;
920 :
921 52175 : return {it->second};
922 : }
923 :
924 : void
925 0 : Mappings::insert_module_child_item (NodeId module,
926 : Resolver::CanonicalPath child)
927 : {
928 0 : rust_assert (!child.is_empty ());
929 0 : rust_assert (child.get_node_id () != UNKNOWN_NODEID);
930 :
931 0 : auto it = module_child_items.find (module);
932 0 : if (it == module_child_items.end ())
933 0 : module_child_items.insert ({module, {child}});
934 : else
935 0 : it->second.emplace_back (child);
936 0 : }
937 :
938 : tl::optional<std::vector<Resolver::CanonicalPath> &>
939 0 : Mappings::lookup_module_chidren_items (NodeId module)
940 : {
941 0 : auto it = module_child_items.find (module);
942 0 : if (it == module_child_items.end ())
943 0 : return tl::nullopt;
944 :
945 0 : return it->second;
946 : }
947 :
948 : tl::optional<Resolver::CanonicalPath &>
949 0 : Mappings::lookup_module_child (NodeId module, const std::string &item_name)
950 : {
951 0 : tl::optional<std::vector<Resolver::CanonicalPath> &> children
952 0 : = lookup_module_chidren_items (module);
953 0 : if (!children.has_value ())
954 0 : return tl::nullopt;
955 :
956 : // lookup the children to match the name if we can
957 0 : for (auto &child : children.value ())
958 : {
959 0 : const std::string &raw_identifier = child.get ();
960 0 : bool found = raw_identifier.compare (item_name) == 0;
961 0 : if (found)
962 0 : return child;
963 0 : }
964 :
965 0 : return tl::nullopt;
966 : }
967 :
968 : void
969 0 : Mappings::insert_child_item_to_parent_module_mapping (NodeId child_item,
970 : NodeId parent_module)
971 : {
972 0 : child_to_parent_module_map.insert ({child_item, parent_module});
973 0 : }
974 :
975 : tl::optional<NodeId>
976 0 : Mappings::lookup_parent_module (NodeId child_item)
977 : {
978 0 : auto it = child_to_parent_module_map.find (child_item);
979 0 : if (it == child_to_parent_module_map.end ())
980 0 : return tl::nullopt;
981 :
982 0 : return it->second;
983 : }
984 :
985 : bool
986 0 : Mappings::node_is_module (NodeId query)
987 : {
988 0 : return module_child_items.find (query) != module_child_items.end ();
989 : }
990 :
991 : void
992 37479 : Mappings::insert_ast_item (AST::Item *item)
993 : {
994 37479 : auto it = ast_item_mappings.find (item->get_node_id ());
995 37479 : rust_assert (it == ast_item_mappings.end ());
996 :
997 37479 : ast_item_mappings[item->get_node_id ()] = item;
998 37479 : }
999 :
1000 : tl::optional<AST::Item *>
1001 0 : Mappings::lookup_ast_item (NodeId id)
1002 : {
1003 0 : auto it = ast_item_mappings.find (id);
1004 0 : if (it == ast_item_mappings.end ())
1005 0 : return tl::nullopt;
1006 :
1007 0 : return it->second;
1008 : }
1009 :
1010 : HIR::ImplBlock *
1011 67924 : Mappings::lookup_builtin_marker ()
1012 : {
1013 67924 : return builtinMarker;
1014 : }
1015 :
1016 : // FIXME: Before merging: Should we remove the `locus` parameter here? since
1017 : // lang items are looked up mostly for code generation, it doesn't make sense to
1018 : // error out on the locus of the node trying to access an inexistant lang item
1019 : DefId
1020 8894 : Mappings::get_lang_item (LangItem::Kind item_type, location_t locus)
1021 : {
1022 8894 : if (auto item = lookup_lang_item (item_type))
1023 8893 : return *item;
1024 :
1025 2 : rust_fatal_error (locus, "failed to find lang item %s",
1026 1 : LangItem::ToString (item_type).c_str ());
1027 : }
1028 :
1029 : tl::optional<HIR::TraitItem *>
1030 43 : Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t locus)
1031 : {
1032 43 : DefId trait_item_id = get_lang_item (item, locus);
1033 43 : return lookup_trait_item_defid (trait_item_id);
1034 : }
1035 :
1036 : void
1037 3893 : Mappings::insert_lang_item (LangItem::Kind item_type, DefId id)
1038 : {
1039 3893 : auto it = lang_item_mappings.find (item_type);
1040 3893 : rust_assert (it == lang_item_mappings.end ());
1041 :
1042 3893 : lang_item_mappings[item_type] = id;
1043 3893 : }
1044 :
1045 : tl::optional<DefId &>
1046 230586 : Mappings::lookup_lang_item (LangItem::Kind item_type)
1047 : {
1048 230586 : auto it = lang_item_mappings.find (item_type);
1049 230586 : if (it == lang_item_mappings.end ())
1050 148854 : return tl::nullopt;
1051 :
1052 81732 : return it->second;
1053 : }
1054 :
1055 : void
1056 3928 : Mappings::insert_lang_item_node (LangItem::Kind item_type, NodeId node_id)
1057 : {
1058 3928 : auto it = lang_item_nodes.find (item_type);
1059 3928 : rust_assert (it == lang_item_nodes.end ());
1060 :
1061 3928 : lang_item_nodes.insert ({item_type, node_id});
1062 3928 : }
1063 :
1064 : tl::optional<NodeId &>
1065 4089 : Mappings::lookup_lang_item_node (LangItem::Kind item_type)
1066 : {
1067 4089 : auto it = lang_item_nodes.find (item_type);
1068 4089 : if (it == lang_item_nodes.end ())
1069 1 : return tl::nullopt;
1070 :
1071 4088 : return it->second;
1072 : }
1073 :
1074 : NodeId
1075 4089 : Mappings::get_lang_item_node (LangItem::Kind item_type)
1076 : {
1077 4089 : if (auto lookup = lookup_lang_item_node (item_type))
1078 4088 : return *lookup;
1079 :
1080 2 : rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs",
1081 1 : LangItem::PrettyString (item_type).c_str ());
1082 : }
1083 :
1084 : std::string &
1085 1525 : Mappings::get_lang_item_identifier (LangItem::Kind item_type)
1086 : {
1087 : // Lang item names are hardcoded because they're only required for metadata
1088 : // dump which will get removed at some point
1089 1525 : static std::unordered_map<LangItem::Kind, std::string> identifiers
1090 101 : = {{LangItem::Kind::COPY, "Copy"},
1091 101 : {LangItem::Kind::CLONE, "Clone"},
1092 101 : {LangItem::Kind::STRUCTURAL_PEQ, "StructuralPartialEq"},
1093 101 : {LangItem::Kind::STRUCTURAL_TEQ, "StructuralEq"},
1094 101 : {LangItem::Kind::SIZED, "Sized"},
1095 101 : {LangItem::Kind::EQ, "PartialEq"},
1096 2333 : {LangItem::Kind::PHANTOM_DATA, "PhantomData"}};
1097 1525 : auto result = identifiers.find (item_type);
1098 1525 : if (result != identifiers.cend ())
1099 1525 : return result->second;
1100 0 : rust_unreachable ();
1101 : }
1102 :
1103 : void
1104 22 : Mappings::insert_auto_trait (HIR::Trait *trait)
1105 : {
1106 22 : auto_traits.emplace_back (trait);
1107 22 : }
1108 :
1109 : std::vector<HIR::Trait *> &
1110 68102 : Mappings::get_auto_traits ()
1111 : {
1112 68102 : return auto_traits;
1113 : }
1114 :
1115 : void
1116 117 : Mappings::add_capture (NodeId closure, NodeId definition)
1117 : {
1118 117 : auto cap = captures.find (closure);
1119 117 : if (cap == captures.end ())
1120 76 : captures[closure] = {definition};
1121 : else
1122 41 : cap->second.push_back (definition);
1123 117 : }
1124 :
1125 : tl::optional<std::vector<NodeId>>
1126 66 : Mappings::lookup_captures (NodeId closure)
1127 : {
1128 66 : auto cap = captures.find (closure);
1129 66 : if (cap == captures.end ())
1130 45 : return tl::nullopt;
1131 : else
1132 21 : return cap->second;
1133 : }
1134 :
1135 : void
1136 1681 : Mappings::add_derived_node (NodeId node_id)
1137 : {
1138 1681 : derived_nodes.insert (node_id);
1139 1681 : }
1140 :
1141 : bool
1142 0 : Mappings::is_derived_node (NodeId node_id)
1143 : {
1144 0 : return derived_nodes.find (node_id) != derived_nodes.end ();
1145 : }
1146 :
1147 : void
1148 505760 : Mappings::add_function_node (NodeId node_id)
1149 : {
1150 505760 : function_nodes.insert (node_id);
1151 505760 : }
1152 :
1153 : bool
1154 1021 : Mappings::is_function_node (NodeId node_id)
1155 : {
1156 1021 : return function_nodes.find (node_id) != function_nodes.end ();
1157 : }
1158 :
1159 : } // namespace Analysis
1160 : } // namespace Rust
|