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