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