Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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-type-check.h"
20 : : #include "rust-type-util.h"
21 : :
22 : : namespace Rust {
23 : : namespace Resolver {
24 : :
25 : : TypeCheckContext *
26 : 7820806 : TypeCheckContext::get ()
27 : : {
28 : 7820806 : static TypeCheckContext *instance;
29 : 7820806 : if (instance == nullptr)
30 : 4939 : instance = new TypeCheckContext ();
31 : :
32 : 7820806 : return instance;
33 : : }
34 : :
35 : 4939 : TypeCheckContext::TypeCheckContext () { lifetime_resolver_stack.emplace (); }
36 : :
37 : 0 : TypeCheckContext::~TypeCheckContext () {}
38 : :
39 : : bool
40 : 0 : TypeCheckContext::lookup_builtin (NodeId id, TyTy::BaseType **type)
41 : : {
42 : 0 : auto ref_it = node_id_refs.find (id);
43 : 0 : if (ref_it == node_id_refs.end ())
44 : : return false;
45 : :
46 : 0 : auto it = resolved.find (ref_it->second);
47 : 0 : if (it == resolved.end ())
48 : : return false;
49 : :
50 : 0 : *type = it->second;
51 : 0 : return true;
52 : : }
53 : :
54 : : bool
55 : 64141 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
56 : : {
57 : 656939 : for (auto &builtin : builtins)
58 : : {
59 : 656939 : if (name.compare (builtin->as_string ()) == 0)
60 : : {
61 : 64141 : *type = builtin.get ();
62 : 64141 : return true;
63 : : }
64 : : }
65 : : return false;
66 : : }
67 : :
68 : : void
69 : 112879 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
70 : : {
71 : 112879 : node_id_refs[ref] = id;
72 : 112879 : resolved[id] = type;
73 : 112879 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
74 : 112879 : }
75 : :
76 : : const std::vector<std::unique_ptr<TyTy::BaseType>> &
77 : 4254 : TypeCheckContext::get_builtins () const
78 : : {
79 : 4254 : return builtins;
80 : : }
81 : :
82 : : void
83 : 529255 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
84 : : TyTy::BaseType *type)
85 : : {
86 : 529255 : rust_assert (type != nullptr);
87 : 529255 : NodeId ref = mappings.get_nodeid ();
88 : 529255 : HirId id = mappings.get_hirid ();
89 : 529255 : node_id_refs[ref] = id;
90 : 529255 : resolved[id] = type;
91 : 529255 : }
92 : :
93 : : void
94 : 43917 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
95 : : {
96 : 43917 : rust_assert (type != nullptr);
97 : 43917 : resolved[id] = type;
98 : 43917 : }
99 : :
100 : : bool
101 : 11275948 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
102 : : {
103 : 11275948 : auto it = resolved.find (id);
104 : 11275948 : if (it == resolved.end ())
105 : : return false;
106 : :
107 : 11138987 : *type = it->second;
108 : 11138987 : return true;
109 : : }
110 : :
111 : : void
112 : 2967 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
113 : : {
114 : 2967 : auto it = resolved.find (ty->get_ref ());
115 : 2967 : if (it == resolved.end ())
116 : 2967 : return;
117 : :
118 : 2967 : resolved.erase (it);
119 : : }
120 : :
121 : : void
122 : 0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
123 : : {
124 : 0 : rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
125 : 0 : node_id_refs[ref] = id;
126 : 0 : }
127 : :
128 : : bool
129 : 0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
130 : : {
131 : 0 : auto it = node_id_refs.find (ref);
132 : 0 : if (it == node_id_refs.end ())
133 : : return false;
134 : :
135 : 0 : *id = it->second;
136 : 0 : return true;
137 : : }
138 : :
139 : : bool
140 : 1667 : TypeCheckContext::have_function_context () const
141 : : {
142 : 1667 : return !return_type_stack.empty ();
143 : : }
144 : :
145 : : TyTy::BaseType *
146 : 553 : TypeCheckContext::peek_return_type ()
147 : : {
148 : 553 : rust_assert (!return_type_stack.empty ());
149 : 553 : return return_type_stack.back ().second;
150 : : }
151 : :
152 : : void
153 : 12743 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
154 : : TyTy::BaseType *return_type)
155 : : {
156 : 12743 : return_type_stack.push_back ({std::move (item), return_type});
157 : 12743 : }
158 : :
159 : : void
160 : 12743 : TypeCheckContext::pop_return_type ()
161 : : {
162 : 12743 : rust_assert (!return_type_stack.empty ());
163 : 12743 : return_type_stack.pop_back ();
164 : 12743 : }
165 : :
166 : : TypeCheckContextItem
167 : 1173 : TypeCheckContext::peek_context ()
168 : : {
169 : 1173 : rust_assert (!return_type_stack.empty ());
170 : 1173 : return return_type_stack.back ().first;
171 : : }
172 : :
173 : : StackedContexts<TypeCheckBlockContextItem> &
174 : 22422 : TypeCheckContext::block_context ()
175 : : {
176 : 22422 : return block_stack;
177 : : }
178 : :
179 : : void
180 : 4379 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
181 : : {
182 : 431078 : for (auto it = resolved.begin (); it != resolved.end (); it++)
183 : : {
184 : 426699 : if (!cb (it->first, it->second))
185 : 4379 : return;
186 : : }
187 : : }
188 : :
189 : : bool
190 : 106 : TypeCheckContext::have_loop_context () const
191 : : {
192 : 106 : return !loop_type_stack.empty ();
193 : : }
194 : :
195 : : void
196 : 124 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
197 : : {
198 : 124 : TyTy::BaseType *infer_var
199 : : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
200 : 124 : TyTy::InferType::TypeHint::Default (), locus);
201 : 124 : loop_type_stack.push_back (infer_var);
202 : 124 : }
203 : :
204 : : void
205 : 70 : TypeCheckContext::push_new_while_loop_context (HirId id)
206 : : {
207 : 70 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
208 : 70 : loop_type_stack.push_back (infer_var);
209 : 70 : }
210 : :
211 : : TyTy::BaseType *
212 : 216 : TypeCheckContext::peek_loop_context ()
213 : : {
214 : 216 : return loop_type_stack.back ();
215 : : }
216 : :
217 : : TyTy::BaseType *
218 : 194 : TypeCheckContext::pop_loop_context ()
219 : : {
220 : 194 : auto back = peek_loop_context ();
221 : 194 : loop_type_stack.pop_back ();
222 : 194 : return back;
223 : : }
224 : :
225 : : void
226 : 18 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
227 : : {
228 : 18 : loop_type_stack.pop_back ();
229 : 18 : loop_type_stack.push_back (val);
230 : 18 : }
231 : :
232 : : void
233 : 3139 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
234 : : {
235 : 3139 : rust_assert (trait_context.find (id) == trait_context.end ());
236 : 3139 : trait_context.emplace (id, std::move (ref));
237 : 3139 : }
238 : :
239 : : bool
240 : 465610 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
241 : : {
242 : 465610 : auto it = trait_context.find (id);
243 : 465610 : if (it == trait_context.end ())
244 : : return false;
245 : :
246 : 443535 : *ref = &it->second;
247 : 443535 : return true;
248 : : }
249 : :
250 : : void
251 : 3947 : TypeCheckContext::insert_associated_trait_impl (
252 : : HirId id, AssociatedImplTrait &&associated)
253 : : {
254 : 3947 : rust_assert (associated_impl_traits.find (id)
255 : : == associated_impl_traits.end ());
256 : 3947 : associated_impl_traits.emplace (id, std::move (associated));
257 : 3947 : }
258 : :
259 : : bool
260 : 44790 : TypeCheckContext::lookup_associated_trait_impl (
261 : : HirId id, AssociatedImplTrait **associated)
262 : : {
263 : 44790 : auto it = associated_impl_traits.find (id);
264 : 44790 : if (it == associated_impl_traits.end ())
265 : : return false;
266 : :
267 : 21362 : *associated = &it->second;
268 : 21362 : return true;
269 : : }
270 : :
271 : : void
272 : 3042 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
273 : : {
274 : 3042 : associated_type_mappings[id] = mapping;
275 : 3042 : }
276 : :
277 : : void
278 : 1218 : TypeCheckContext::clear_associated_type_mapping (HirId id)
279 : : {
280 : 1218 : auto it = associated_type_mappings.find (id);
281 : 1218 : if (it != associated_type_mappings.end ())
282 : 1214 : associated_type_mappings.erase (it);
283 : 1218 : }
284 : :
285 : : // lookup any associated type mappings, the out parameter of mapping is
286 : : // allowed to be nullptr which allows this interface to do a simple does exist
287 : : // check
288 : : bool
289 : 45554 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
290 : : {
291 : 45554 : auto it = associated_type_mappings.find (id);
292 : 45554 : if (it == associated_type_mappings.end ())
293 : : return false;
294 : :
295 : 24816 : if (mapping != nullptr)
296 : 24816 : *mapping = it->second;
297 : :
298 : : return true;
299 : : }
300 : :
301 : : void
302 : 3947 : TypeCheckContext::insert_associated_impl_mapping (
303 : : HirId trait_id, const TyTy::BaseType *impl_type, HirId impl_id)
304 : : {
305 : 3947 : auto it = associated_traits_to_impls.find (trait_id);
306 : 3947 : if (it == associated_traits_to_impls.end ())
307 : : {
308 : 1380 : associated_traits_to_impls[trait_id] = {};
309 : : }
310 : :
311 : 3947 : associated_traits_to_impls[trait_id].push_back ({impl_type, impl_id});
312 : 3947 : }
313 : :
314 : : bool
315 : 0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (
316 : : HirId trait_id, const TyTy::BaseType *self, HirId *mapping)
317 : : {
318 : 0 : auto it = associated_traits_to_impls.find (trait_id);
319 : 0 : if (it == associated_traits_to_impls.end ())
320 : : return false;
321 : :
322 : 0 : for (auto &item : it->second)
323 : : {
324 : 0 : if (item.first->can_eq (self, false))
325 : : {
326 : 0 : *mapping = item.second;
327 : 0 : return true;
328 : : }
329 : : }
330 : : return false;
331 : : }
332 : :
333 : : void
334 : 34835 : TypeCheckContext::insert_autoderef_mappings (
335 : : HirId id, std::vector<Adjustment> &&adjustments)
336 : : {
337 : 34835 : autoderef_mappings.emplace (id, std::move (adjustments));
338 : 34835 : }
339 : :
340 : : bool
341 : 40973 : TypeCheckContext::lookup_autoderef_mappings (
342 : : HirId id, std::vector<Adjustment> **adjustments)
343 : : {
344 : 40973 : auto it = autoderef_mappings.find (id);
345 : 40973 : if (it == autoderef_mappings.end ())
346 : : return false;
347 : :
348 : 26594 : *adjustments = &it->second;
349 : 26594 : return true;
350 : : }
351 : :
352 : : void
353 : 4638 : TypeCheckContext::insert_cast_autoderef_mappings (
354 : : HirId id, std::vector<Adjustment> &&adjustments)
355 : : {
356 : 4638 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
357 : 4638 : }
358 : :
359 : : bool
360 : 4274 : TypeCheckContext::lookup_cast_autoderef_mappings (
361 : : HirId id, std::vector<Adjustment> **adjustments)
362 : : {
363 : 4274 : auto it = cast_autoderef_mappings.find (id);
364 : 4274 : if (it == cast_autoderef_mappings.end ())
365 : : return false;
366 : :
367 : 4274 : *adjustments = &it->second;
368 : 4274 : return true;
369 : : }
370 : :
371 : : void
372 : 1750 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
373 : : {
374 : 1750 : auto it = variants.find (id);
375 : 1750 : rust_assert (it == variants.end ());
376 : :
377 : 1750 : variants[id] = variant;
378 : 1750 : }
379 : :
380 : : bool
381 : 3416 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
382 : : {
383 : 3416 : auto it = variants.find (id);
384 : 3416 : if (it == variants.end ())
385 : : return false;
386 : :
387 : 3410 : *variant = it->second;
388 : 3410 : return true;
389 : : }
390 : :
391 : : void
392 : 406 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
393 : : {
394 : 406 : auto it = operator_overloads.find (id);
395 : 406 : rust_assert (it == operator_overloads.end ());
396 : :
397 : 406 : operator_overloads[id] = call_site;
398 : 406 : }
399 : :
400 : : bool
401 : 16761 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
402 : : {
403 : 16761 : auto it = operator_overloads.find (id);
404 : 16761 : if (it == operator_overloads.end ())
405 : : return false;
406 : :
407 : 721 : *call = it->second;
408 : 721 : return true;
409 : : }
410 : :
411 : : void
412 : 4971 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
413 : : {
414 : 4971 : unconstrained[id] = status;
415 : 4971 : }
416 : :
417 : : bool
418 : 21321 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
419 : : {
420 : 21321 : auto it = unconstrained.find (id);
421 : 21321 : bool found = it != unconstrained.end ();
422 : 21321 : if (!found)
423 : : return false;
424 : :
425 : 16350 : *result = it->second;
426 : 16350 : return true;
427 : : }
428 : :
429 : : void
430 : 5357 : TypeCheckContext::insert_resolved_predicate (HirId id,
431 : : TyTy::TypeBoundPredicate predicate)
432 : : {
433 : : // auto it = predicates.find (id);
434 : : // rust_assert (it == predicates.end ());
435 : :
436 : 5357 : predicates.insert ({id, predicate});
437 : 5357 : }
438 : :
439 : : bool
440 : 21568 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
441 : : {
442 : 21568 : auto it = predicates.find (id);
443 : 21568 : bool found = it != predicates.end ();
444 : 21568 : if (!found)
445 : : return false;
446 : :
447 : 16193 : *result = it->second;
448 : 16193 : return true;
449 : : }
450 : :
451 : : void
452 : 7169 : TypeCheckContext::insert_query (HirId id)
453 : : {
454 : 7169 : querys_in_progress.insert (id);
455 : 7169 : }
456 : :
457 : : void
458 : 7169 : TypeCheckContext::query_completed (HirId id)
459 : : {
460 : 7169 : querys_in_progress.erase (id);
461 : 7169 : }
462 : :
463 : : bool
464 : 714720 : TypeCheckContext::query_in_progress (HirId id) const
465 : : {
466 : 714720 : return querys_in_progress.find (id) != querys_in_progress.end ();
467 : : }
468 : :
469 : : void
470 : 3155 : TypeCheckContext::insert_trait_query (DefId id)
471 : : {
472 : 3155 : trait_queries_in_progress.insert (id);
473 : 3155 : }
474 : :
475 : : void
476 : 3155 : TypeCheckContext::trait_query_completed (DefId id)
477 : : {
478 : 3155 : trait_queries_in_progress.erase (id);
479 : 3155 : }
480 : :
481 : : bool
482 : 555253 : TypeCheckContext::trait_query_in_progress (DefId id) const
483 : : {
484 : 555253 : return trait_queries_in_progress.find (id)
485 : 555253 : != trait_queries_in_progress.end ();
486 : : }
487 : :
488 : : Lifetime
489 : 1672 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
490 : : {
491 : 1672 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
492 : : {
493 : 1670 : auto maybe_interned = lookup_lifetime (lifetime);
494 : 1670 : if (maybe_interned)
495 : 1559 : return *maybe_interned;
496 : :
497 : 111 : auto interned = next_lifetime_index.next ();
498 : 111 : lifetime_name_interner[lifetime.get_name ()] = interned;
499 : 111 : return interned;
500 : : }
501 : 2 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
502 : : {
503 : 2 : return next_lifetime_index.next ();
504 : : }
505 : 0 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
506 : : {
507 : 0 : return Lifetime::static_lifetime ();
508 : : }
509 : 0 : rust_unreachable ();
510 : : }
511 : :
512 : : tl::optional<Lifetime>
513 : 11801 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
514 : : {
515 : 11801 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
516 : : {
517 : 2062 : if (lifetime.get_name () == "static")
518 : : {
519 : 2 : rich_location r (line_table, lifetime.get_locus ());
520 : 2 : r.add_fixit_insert_after (lifetime.get_locus (),
521 : : "static is a reserved lifetime name");
522 : 2 : rust_error_at (r, ErrorCode::E0262,
523 : : "invalid lifetime parameter name: %qs",
524 : 2 : lifetime.get_name ().c_str ());
525 : 2 : return tl::nullopt;
526 : 2 : }
527 : 2060 : const auto name = lifetime.get_name ();
528 : 2060 : auto it = lifetime_name_interner.find (name);
529 : 2060 : if (it == lifetime_name_interner.end ())
530 : 113 : return tl::nullopt;
531 : 1947 : return it->second;
532 : 2060 : }
533 : 9739 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
534 : : {
535 : 9664 : return Lifetime::anonymous_lifetime ();
536 : : }
537 : 75 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
538 : : {
539 : 75 : return Lifetime::static_lifetime ();
540 : : }
541 : 0 : rust_unreachable ();
542 : : }
543 : :
544 : : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
545 : 10131 : TypeCheckContext::lookup_and_resolve_lifetime (
546 : : const HIR::Lifetime &lifetime) const
547 : : {
548 : 10131 : auto maybe_interned = lookup_lifetime (lifetime);
549 : 10131 : if (!maybe_interned)
550 : 4 : return tl::nullopt;
551 : :
552 : 10127 : return get_lifetime_resolver ().resolve (maybe_interned.value ());
553 : : }
554 : : void
555 : 16 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
556 : : {
557 : 16 : get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
558 : 16 : }
559 : :
560 : : WARN_UNUSED_RESULT std::vector<TyTy::Region>
561 : 7564 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
562 : : {
563 : 7564 : std::vector<TyTy::Region> regions;
564 : 7610 : for (const auto &lifetime : args.get_lifetime_args ())
565 : : {
566 : 48 : auto resolved = lookup_and_resolve_lifetime (lifetime);
567 : 48 : if (!resolved)
568 : : {
569 : 2 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
570 : 2 : return {};
571 : : }
572 : 46 : regions.push_back (*resolved);
573 : : }
574 : 7562 : return regions;
575 : 7564 : }
576 : :
577 : : void
578 : 4379 : TypeCheckContext::compute_inference_variables (bool error)
579 : : {
580 : 4379 : auto &mappings = Analysis::Mappings::get ();
581 : :
582 : : // default inference variables if possible
583 : 4379 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
584 : : // nothing to do
585 : 426699 : if (ty->get_kind () != TyTy::TypeKind::INFER)
586 : : return true;
587 : :
588 : 39067 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
589 : 39067 : TyTy::BaseType *default_type;
590 : :
591 : 39067 : rust_debug_loc (mappings.lookup_location (id),
592 : : "trying to default infer-var: %s",
593 : 39067 : infer_var->as_string ().c_str ());
594 : 39067 : bool ok = infer_var->default_type (&default_type);
595 : 39067 : if (!ok)
596 : : {
597 : 24 : if (error)
598 : 24 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
599 : : "type annotations needed");
600 : 24 : return true;
601 : : }
602 : :
603 : 39043 : auto result
604 : 39043 : = unify_site (id, TyTy::TyWithLocation (ty),
605 : 39043 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
606 : 39043 : rust_assert (result);
607 : 39043 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
608 : 39043 : result->set_ref (id);
609 : 39043 : insert_type (Analysis::NodeMapping (mappings.get_current_crate (), 0, id,
610 : 39043 : UNKNOWN_LOCAL_DEFID),
611 : : result);
612 : :
613 : 39043 : return true;
614 : : });
615 : 4379 : }
616 : :
617 : : TyTy::VarianceAnalysis::CrateCtx &
618 : 8021 : TypeCheckContext::get_variance_analysis_ctx ()
619 : : {
620 : 8021 : return variance_analysis_ctx;
621 : : }
622 : :
623 : : // TypeCheckContextItem
624 : :
625 : 7765 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
626 : :
627 : 5839 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
628 : : HIR::Function *item)
629 : 5839 : : impl_item ({impl_block, item})
630 : 5839 : {}
631 : :
632 : 251 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
633 : 251 : : trait_item (trait_item)
634 : 251 : {}
635 : :
636 : 6653 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
637 : 6653 : : type (ItemType::ITEM), item (item)
638 : 6653 : {}
639 : :
640 : 5839 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
641 : 5839 : HIR::Function *item)
642 : 5839 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
643 : 5839 : {}
644 : :
645 : 251 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
646 : 251 : : type (ItemType::TRAIT_ITEM), item (trait_item)
647 : 251 : {}
648 : :
649 : 27634 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
650 : 27634 : : type (other.type), item (other.item)
651 : : {
652 : 27634 : switch (other.type)
653 : : {
654 : : case ITEM:
655 : : item.item = other.item.item;
656 : : break;
657 : :
658 : 12963 : case IMPL_ITEM:
659 : 12963 : item.impl_item = other.item.impl_item;
660 : 12963 : break;
661 : :
662 : : case TRAIT_ITEM:
663 : : item.trait_item = other.item.trait_item;
664 : : break;
665 : :
666 : 0 : case ERROR:
667 : 0 : item.item = nullptr;
668 : 0 : break;
669 : : }
670 : 27634 : }
671 : :
672 : 1112 : TypeCheckContextItem::TypeCheckContextItem ()
673 : 1112 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
674 : 1112 : {}
675 : :
676 : : TypeCheckContextItem &
677 : 1112 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
678 : : {
679 : 1112 : type = other.type;
680 : 1112 : switch (other.type)
681 : : {
682 : 391 : case ITEM:
683 : 391 : item.item = other.item.item;
684 : 391 : break;
685 : :
686 : 721 : case IMPL_ITEM:
687 : 721 : item.impl_item = other.item.impl_item;
688 : 721 : break;
689 : :
690 : 0 : case TRAIT_ITEM:
691 : 0 : item.trait_item = other.item.trait_item;
692 : 0 : break;
693 : :
694 : 0 : case ERROR:
695 : 0 : item.item = nullptr;
696 : 0 : break;
697 : : }
698 : :
699 : 1112 : return *this;
700 : : }
701 : :
702 : : TypeCheckContextItem
703 : 1112 : TypeCheckContextItem::get_error ()
704 : : {
705 : 1112 : return TypeCheckContextItem ();
706 : : }
707 : :
708 : : bool
709 : 0 : TypeCheckContextItem::is_error () const
710 : : {
711 : 0 : return type == ERROR;
712 : : }
713 : :
714 : : HIR::Function *
715 : 59 : TypeCheckContextItem::get_item ()
716 : : {
717 : 59 : rust_assert (get_type () == ItemType::ITEM);
718 : 59 : return item.item;
719 : : }
720 : :
721 : : std::pair<HIR::ImplBlock *, HIR::Function *> &
722 : 603 : TypeCheckContextItem::get_impl_item ()
723 : : {
724 : 603 : rust_assert (get_type () == ItemType::IMPL_ITEM);
725 : 603 : return item.impl_item;
726 : : }
727 : :
728 : : HIR::TraitItemFunc *
729 : 2 : TypeCheckContextItem::get_trait_item ()
730 : : {
731 : 2 : rust_assert (get_type () == ItemType::TRAIT_ITEM);
732 : 2 : return item.trait_item;
733 : : }
734 : :
735 : : TypeCheckContextItem::ItemType
736 : 2815 : TypeCheckContextItem::get_type () const
737 : : {
738 : 2815 : return type;
739 : : }
740 : :
741 : : TyTy::FnType *
742 : 61 : TypeCheckContextItem::get_context_type ()
743 : : {
744 : 61 : auto &context = *TypeCheckContext::get ();
745 : :
746 : 61 : HirId reference = UNKNOWN_HIRID;
747 : 61 : switch (get_type ())
748 : : {
749 : 59 : case ITEM:
750 : 59 : reference = get_item ()->get_mappings ().get_hirid ();
751 : 59 : break;
752 : :
753 : 0 : case IMPL_ITEM:
754 : 0 : reference = get_impl_item ().second->get_mappings ().get_hirid ();
755 : 0 : break;
756 : :
757 : 2 : case TRAIT_ITEM:
758 : 2 : reference = get_trait_item ()->get_mappings ().get_hirid ();
759 : 2 : break;
760 : :
761 : 0 : case ERROR:
762 : 0 : rust_unreachable ();
763 : : return nullptr;
764 : : }
765 : :
766 : 61 : rust_assert (reference != UNKNOWN_HIRID);
767 : :
768 : 61 : TyTy::BaseType *lookup = nullptr;
769 : 61 : bool ok = context.lookup_type (reference, &lookup);
770 : 61 : rust_assert (ok);
771 : 61 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
772 : 61 : return static_cast<TyTy::FnType *> (lookup);
773 : : }
774 : :
775 : : DefId
776 : 1119 : TypeCheckContextItem::get_defid () const
777 : : {
778 : 1119 : switch (get_type ())
779 : : {
780 : 422 : case ITEM:
781 : 422 : return item.item->get_mappings ().get_defid ();
782 : :
783 : 697 : case IMPL_ITEM:
784 : 697 : return item.impl_item.second->get_mappings ().get_defid ();
785 : :
786 : 0 : case TRAIT_ITEM:
787 : 0 : return item.trait_item->get_mappings ().get_defid ();
788 : :
789 : 0 : case ERROR:
790 : 0 : return UNKNOWN_DEFID;
791 : : }
792 : :
793 : 0 : return UNKNOWN_DEFID;
794 : : }
795 : :
796 : : // TypeCheckBlockContextItem
797 : :
798 : 7087 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
799 : :
800 : 3139 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
801 : :
802 : 7087 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
803 : 7087 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
804 : 7087 : {}
805 : :
806 : 3139 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
807 : 3139 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
808 : 3139 : {}
809 : :
810 : : bool
811 : 906 : TypeCheckBlockContextItem::is_impl_block () const
812 : : {
813 : 906 : return type == IMPL_BLOCK;
814 : : }
815 : :
816 : : bool
817 : 158 : TypeCheckBlockContextItem::is_trait_block () const
818 : : {
819 : 158 : return type == TRAIT;
820 : : }
821 : :
822 : : HIR::ImplBlock &
823 : 158 : TypeCheckBlockContextItem::get_impl_block ()
824 : : {
825 : 158 : return *(item.block);
826 : : }
827 : :
828 : : HIR::Trait &
829 : 0 : TypeCheckBlockContextItem::get_trait ()
830 : : {
831 : 0 : return *(item.trait);
832 : : }
833 : :
834 : : } // namespace Resolver
835 : : } // namespace Rust
|