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 35550685 : TypeCheckContext::get ()
28 : {
29 35550685 : static TypeCheckContext *instance;
30 35550685 : if (instance == nullptr)
31 4908 : instance = new TypeCheckContext ();
32 :
33 35550685 : return instance;
34 : }
35 :
36 4908 : 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 36298 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : {
58 413500 : for (auto &builtin : builtins)
59 : {
60 413500 : if (name.compare (builtin->as_string ()) == 0)
61 : {
62 36298 : *type = builtin.get ();
63 36298 : return true;
64 : }
65 : }
66 : return false;
67 : }
68 :
69 : void
70 94164 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : {
72 94164 : node_id_refs[ref] = id;
73 94164 : resolved[id] = type;
74 94164 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 94164 : }
76 :
77 : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 4645 : TypeCheckContext::get_builtins () const
79 : {
80 4645 : return builtins;
81 : }
82 :
83 : void
84 495637 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : TyTy::BaseType *type)
86 : {
87 495637 : rust_assert (type != nullptr);
88 495637 : NodeId ref = mappings.get_nodeid ();
89 495637 : HirId id = mappings.get_hirid ();
90 495637 : node_id_refs[ref] = id;
91 495637 : resolved[id] = type;
92 495637 : }
93 :
94 : void
95 338622 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : {
97 338622 : rust_assert (type != nullptr);
98 338622 : resolved[id] = type;
99 338622 : }
100 :
101 : bool
102 23689129 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
103 : {
104 23689129 : auto it = resolved.find (id);
105 23689129 : if (it == resolved.end ())
106 : return false;
107 :
108 23485607 : *type = it->second;
109 23485607 : return true;
110 : }
111 :
112 : void
113 175220 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
114 : {
115 175220 : auto it = resolved.find (ty->get_ref ());
116 175220 : if (it == resolved.end ())
117 175220 : return;
118 :
119 175220 : 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 16363 : TypeCheckContext::have_function_context () const
142 : {
143 16363 : return !return_type_stack.empty ();
144 : }
145 :
146 : TyTy::BaseType *
147 557 : TypeCheckContext::peek_return_type ()
148 : {
149 557 : rust_assert (!return_type_stack.empty ());
150 557 : return return_type_stack.back ().second;
151 : }
152 :
153 : void
154 14640 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
155 : TyTy::BaseType *return_type)
156 : {
157 14640 : return_type_stack.emplace_back (std::move (item), return_type);
158 14640 : }
159 :
160 : void
161 14640 : TypeCheckContext::pop_return_type ()
162 : {
163 14640 : rust_assert (!return_type_stack.empty ());
164 14640 : return_type_stack.pop_back ();
165 14640 : }
166 :
167 : TypeCheckContextItem
168 15787 : TypeCheckContext::peek_context ()
169 : {
170 15787 : rust_assert (!return_type_stack.empty ());
171 15787 : return return_type_stack.back ().first;
172 : }
173 :
174 : void
175 51616 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
176 : {
177 51616 : expected_type_stack.push_back (expected);
178 51616 : }
179 :
180 : void
181 51616 : TypeCheckContext::pop_expected_type ()
182 : {
183 51616 : rust_assert (!expected_type_stack.empty ());
184 51616 : expected_type_stack.pop_back ();
185 51616 : }
186 :
187 : TyTy::BaseType *
188 34481 : TypeCheckContext::peek_expected_type () const
189 : {
190 34481 : if (expected_type_stack.empty ())
191 : return nullptr;
192 23362 : return expected_type_stack.back ();
193 : }
194 :
195 : StackedContexts<TypeCheckBlockContextItem> &
196 26244 : TypeCheckContext::block_context ()
197 : {
198 26244 : return block_stack;
199 : }
200 :
201 : void
202 4445 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
203 : {
204 512842 : for (auto it = resolved.begin (); it != resolved.end (); it++)
205 : {
206 508397 : if (!cb (it->first, it->second))
207 4445 : return;
208 : }
209 : }
210 :
211 : bool
212 140 : TypeCheckContext::have_loop_context () const
213 : {
214 140 : return !loop_type_stack.empty ();
215 : }
216 :
217 : void
218 147 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
219 : {
220 147 : TyTy::BaseType *infer_var
221 : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
222 147 : TyTy::InferType::TypeHint::Default (), locus);
223 147 : loop_type_stack.push_back (infer_var);
224 147 : }
225 :
226 : void
227 86 : TypeCheckContext::push_new_while_loop_context (HirId id)
228 : {
229 86 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
230 86 : loop_type_stack.push_back (infer_var);
231 86 : }
232 :
233 : TyTy::BaseType *
234 258 : TypeCheckContext::peek_loop_context ()
235 : {
236 258 : return loop_type_stack.back ();
237 : }
238 :
239 : TyTy::BaseType *
240 233 : TypeCheckContext::pop_loop_context ()
241 : {
242 233 : auto back = peek_loop_context ();
243 233 : loop_type_stack.pop_back ();
244 233 : return back;
245 : }
246 :
247 : void
248 21 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
249 : {
250 21 : loop_type_stack.pop_back ();
251 21 : loop_type_stack.push_back (val);
252 21 : }
253 :
254 : bool
255 11247 : TypeCheckContext::find_matching_impl_trait_frame (
256 : const TraitReference &tref, struct ImplTraitContextFrame *find) const
257 : {
258 11247 : if (!have_impl_trait_context ())
259 : return false;
260 :
261 6053 : for (auto it = impl_trait_frame_stack.rbegin ();
262 6053 : it != impl_trait_frame_stack.rend (); ++it)
263 : {
264 5254 : const auto &i = *it;
265 5254 : if (i.trait->is_equal (tref))
266 : {
267 4451 : *find = i;
268 4451 : return true;
269 : }
270 : }
271 :
272 : return false;
273 : }
274 :
275 : bool
276 11247 : TypeCheckContext::have_impl_trait_context () const
277 : {
278 11247 : return !impl_trait_frame_stack.empty ();
279 : }
280 :
281 : void
282 13459 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
283 : {
284 13459 : impl_trait_frame_stack.push_back (frame);
285 13459 : }
286 :
287 : struct ImplTraitContextFrame
288 13459 : TypeCheckContext::pop_impl_trait_context ()
289 : {
290 13459 : auto back = peek_impl_trait_context ();
291 13459 : impl_trait_frame_stack.pop_back ();
292 13459 : return back;
293 : }
294 :
295 : struct ImplTraitContextFrame
296 13459 : TypeCheckContext::peek_impl_trait_context ()
297 : {
298 13459 : return impl_trait_frame_stack.back ();
299 : }
300 :
301 : void
302 3992 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
303 : {
304 3992 : rust_assert (trait_context.find (id) == trait_context.end ());
305 3992 : trait_context.emplace (id, std::move (ref));
306 3992 : }
307 :
308 : bool
309 1606577 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
310 : {
311 1606577 : auto it = trait_context.find (id);
312 1606577 : if (it == trait_context.end ())
313 : return false;
314 :
315 1580753 : *ref = &it->second;
316 1580753 : return true;
317 : }
318 :
319 : bool
320 4767 : TypeCheckContext::insert_associated_trait_impl (
321 : HirId id, AssociatedImplTrait &&associated)
322 : {
323 4767 : auto it = associated_impl_traits.find (id);
324 4767 : if (it != associated_impl_traits.end ())
325 : {
326 : return false;
327 : }
328 4766 : associated_impl_traits.emplace (id, std::move (associated));
329 4766 : return true;
330 : }
331 :
332 : bool
333 52724 : TypeCheckContext::lookup_associated_trait_impl (
334 : HirId id, AssociatedImplTrait **associated)
335 : {
336 52724 : auto it = associated_impl_traits.find (id);
337 52724 : if (it == associated_impl_traits.end ())
338 : return false;
339 :
340 27670 : *associated = &it->second;
341 27670 : return true;
342 : }
343 :
344 : void
345 0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
346 : {
347 0 : associated_type_mappings[id] = mapping;
348 0 : }
349 :
350 : void
351 0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
352 : {
353 0 : auto it = associated_type_mappings.find (id);
354 0 : if (it != associated_type_mappings.end ())
355 0 : associated_type_mappings.erase (it);
356 0 : }
357 :
358 : // lookup any associated type mappings, the out parameter of mapping is
359 : // allowed to be nullptr which allows this interface to do a simple does exist
360 : // check
361 : bool
362 0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
363 : {
364 0 : auto it = associated_type_mappings.find (id);
365 0 : if (it == associated_type_mappings.end ())
366 : return false;
367 :
368 0 : if (mapping != nullptr)
369 0 : *mapping = it->second;
370 :
371 : return true;
372 : }
373 :
374 : void
375 4767 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
376 : TyTy::BaseType *impl_type,
377 : HirId impl_id)
378 : {
379 4767 : auto it = associated_traits_to_impls.find (trait_id);
380 4767 : if (it == associated_traits_to_impls.end ())
381 : {
382 1843 : associated_traits_to_impls[trait_id] = {};
383 : }
384 :
385 4767 : associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
386 4767 : }
387 :
388 : bool
389 0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
390 : TyTy::BaseType *self,
391 : HirId *mapping)
392 : {
393 0 : auto it = associated_traits_to_impls.find (trait_id);
394 0 : if (it == associated_traits_to_impls.end ())
395 : return false;
396 :
397 0 : for (auto &item : it->second)
398 : {
399 0 : if (types_compatable (TyTy::TyWithLocation (item.first),
400 0 : TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
401 : false))
402 : {
403 0 : *mapping = item.second;
404 0 : return true;
405 : }
406 : }
407 : return false;
408 : }
409 :
410 : void
411 45544 : TypeCheckContext::insert_autoderef_mappings (
412 : HirId id, std::vector<Adjustment> &&adjustments)
413 : {
414 45544 : autoderef_mappings.emplace (id, std::move (adjustments));
415 45544 : }
416 :
417 : bool
418 48664 : TypeCheckContext::lookup_autoderef_mappings (
419 : HirId id, std::vector<Adjustment> **adjustments)
420 : {
421 48664 : auto it = autoderef_mappings.find (id);
422 48664 : if (it == autoderef_mappings.end ())
423 : return false;
424 :
425 35169 : *adjustments = &it->second;
426 35169 : return true;
427 : }
428 :
429 : void
430 5406 : TypeCheckContext::insert_cast_autoderef_mappings (
431 : HirId id, std::vector<Adjustment> &&adjustments)
432 : {
433 5406 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
434 5406 : }
435 :
436 : bool
437 5084 : TypeCheckContext::lookup_cast_autoderef_mappings (
438 : HirId id, std::vector<Adjustment> **adjustments)
439 : {
440 5084 : auto it = cast_autoderef_mappings.find (id);
441 5084 : if (it == cast_autoderef_mappings.end ())
442 : return false;
443 :
444 5084 : *adjustments = &it->second;
445 5084 : return true;
446 : }
447 :
448 : void
449 4307 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
450 : {
451 4307 : auto it = variants.find (id);
452 4307 : rust_assert (it == variants.end ());
453 :
454 4307 : variants[id] = variant;
455 4307 : }
456 :
457 : bool
458 8405 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
459 : {
460 8405 : auto it = variants.find (id);
461 8405 : if (it == variants.end ())
462 : return false;
463 :
464 8399 : *variant = it->second;
465 8399 : return true;
466 : }
467 :
468 : void
469 1333 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
470 : {
471 1333 : auto it = operator_overloads.find (id);
472 1333 : rust_assert (it == operator_overloads.end ());
473 :
474 1333 : operator_overloads[id] = call_site;
475 1333 : }
476 :
477 : bool
478 23764 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
479 : {
480 23764 : auto it = operator_overloads.find (id);
481 23764 : if (it == operator_overloads.end ())
482 : return false;
483 :
484 2358 : *call = it->second;
485 2358 : return true;
486 : }
487 :
488 : void
489 8 : TypeCheckContext::insert_deferred_operator_overload (
490 : DeferredOpOverload deferred)
491 : {
492 8 : HirId expr_id = deferred.expr_id;
493 8 : deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
494 8 : }
495 :
496 : bool
497 0 : TypeCheckContext::lookup_deferred_operator_overload (
498 : HirId id, DeferredOpOverload *deferred)
499 : {
500 0 : auto it = deferred_operator_overloads.find (id);
501 0 : if (it == deferred_operator_overloads.end ())
502 : return false;
503 :
504 0 : *deferred = it->second;
505 0 : return true;
506 : }
507 :
508 : void
509 4445 : TypeCheckContext::iterate_deferred_operator_overloads (
510 : std::function<bool (HirId, DeferredOpOverload &)> cb)
511 : {
512 4453 : for (auto it = deferred_operator_overloads.begin ();
513 4453 : it != deferred_operator_overloads.end (); it++)
514 : {
515 8 : if (!cb (it->first, it->second))
516 4445 : return;
517 : }
518 : }
519 :
520 : void
521 5802 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
522 : {
523 5802 : unconstrained[id] = status;
524 5802 : }
525 :
526 : bool
527 43814 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
528 : {
529 43814 : auto it = unconstrained.find (id);
530 43814 : bool found = it != unconstrained.end ();
531 43814 : if (!found)
532 : return false;
533 :
534 38012 : *result = it->second;
535 38012 : return true;
536 : }
537 :
538 : void
539 7037 : TypeCheckContext::insert_resolved_predicate (HirId id,
540 : TyTy::TypeBoundPredicate predicate)
541 : {
542 : // auto it = predicates.find (id);
543 : // rust_assert (it == predicates.end ());
544 :
545 7037 : predicates.insert ({id, predicate});
546 7037 : }
547 :
548 : bool
549 43381 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
550 : {
551 43381 : auto it = predicates.find (id);
552 43381 : bool found = it != predicates.end ();
553 43381 : if (!found)
554 : return false;
555 :
556 36335 : *result = it->second;
557 36335 : return true;
558 : }
559 :
560 : void
561 10989 : TypeCheckContext::insert_query (HirId id)
562 : {
563 10989 : querys_in_progress.insert (id);
564 10989 : }
565 :
566 : void
567 10989 : TypeCheckContext::query_completed (HirId id)
568 : {
569 10989 : querys_in_progress.erase (id);
570 10989 : }
571 :
572 : bool
573 16559 : TypeCheckContext::query_in_progress (HirId id) const
574 : {
575 16559 : return querys_in_progress.find (id) != querys_in_progress.end ();
576 : }
577 :
578 : void
579 4011 : TypeCheckContext::insert_trait_query (DefId id)
580 : {
581 4011 : trait_queries_in_progress.insert (id);
582 4011 : }
583 :
584 : void
585 4011 : TypeCheckContext::trait_query_completed (DefId id)
586 : {
587 4011 : trait_queries_in_progress.erase (id);
588 4011 : }
589 :
590 : bool
591 4015 : TypeCheckContext::trait_query_in_progress (DefId id) const
592 : {
593 4015 : return trait_queries_in_progress.find (id)
594 4015 : != trait_queries_in_progress.end ();
595 : }
596 :
597 : Lifetime
598 968 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
599 : {
600 968 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
601 : {
602 967 : auto maybe_interned = lookup_lifetime (lifetime);
603 967 : if (maybe_interned)
604 870 : return *maybe_interned;
605 :
606 97 : auto interned = next_lifetime_index.next ();
607 97 : lifetime_name_interner[lifetime.get_name ()] = interned;
608 97 : return interned;
609 : }
610 1 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
611 : {
612 1 : return next_lifetime_index.next ();
613 : }
614 0 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
615 : {
616 0 : return Lifetime::static_lifetime ();
617 : }
618 0 : rust_unreachable ();
619 : }
620 :
621 : tl::optional<Lifetime>
622 30822 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
623 : {
624 30822 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
625 : {
626 1246 : if (lifetime.get_name () == "static")
627 : {
628 1 : rich_location r (line_table, lifetime.get_locus ());
629 1 : r.add_fixit_insert_after (lifetime.get_locus (),
630 : "static is a reserved lifetime name");
631 1 : rust_error_at (r, ErrorCode::E0262,
632 : "invalid lifetime parameter name: %qs",
633 1 : lifetime.get_name ().c_str ());
634 1 : return tl::nullopt;
635 1 : }
636 1245 : const auto name = lifetime.get_name ();
637 1245 : auto it = lifetime_name_interner.find (name);
638 1245 : if (it == lifetime_name_interner.end ())
639 101 : return tl::nullopt;
640 1144 : return it->second;
641 1245 : }
642 29576 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
643 : {
644 29487 : return Lifetime::anonymous_lifetime ();
645 : }
646 89 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
647 : {
648 89 : return Lifetime::static_lifetime ();
649 : }
650 0 : rust_unreachable ();
651 : }
652 :
653 : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
654 29855 : TypeCheckContext::lookup_and_resolve_lifetime (
655 : const HIR::Lifetime &lifetime) const
656 : {
657 29855 : auto maybe_interned = lookup_lifetime (lifetime);
658 29855 : if (!maybe_interned)
659 5 : return tl::nullopt;
660 :
661 29850 : return get_lifetime_resolver ().resolve (maybe_interned.value ());
662 : }
663 : void
664 16 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
665 : {
666 16 : get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
667 16 : }
668 :
669 : WARN_UNUSED_RESULT std::vector<TyTy::Region>
670 9580 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
671 : {
672 9580 : std::vector<TyTy::Region> regions;
673 9609 : for (const auto &lifetime : args.get_lifetime_args ())
674 : {
675 30 : auto resolved = lookup_and_resolve_lifetime (lifetime);
676 30 : if (!resolved)
677 : {
678 1 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
679 1 : return {};
680 : }
681 29 : regions.push_back (*resolved);
682 : }
683 9579 : return regions;
684 9580 : }
685 :
686 : bool
687 8 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
688 : DeferredOpOverload &op)
689 : {
690 8 : rust_debug ("attempting resolution of op overload: %s",
691 : op.predicate.as_string ().c_str ());
692 :
693 8 : TyTy::BaseType *lhs = nullptr;
694 8 : bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
695 8 : rust_assert (ok);
696 :
697 8 : TyTy::BaseType *rhs = nullptr;
698 8 : if (op.op.has_rvalue_mappings ())
699 : {
700 8 : bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
701 8 : rust_assert (ok);
702 : }
703 :
704 8 : TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
705 8 : op.specified_segment);
706 :
707 8 : return true;
708 : }
709 :
710 : void
711 4445 : TypeCheckContext::compute_inference_variables (bool emit_error)
712 : {
713 4445 : iterate_deferred_operator_overloads (
714 4445 : [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
715 8 : return compute_ambigious_op_overload (id, op);
716 : });
717 :
718 4445 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
719 508397 : return compute_infer_var (id, ty, emit_error);
720 : });
721 4445 : }
722 :
723 : bool
724 508397 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
725 : bool emit_error)
726 : {
727 508397 : auto &mappings = Analysis::Mappings::get ();
728 :
729 : // nothing to do
730 508397 : if (ty->get_kind () != TyTy::TypeKind::INFER)
731 : return true;
732 :
733 1721 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
734 1721 : TyTy::BaseType *default_type;
735 :
736 1721 : rust_debug_loc (mappings.lookup_location (id),
737 : "trying to default infer-var: %s",
738 1721 : infer_var->as_string ().c_str ());
739 1721 : bool ok = infer_var->default_type (&default_type);
740 1721 : if (!ok)
741 : {
742 11 : if (emit_error)
743 11 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
744 : "type annotations needed");
745 : return true;
746 : }
747 :
748 1710 : auto result
749 1710 : = unify_site (id, TyTy::TyWithLocation (ty),
750 1710 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
751 1710 : rust_assert (result);
752 1710 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
753 1710 : result->set_ref (id);
754 1710 : insert_implicit_type (id, result);
755 :
756 1710 : return true;
757 : }
758 :
759 : TyTy::VarianceAnalysis::CrateCtx &
760 8629 : TypeCheckContext::get_variance_analysis_ctx ()
761 : {
762 8629 : return variance_analysis_ctx;
763 : }
764 :
765 : // TypeCheckContextItem
766 :
767 9621 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
768 :
769 6982 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
770 : HIR::Function *item)
771 6982 : : impl_item ({impl_block, item})
772 6982 : {}
773 :
774 859 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
775 859 : : trait_item (trait_item)
776 859 : {}
777 :
778 6799 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
779 6799 : : type (ItemType::ITEM), item (item)
780 6799 : {}
781 :
782 6982 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
783 : HIR::Function *item)
784 6982 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
785 6982 : {}
786 :
787 859 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
788 859 : : type (ItemType::TRAIT_ITEM), item (trait_item)
789 859 : {}
790 :
791 32038 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
792 32038 : : type (other.type), item (other.item)
793 : {
794 32038 : switch (other.type)
795 : {
796 14871 : case ITEM:
797 14871 : item.item = other.item.item;
798 14871 : break;
799 :
800 15276 : case IMPL_ITEM:
801 15276 : item.impl_item = other.item.impl_item;
802 15276 : break;
803 :
804 1891 : case TRAIT_ITEM:
805 1891 : item.trait_item = other.item.trait_item;
806 1891 : break;
807 :
808 0 : case ERROR:
809 0 : item.item = nullptr;
810 0 : break;
811 : }
812 32038 : }
813 :
814 2822 : TypeCheckContextItem::TypeCheckContextItem ()
815 2822 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
816 2822 : {}
817 :
818 : TypeCheckContextItem &
819 2814 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
820 : {
821 2814 : type = other.type;
822 2814 : switch (other.type)
823 : {
824 635 : case ITEM:
825 635 : item.item = other.item.item;
826 635 : break;
827 :
828 2065 : case IMPL_ITEM:
829 2065 : item.impl_item = other.item.impl_item;
830 2065 : break;
831 :
832 114 : case TRAIT_ITEM:
833 114 : item.trait_item = other.item.trait_item;
834 114 : break;
835 :
836 0 : case ERROR:
837 0 : item.item = nullptr;
838 0 : break;
839 : }
840 :
841 2814 : return *this;
842 : }
843 :
844 : TypeCheckContextItem
845 2822 : TypeCheckContextItem::get_error ()
846 : {
847 2822 : return TypeCheckContextItem ();
848 : }
849 :
850 : bool
851 0 : TypeCheckContextItem::is_error () const
852 : {
853 0 : return type == ERROR;
854 : }
855 :
856 : HIR::Function *
857 63 : TypeCheckContextItem::get_item ()
858 : {
859 63 : rust_assert (get_type () == ItemType::ITEM);
860 63 : return item.item;
861 : }
862 :
863 : std::pair<HIR::ImplBlock *, HIR::Function *> &
864 771 : TypeCheckContextItem::get_impl_item ()
865 : {
866 771 : rust_assert (get_type () == ItemType::IMPL_ITEM);
867 771 : return item.impl_item;
868 : }
869 :
870 : HIR::TraitItemFunc *
871 1 : TypeCheckContextItem::get_trait_item ()
872 : {
873 1 : rust_assert (get_type () == ItemType::TRAIT_ITEM);
874 1 : return item.trait_item;
875 : }
876 :
877 : TypeCheckContextItem::ItemType
878 18160 : TypeCheckContextItem::get_type () const
879 : {
880 18160 : return type;
881 : }
882 :
883 : TyTy::FnType *
884 64 : TypeCheckContextItem::get_context_type ()
885 : {
886 64 : auto &context = *TypeCheckContext::get ();
887 :
888 64 : HirId reference = UNKNOWN_HIRID;
889 64 : switch (get_type ())
890 : {
891 63 : case ITEM:
892 63 : reference = get_item ()->get_mappings ().get_hirid ();
893 63 : break;
894 :
895 0 : case IMPL_ITEM:
896 0 : reference = get_impl_item ().second->get_mappings ().get_hirid ();
897 0 : break;
898 :
899 1 : case TRAIT_ITEM:
900 1 : reference = get_trait_item ()->get_mappings ().get_hirid ();
901 1 : break;
902 :
903 0 : case ERROR:
904 0 : rust_unreachable ();
905 : return nullptr;
906 : }
907 :
908 64 : rust_assert (reference != UNKNOWN_HIRID);
909 :
910 64 : TyTy::BaseType *lookup = nullptr;
911 64 : bool ok = context.lookup_type (reference, &lookup);
912 64 : rust_assert (ok);
913 64 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
914 64 : return static_cast<TyTy::FnType *> (lookup);
915 : }
916 :
917 : DefId
918 2856 : TypeCheckContextItem::get_defid () const
919 : {
920 2856 : switch (get_type ())
921 : {
922 747 : case ITEM:
923 747 : return item.item->get_mappings ().get_defid ();
924 :
925 1987 : case IMPL_ITEM:
926 1987 : return item.impl_item.second->get_mappings ().get_defid ();
927 :
928 114 : case TRAIT_ITEM:
929 114 : return item.trait_item->get_mappings ().get_defid ();
930 :
931 8 : case ERROR:
932 8 : return UNKNOWN_DEFID;
933 : }
934 :
935 0 : return UNKNOWN_DEFID;
936 : }
937 :
938 : // TypeCheckBlockContextItem
939 :
940 8237 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
941 :
942 3992 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
943 :
944 8237 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
945 8237 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
946 8237 : {}
947 :
948 3992 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
949 3992 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
950 3992 : {}
951 :
952 : bool
953 0 : TypeCheckBlockContextItem::is_impl_block () const
954 : {
955 0 : return type == IMPL_BLOCK;
956 : }
957 :
958 : bool
959 893 : TypeCheckBlockContextItem::is_trait_block () const
960 : {
961 893 : return type == TRAIT;
962 : }
963 :
964 : HIR::ImplBlock &
965 158 : TypeCheckBlockContextItem::get_impl_block ()
966 : {
967 158 : return *(item.block);
968 : }
969 :
970 : HIR::Trait &
971 735 : TypeCheckBlockContextItem::get_trait ()
972 : {
973 735 : return *(item.trait);
974 : }
975 :
976 : } // namespace Resolver
977 : } // namespace Rust
|