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 7327297 : TypeCheckContext::get ()
28 : {
29 7327297 : static TypeCheckContext *instance;
30 7327297 : if (instance == nullptr)
31 4971 : instance = new TypeCheckContext ();
32 :
33 7327297 : return instance;
34 : }
35 :
36 4971 : 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 36806 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : {
58 418252 : for (auto &builtin : builtins)
59 : {
60 418252 : if (name.compare (builtin->as_string ()) == 0)
61 : {
62 36806 : *type = builtin.get ();
63 36806 : return true;
64 : }
65 : }
66 : return false;
67 : }
68 :
69 : void
70 95361 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : {
72 95361 : node_id_refs[ref] = id;
73 95361 : resolved[id] = type;
74 95361 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 95361 : }
76 :
77 : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 4707 : TypeCheckContext::get_builtins () const
79 : {
80 4707 : return builtins;
81 : }
82 :
83 : void
84 433805 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : TyTy::BaseType *type)
86 : {
87 433805 : rust_assert (type != nullptr);
88 433805 : NodeId ref = mappings.get_nodeid ();
89 433805 : HirId id = mappings.get_hirid ();
90 433805 : node_id_refs[ref] = id;
91 433805 : resolved[id] = type;
92 433805 : }
93 :
94 : void
95 173149 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : {
97 173149 : rust_assert (type != nullptr);
98 173149 : resolved[id] = type;
99 173149 : }
100 :
101 : bool
102 6467339 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
103 : {
104 6467339 : auto it = resolved.find (id);
105 6467339 : if (it == resolved.end ())
106 : return false;
107 :
108 6251379 : *type = it->second;
109 6251379 : return true;
110 : }
111 :
112 : void
113 3079 : TypeCheckContext::mark_function_body_pending (DefId id)
114 : {
115 3079 : function_bodies_pending.insert (id);
116 3079 : }
117 :
118 : void
119 15699 : TypeCheckContext::clear_function_body_pending (DefId id)
120 : {
121 15699 : function_bodies_pending.erase (id);
122 15699 : }
123 :
124 : bool
125 3087 : TypeCheckContext::function_body_pending (DefId id) const
126 : {
127 3087 : return function_bodies_pending.find (id) != function_bodies_pending.end ();
128 : }
129 :
130 : void
131 4710 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
132 : {
133 4710 : auto it = resolved.find (ty->get_ref ());
134 4710 : if (it == resolved.end ())
135 4710 : return;
136 :
137 4710 : resolved.erase (it);
138 : }
139 :
140 : void
141 0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
142 : {
143 0 : rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
144 0 : node_id_refs[ref] = id;
145 0 : }
146 :
147 : bool
148 0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
149 : {
150 0 : auto it = node_id_refs.find (ref);
151 0 : if (it == node_id_refs.end ())
152 : return false;
153 :
154 0 : *id = it->second;
155 0 : return true;
156 : }
157 :
158 : bool
159 17873 : TypeCheckContext::have_function_context () const
160 : {
161 17873 : return !return_type_stack.empty ();
162 : }
163 :
164 : TyTy::BaseType *
165 572 : TypeCheckContext::peek_return_type ()
166 : {
167 572 : rust_assert (!return_type_stack.empty ());
168 572 : return return_type_stack.back ().second;
169 : }
170 :
171 : void
172 15699 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
173 : TyTy::BaseType *return_type)
174 : {
175 15699 : return_type_stack.emplace_back (std::move (item), return_type);
176 : // a query can check another function body while an expression in the
177 : // caller has an expected type
178 15699 : push_expected_type (nullptr);
179 15699 : }
180 :
181 : void
182 15699 : TypeCheckContext::pop_return_type ()
183 : {
184 15699 : rust_assert (!return_type_stack.empty ());
185 15699 : pop_expected_type ();
186 15699 : return_type_stack.pop_back ();
187 15699 : }
188 :
189 : TypeCheckContextItem
190 17274 : TypeCheckContext::peek_context ()
191 : {
192 17274 : rust_assert (!return_type_stack.empty ());
193 17274 : return return_type_stack.back ().first;
194 : }
195 :
196 : void
197 71494 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
198 : {
199 71494 : expected_type_stack.push_back (expected);
200 71494 : }
201 :
202 : void
203 71494 : TypeCheckContext::pop_expected_type ()
204 : {
205 71494 : rust_assert (!expected_type_stack.empty ());
206 71494 : expected_type_stack.pop_back ();
207 71494 : }
208 :
209 : TyTy::BaseType *
210 36831 : TypeCheckContext::peek_expected_type () const
211 : {
212 36831 : if (expected_type_stack.empty ())
213 : return nullptr;
214 36545 : return expected_type_stack.back ();
215 : }
216 :
217 : StackedContexts<TypeCheckBlockContextItem> &
218 33068 : TypeCheckContext::block_context ()
219 : {
220 33068 : return block_stack;
221 : }
222 :
223 : void
224 4505 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
225 : {
226 533587 : for (auto it = resolved.begin (); it != resolved.end (); it++)
227 : {
228 529082 : if (!cb (it->first, it->second))
229 4505 : return;
230 : }
231 : }
232 :
233 : bool
234 148 : TypeCheckContext::have_loop_context () const
235 : {
236 148 : return !loop_type_stack.empty ();
237 : }
238 :
239 : void
240 155 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
241 : {
242 155 : TyTy::BaseType *infer_var
243 : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
244 155 : TyTy::InferType::TypeHint::Default (), locus);
245 155 : loop_type_stack.push_back (infer_var);
246 155 : }
247 :
248 : void
249 94 : TypeCheckContext::push_new_while_loop_context (HirId id)
250 : {
251 94 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
252 94 : loop_type_stack.push_back (infer_var);
253 94 : }
254 :
255 : TyTy::BaseType *
256 274 : TypeCheckContext::peek_loop_context ()
257 : {
258 274 : return loop_type_stack.back ();
259 : }
260 :
261 : TyTy::BaseType *
262 249 : TypeCheckContext::pop_loop_context ()
263 : {
264 249 : auto back = peek_loop_context ();
265 249 : loop_type_stack.pop_back ();
266 249 : return back;
267 : }
268 :
269 : void
270 21 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
271 : {
272 21 : loop_type_stack.pop_back ();
273 21 : loop_type_stack.push_back (val);
274 21 : }
275 :
276 : bool
277 3884 : TypeCheckContext::find_matching_impl_trait_frame (
278 : const TraitReference &tref, TyTy::BaseType &self,
279 : struct ImplTraitContextFrame *find) const
280 : {
281 3884 : if (!have_impl_trait_context ())
282 : return false;
283 :
284 2879 : for (auto it = impl_trait_frame_stack.rbegin ();
285 2879 : it != impl_trait_frame_stack.rend (); ++it)
286 : {
287 2098 : const auto &i = *it;
288 2098 : if (!i.trait->is_equal (tref))
289 675 : continue;
290 :
291 1423 : TyTy::BaseType *resolved_self = &self;
292 1423 : bool unresolved_trait_self = false;
293 1423 : if (auto param = self.try_as<TyTy::ParamType> ())
294 : {
295 84 : if (param->can_resolve ())
296 84 : resolved_self = param->resolve ();
297 : else
298 0 : unresolved_trait_self = param->is_implicit_self_trait ();
299 : }
300 :
301 84 : bool compatible_self
302 : = unresolved_trait_self
303 1423 : || types_compatable (TyTy::TyWithLocation (i.self),
304 1423 : TyTy::TyWithLocation (resolved_self),
305 : UNDEF_LOCATION, false /* emit_errors */,
306 1423 : false /* check_bounds */);
307 1423 : if (compatible_self)
308 : {
309 1290 : *find = i;
310 1290 : return true;
311 : }
312 : }
313 :
314 : return false;
315 : }
316 :
317 : bool
318 3884 : TypeCheckContext::have_impl_trait_context () const
319 : {
320 3884 : return !impl_trait_frame_stack.empty ();
321 : }
322 :
323 : void
324 13507 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
325 : {
326 13507 : impl_trait_frame_stack.push_back (frame);
327 13507 : }
328 :
329 : struct ImplTraitContextFrame
330 13507 : TypeCheckContext::pop_impl_trait_context ()
331 : {
332 13507 : auto back = peek_impl_trait_context ();
333 13507 : impl_trait_frame_stack.pop_back ();
334 13507 : return back;
335 : }
336 :
337 : struct ImplTraitContextFrame
338 13507 : TypeCheckContext::peek_impl_trait_context ()
339 : {
340 13507 : return impl_trait_frame_stack.back ();
341 : }
342 :
343 : void
344 4167 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
345 : {
346 4167 : rust_assert (trait_context.find (id) == trait_context.end ());
347 4167 : trait_context.emplace (id, std::move (ref));
348 4167 : }
349 :
350 : bool
351 530345 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
352 : {
353 530345 : auto it = trait_context.find (id);
354 530345 : if (it == trait_context.end ())
355 : return false;
356 :
357 502982 : *ref = &it->second;
358 502982 : return true;
359 : }
360 :
361 : bool
362 5335 : TypeCheckContext::insert_associated_trait_impl (
363 : HirId id, AssociatedImplTrait &&associated)
364 : {
365 5335 : auto it = associated_impl_traits.find (id);
366 5335 : if (it != associated_impl_traits.end ())
367 : {
368 : return false;
369 : }
370 5334 : associated_impl_traits.emplace (id, std::move (associated));
371 5334 : return true;
372 : }
373 :
374 : bool
375 26558 : TypeCheckContext::lookup_associated_trait_impl (
376 : HirId id, AssociatedImplTrait **associated)
377 : {
378 26558 : auto it = associated_impl_traits.find (id);
379 26558 : if (it == associated_impl_traits.end ())
380 : return false;
381 :
382 10578 : *associated = &it->second;
383 10578 : return true;
384 : }
385 :
386 : void
387 0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
388 : {
389 0 : associated_type_mappings[id] = mapping;
390 0 : }
391 :
392 : void
393 0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
394 : {
395 0 : auto it = associated_type_mappings.find (id);
396 0 : if (it != associated_type_mappings.end ())
397 0 : associated_type_mappings.erase (it);
398 0 : }
399 :
400 : // lookup any associated type mappings, the out parameter of mapping is
401 : // allowed to be nullptr which allows this interface to do a simple does exist
402 : // check
403 : bool
404 0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
405 : {
406 0 : auto it = associated_type_mappings.find (id);
407 0 : if (it == associated_type_mappings.end ())
408 : return false;
409 :
410 0 : if (mapping != nullptr)
411 0 : *mapping = it->second;
412 :
413 : return true;
414 : }
415 :
416 : void
417 5335 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
418 : TyTy::BaseType *impl_type,
419 : HirId impl_id)
420 : {
421 5335 : auto it = associated_traits_to_impls.find (trait_id);
422 5335 : if (it == associated_traits_to_impls.end ())
423 : {
424 1956 : associated_traits_to_impls[trait_id] = {};
425 : }
426 :
427 5335 : associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
428 5335 : }
429 :
430 : bool
431 0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
432 : TyTy::BaseType *self,
433 : HirId *mapping)
434 : {
435 0 : auto it = associated_traits_to_impls.find (trait_id);
436 0 : if (it == associated_traits_to_impls.end ())
437 : return false;
438 :
439 0 : for (auto &item : it->second)
440 : {
441 0 : if (types_compatable (TyTy::TyWithLocation (item.first),
442 0 : TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
443 : false))
444 : {
445 0 : *mapping = item.second;
446 0 : return true;
447 : }
448 : }
449 : return false;
450 : }
451 :
452 : void
453 48186 : TypeCheckContext::insert_autoderef_mappings (
454 : HirId id, std::vector<Adjustment> &&adjustments)
455 : {
456 48186 : autoderef_mappings.emplace (id, std::move (adjustments));
457 48186 : }
458 :
459 : bool
460 51261 : TypeCheckContext::lookup_autoderef_mappings (
461 : HirId id, std::vector<Adjustment> **adjustments)
462 : {
463 51261 : auto it = autoderef_mappings.find (id);
464 51261 : if (it == autoderef_mappings.end ())
465 : return false;
466 :
467 37358 : *adjustments = &it->second;
468 37358 : return true;
469 : }
470 :
471 : void
472 5741 : TypeCheckContext::insert_cast_autoderef_mappings (
473 : HirId id, std::vector<Adjustment> &&adjustments)
474 : {
475 5741 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
476 5741 : }
477 :
478 : bool
479 5380 : TypeCheckContext::lookup_cast_autoderef_mappings (
480 : HirId id, std::vector<Adjustment> **adjustments)
481 : {
482 5380 : auto it = cast_autoderef_mappings.find (id);
483 5380 : if (it == cast_autoderef_mappings.end ())
484 : return false;
485 :
486 5380 : *adjustments = &it->second;
487 5380 : return true;
488 : }
489 :
490 : void
491 4496 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
492 : {
493 4496 : auto it = variants.find (id);
494 4496 : rust_assert (it == variants.end ());
495 :
496 4496 : variants[id] = variant;
497 4496 : }
498 :
499 : bool
500 8751 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
501 : {
502 8751 : auto it = variants.find (id);
503 8751 : if (it == variants.end ())
504 : return false;
505 :
506 8745 : *variant = it->second;
507 8745 : return true;
508 : }
509 :
510 : void
511 1408 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
512 : {
513 1408 : auto it = operator_overloads.find (id);
514 1408 : rust_assert (it == operator_overloads.end ());
515 :
516 1408 : operator_overloads[id] = call_site;
517 1408 : }
518 :
519 : bool
520 25266 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
521 : {
522 25266 : auto it = operator_overloads.find (id);
523 25266 : if (it == operator_overloads.end ())
524 : return false;
525 :
526 2498 : *call = it->second;
527 2498 : return true;
528 : }
529 :
530 : void
531 15 : TypeCheckContext::insert_deferred_operator_overload (
532 : DeferredOpOverload deferred)
533 : {
534 15 : HirId expr_id = deferred.expr_id;
535 15 : deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
536 15 : }
537 :
538 : bool
539 0 : TypeCheckContext::lookup_deferred_operator_overload (
540 : HirId id, DeferredOpOverload *deferred)
541 : {
542 0 : auto it = deferred_operator_overloads.find (id);
543 0 : if (it == deferred_operator_overloads.end ())
544 : return false;
545 :
546 0 : *deferred = it->second;
547 0 : return true;
548 : }
549 :
550 : void
551 0 : TypeCheckContext::iterate_deferred_operator_overloads (
552 : std::function<bool (HirId, DeferredOpOverload &)> cb)
553 : {
554 0 : for (auto it = deferred_operator_overloads.begin ();
555 0 : it != deferred_operator_overloads.end (); it++)
556 : {
557 0 : if (!cb (it->first, it->second))
558 0 : return;
559 : }
560 : }
561 :
562 : void
563 6432 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
564 : {
565 6432 : unconstrained[id] = status;
566 6432 : }
567 :
568 : bool
569 34858 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
570 : {
571 34858 : auto it = unconstrained.find (id);
572 34858 : bool found = it != unconstrained.end ();
573 34858 : if (!found)
574 : return false;
575 :
576 28426 : *result = it->second;
577 28426 : return true;
578 : }
579 :
580 : void
581 7904 : TypeCheckContext::insert_resolved_predicate (
582 : HirId id, const TyTy::TypeBoundPredicate &predicate)
583 : {
584 : // auto it = predicates.find (id);
585 : // rust_assert (it == predicates.end ());
586 :
587 7904 : predicates.emplace (id, predicate);
588 7904 : }
589 :
590 : bool
591 34087 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
592 : {
593 34087 : auto it = predicates.find (id);
594 34087 : bool found = it != predicates.end ();
595 34087 : if (!found)
596 : return false;
597 :
598 25843 : *result = it->second;
599 25843 : return true;
600 : }
601 :
602 : void
603 7993 : TypeCheckContext::insert_query (HirId id)
604 : {
605 7993 : querys_in_progress.insert (id);
606 7993 : }
607 :
608 : void
609 7993 : TypeCheckContext::query_completed (HirId id)
610 : {
611 7993 : querys_in_progress.erase (id);
612 7993 : }
613 :
614 : bool
615 8436 : TypeCheckContext::query_in_progress (HirId id) const
616 : {
617 8436 : return querys_in_progress.find (id) != querys_in_progress.end ();
618 : }
619 :
620 : void
621 4182 : TypeCheckContext::insert_trait_query (DefId id)
622 : {
623 4182 : trait_queries_in_progress.insert (id);
624 4182 : }
625 :
626 : void
627 4182 : TypeCheckContext::trait_query_completed (DefId id)
628 : {
629 4182 : trait_queries_in_progress.erase (id);
630 4182 : }
631 :
632 : bool
633 4186 : TypeCheckContext::trait_query_in_progress (DefId id) const
634 : {
635 4186 : return trait_queries_in_progress.find (id)
636 4186 : != trait_queries_in_progress.end ();
637 : }
638 :
639 : Lifetime
640 901 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
641 : {
642 901 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
643 : {
644 900 : auto maybe_interned = lookup_lifetime (lifetime);
645 900 : if (maybe_interned)
646 800 : return *maybe_interned;
647 :
648 100 : auto interned = next_lifetime_index.next ();
649 100 : lifetime_name_interner[lifetime.get_name ()] = interned;
650 100 : return interned;
651 : }
652 1 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
653 : {
654 1 : return next_lifetime_index.next ();
655 : }
656 0 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
657 : {
658 0 : return Lifetime::static_lifetime ();
659 : }
660 0 : rust_unreachable ();
661 : }
662 :
663 : tl::optional<Lifetime>
664 10707 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
665 : {
666 10707 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
667 : {
668 1188 : if (lifetime.get_name () == "static")
669 : {
670 1 : rich_location r (line_table, lifetime.get_locus ());
671 1 : r.add_fixit_insert_after (lifetime.get_locus (),
672 : "static is a reserved lifetime name");
673 1 : rust_error_at (r, ErrorCode::E0262,
674 : "invalid lifetime parameter name: %qs",
675 1 : lifetime.get_name ().c_str ());
676 1 : return tl::nullopt;
677 1 : }
678 1187 : const auto name = lifetime.get_name ();
679 1187 : auto it = lifetime_name_interner.find (name);
680 1187 : if (it == lifetime_name_interner.end ())
681 104 : return tl::nullopt;
682 1083 : return it->second;
683 1187 : }
684 9519 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
685 : {
686 9428 : return Lifetime::anonymous_lifetime ();
687 : }
688 91 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
689 : {
690 91 : return Lifetime::static_lifetime ();
691 : }
692 0 : rust_unreachable ();
693 : }
694 :
695 : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
696 9807 : TypeCheckContext::lookup_and_resolve_lifetime (
697 : const HIR::Lifetime &lifetime) const
698 : {
699 9807 : auto maybe_interned = lookup_lifetime (lifetime);
700 9807 : if (!maybe_interned)
701 5 : return tl::nullopt;
702 :
703 9802 : return get_lifetime_resolver ().resolve (maybe_interned.value ());
704 : }
705 : void
706 32 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
707 : {
708 32 : get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
709 32 : }
710 :
711 : WARN_UNUSED_RESULT std::vector<TyTy::Region>
712 10954 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
713 : {
714 10954 : std::vector<TyTy::Region> regions;
715 10983 : for (const auto &lifetime : args.get_lifetime_args ())
716 : {
717 30 : auto resolved = lookup_and_resolve_lifetime (lifetime);
718 30 : if (!resolved)
719 : {
720 1 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
721 1 : return {};
722 : }
723 29 : regions.push_back (*resolved);
724 : }
725 10953 : return regions;
726 10954 : }
727 :
728 : bool
729 15 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
730 : DeferredOpOverload &op)
731 : {
732 15 : rust_debug ("attempting resolution of deferred operator overload");
733 :
734 15 : TyTy::BaseType *lhs = nullptr;
735 15 : bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
736 15 : rust_assert (ok);
737 :
738 15 : TyTy::BaseType *rhs = nullptr;
739 15 : if (op.op.has_rvalue_mappings ())
740 : {
741 15 : bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
742 15 : rust_assert (ok);
743 : }
744 :
745 15 : TyTy::BaseType *current_result = op.result_type.get_tyty ();
746 15 : rust_assert (current_result != nullptr);
747 :
748 15 : rust_debug ("deferred operator expr=%u lhs=%s rhs=%s "
749 : "stored-result=%s current-result=%s result-ref=%u ty-ref=%u",
750 : id, lhs->debug_str ().c_str (),
751 : rhs == nullptr ? "<none>" : rhs->debug_str ().c_str (),
752 : current_result->debug_str ().c_str (),
753 : current_result->debug_str ().c_str (), op.result_type.get_ref (),
754 : current_result->get_ty_ref ());
755 :
756 15 : TyTy::BaseType *resolved
757 15 : = TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
758 15 : op.specified_segment, current_result);
759 15 : if (resolved == nullptr)
760 : return false;
761 :
762 15 : TyTy::BaseType *result
763 15 : = unify_site (id, TyTy::TyWithLocation (current_result),
764 15 : TyTy::TyWithLocation (resolved), op.op.get_locus ());
765 15 : rust_assert (result != nullptr);
766 15 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
767 :
768 : return true;
769 : }
770 :
771 : void
772 4505 : TypeCheckContext::compute_inference_variables (bool emit_error)
773 : {
774 9010 : auto resolve_deferred_operator_overloads = [this] () {
775 9025 : bool progress;
776 9025 : do
777 : {
778 9025 : progress = false;
779 9025 : for (auto it = deferred_operator_overloads.begin ();
780 9040 : it != deferred_operator_overloads.end ();)
781 : {
782 15 : if (compute_ambigious_op_overload (it->first, it->second))
783 : {
784 15 : it = deferred_operator_overloads.erase (it);
785 15 : progress = true;
786 : }
787 : else
788 0 : ++it;
789 : }
790 : }
791 : while (progress);
792 13515 : };
793 :
794 4505 : resolve_deferred_operator_overloads ();
795 :
796 4505 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
797 529082 : return compute_infer_var (id, ty, emit_error);
798 : });
799 :
800 4505 : resolve_deferred_operator_overloads ();
801 4505 : }
802 :
803 : bool
804 529082 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
805 : bool emit_error)
806 : {
807 529082 : auto &mappings = Analysis::Mappings::get ();
808 :
809 : // nothing to do
810 529082 : if (ty->get_kind () != TyTy::TypeKind::INFER)
811 : return true;
812 :
813 1593 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
814 1593 : TyTy::BaseType *default_type;
815 :
816 1593 : TyTy::BaseType *current = TyTy::TyVar (ty->get_ref ()).get_tyty ();
817 1593 : rust_assert (current != nullptr);
818 :
819 1593 : rust_debug_loc (mappings.lookup_location (id),
820 : "trying to default infer-var id=%u ref=%u ty-ref=%u "
821 : "stored=%s current=%s",
822 : id, ty->get_ref (), ty->get_ty_ref (),
823 : infer_var->debug_str ().c_str (),
824 : current->debug_str ().c_str ());
825 1593 : bool ok = infer_var->default_type (&default_type);
826 1593 : if (!ok)
827 : {
828 8 : if (emit_error)
829 8 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
830 : "type annotations needed");
831 : return true;
832 : }
833 :
834 1585 : rust_debug_loc (mappings.lookup_location (id), "default type selected: %s",
835 : default_type->debug_str ().c_str ());
836 :
837 1585 : auto result
838 1585 : = unify_site (id, TyTy::TyWithLocation (ty),
839 1585 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
840 1585 : rust_assert (result);
841 1585 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
842 1585 : result->set_ref (id);
843 1585 : insert_implicit_type (id, result);
844 :
845 1585 : return true;
846 : }
847 :
848 : TyTy::VarianceAnalysis::CrateCtx &
849 8974 : TypeCheckContext::get_variance_analysis_ctx ()
850 : {
851 8974 : return variance_analysis_ctx;
852 : }
853 :
854 : // TypeCheckContextItem
855 :
856 10117 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
857 :
858 7891 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
859 : HIR::Function *item)
860 7891 : : impl_item ({impl_block, item})
861 7891 : {}
862 :
863 869 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
864 869 : : trait_item (trait_item)
865 869 : {}
866 :
867 6939 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
868 6939 : : type (ItemType::ITEM), item (item)
869 6939 : {}
870 :
871 7891 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
872 : HIR::Function *item)
873 7891 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
874 7891 : {}
875 :
876 869 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
877 869 : : type (ItemType::TRAIT_ITEM), item (trait_item)
878 869 : {}
879 :
880 33056 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
881 33056 : : type (other.type), item (other.item)
882 : {
883 33056 : switch (other.type)
884 : {
885 15308 : case ITEM:
886 15308 : item.item = other.item.item;
887 15308 : break;
888 :
889 16315 : case IMPL_ITEM:
890 16315 : item.impl_item = other.item.impl_item;
891 16315 : break;
892 :
893 1433 : case TRAIT_ITEM:
894 1433 : item.trait_item = other.item.trait_item;
895 1433 : break;
896 :
897 0 : case ERROR:
898 0 : item.item = nullptr;
899 0 : break;
900 : }
901 33056 : }
902 :
903 3178 : TypeCheckContextItem::TypeCheckContextItem ()
904 3178 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
905 3178 : {}
906 :
907 : TypeCheckContextItem &
908 3163 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
909 : {
910 3163 : type = other.type;
911 3163 : switch (other.type)
912 : {
913 700 : case ITEM:
914 700 : item.item = other.item.item;
915 700 : break;
916 :
917 2349 : case IMPL_ITEM:
918 2349 : item.impl_item = other.item.impl_item;
919 2349 : break;
920 :
921 114 : case TRAIT_ITEM:
922 114 : item.trait_item = other.item.trait_item;
923 114 : break;
924 :
925 0 : case ERROR:
926 0 : item.item = nullptr;
927 0 : break;
928 : }
929 :
930 3163 : return *this;
931 : }
932 :
933 : TypeCheckContextItem
934 3178 : TypeCheckContextItem::get_error ()
935 : {
936 3178 : return TypeCheckContextItem ();
937 : }
938 :
939 : bool
940 0 : TypeCheckContextItem::is_error () const
941 : {
942 0 : return type == ERROR;
943 : }
944 :
945 : HIR::Function *
946 63 : TypeCheckContextItem::get_item ()
947 : {
948 63 : rust_assert (get_type () == ItemType::ITEM);
949 63 : return item.item;
950 : }
951 :
952 : std::pair<HIR::ImplBlock *, HIR::Function *> &
953 781 : TypeCheckContextItem::get_impl_item ()
954 : {
955 781 : rust_assert (get_type () == ItemType::IMPL_ITEM);
956 781 : return item.impl_item;
957 : }
958 :
959 : HIR::TraitItemFunc *
960 1 : TypeCheckContextItem::get_trait_item ()
961 : {
962 1 : rust_assert (get_type () == ItemType::TRAIT_ITEM);
963 1 : return item.trait_item;
964 : }
965 :
966 : TypeCheckContextItem::ItemType
967 19959 : TypeCheckContextItem::get_type () const
968 : {
969 19959 : return type;
970 : }
971 :
972 : TyTy::FnType *
973 64 : TypeCheckContextItem::get_context_type ()
974 : {
975 64 : auto &context = *TypeCheckContext::get ();
976 :
977 64 : HirId reference = UNKNOWN_HIRID;
978 64 : switch (get_type ())
979 : {
980 63 : case ITEM:
981 63 : reference = get_item ()->get_mappings ().get_hirid ();
982 63 : break;
983 :
984 0 : case IMPL_ITEM:
985 0 : reference = get_impl_item ().second->get_mappings ().get_hirid ();
986 0 : break;
987 :
988 1 : case TRAIT_ITEM:
989 1 : reference = get_trait_item ()->get_mappings ().get_hirid ();
990 1 : break;
991 :
992 0 : case ERROR:
993 0 : rust_unreachable ();
994 : return nullptr;
995 : }
996 :
997 64 : rust_assert (reference != UNKNOWN_HIRID);
998 :
999 64 : TyTy::BaseType *lookup = nullptr;
1000 64 : bool ok = context.lookup_type (reference, &lookup);
1001 64 : rust_assert (ok);
1002 64 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
1003 64 : return static_cast<TyTy::FnType *> (lookup);
1004 : }
1005 :
1006 : DefId
1007 3432 : TypeCheckContextItem::get_defid () const
1008 : {
1009 3432 : switch (get_type ())
1010 : {
1011 952 : case ITEM:
1012 952 : return item.item->get_mappings ().get_defid ();
1013 :
1014 2270 : case IMPL_ITEM:
1015 2270 : return item.impl_item.second->get_mappings ().get_defid ();
1016 :
1017 114 : case TRAIT_ITEM:
1018 114 : return item.trait_item->get_mappings ().get_defid ();
1019 :
1020 96 : case ERROR:
1021 96 : return UNKNOWN_DEFID;
1022 : }
1023 :
1024 0 : return UNKNOWN_DEFID;
1025 : }
1026 :
1027 : // TypeCheckBlockContextItem
1028 :
1029 11408 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
1030 :
1031 4167 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
1032 :
1033 11408 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
1034 11408 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
1035 11408 : {}
1036 :
1037 4167 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
1038 4167 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
1039 4167 : {}
1040 :
1041 : bool
1042 0 : TypeCheckBlockContextItem::is_impl_block () const
1043 : {
1044 0 : return type == IMPL_BLOCK;
1045 : }
1046 :
1047 : bool
1048 959 : TypeCheckBlockContextItem::is_trait_block () const
1049 : {
1050 959 : return type == TRAIT;
1051 : }
1052 :
1053 : HIR::ImplBlock &
1054 166 : TypeCheckBlockContextItem::get_impl_block ()
1055 : {
1056 166 : return *(item.block);
1057 : }
1058 :
1059 : HIR::Trait &
1060 793 : TypeCheckBlockContextItem::get_trait ()
1061 : {
1062 793 : return *(item.trait);
1063 : }
1064 :
1065 : } // namespace Resolver
1066 : } // namespace Rust
|