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 7176855 : TypeCheckContext::get ()
28 : {
29 7176855 : static TypeCheckContext *instance;
30 7176855 : if (instance == nullptr)
31 5046 : instance = new TypeCheckContext ();
32 :
33 7176855 : return instance;
34 : }
35 :
36 5046 : 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 37588 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : {
58 424410 : for (auto &builtin : builtins)
59 : {
60 424410 : if (name.compare (builtin->as_string ()) == 0)
61 : {
62 37588 : *type = builtin.get ();
63 37588 : return true;
64 : }
65 : }
66 : return false;
67 : }
68 :
69 : void
70 96786 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : {
72 96786 : node_id_refs[ref] = id;
73 96786 : resolved[id] = type;
74 96786 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 96786 : }
76 :
77 : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 4772 : TypeCheckContext::get_builtins () const
79 : {
80 4772 : return builtins;
81 : }
82 :
83 : void
84 434293 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : TyTy::BaseType *type)
86 : {
87 434293 : rust_assert (type != nullptr);
88 434293 : NodeId ref = mappings.get_nodeid ();
89 434293 : HirId id = mappings.get_hirid ();
90 434293 : node_id_refs[ref] = id;
91 434293 : resolved[id] = type;
92 434293 : }
93 :
94 : void
95 181539 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : {
97 181539 : rust_assert (type != nullptr);
98 181539 : resolved[id] = type;
99 181539 : }
100 :
101 : static std::pair<DefId, std::vector<HirId>>
102 15261 : make_adt_substitution_key (DefId id,
103 : const TyTy::SubstitutionArgumentMappings &mappings)
104 : {
105 15261 : std::vector<HirId> arguments;
106 15261 : arguments.reserve (mappings.size ());
107 32046 : for (const auto &mapping : mappings.get_mappings ())
108 16785 : arguments.push_back (mapping.get_tyty ()->get_ty_ref ());
109 :
110 15261 : return {id, std::move (arguments)};
111 15261 : }
112 :
113 : bool
114 9214 : TypeCheckContext::lookup_adt_substitution (
115 : DefId id, const TyTy::SubstitutionArgumentMappings &mappings,
116 : TyTy::ADTType **type) const
117 : {
118 9214 : auto it = adt_substitutions.find (make_adt_substitution_key (id, mappings));
119 9214 : if (it == adt_substitutions.end ())
120 : return false;
121 :
122 3167 : *type = it->second;
123 3167 : return true;
124 : }
125 :
126 : void
127 6047 : TypeCheckContext::insert_adt_substitution (
128 : DefId id, const TyTy::SubstitutionArgumentMappings &mappings,
129 : TyTy::ADTType *type)
130 : {
131 6047 : rust_assert (type != nullptr);
132 6047 : auto inserted
133 6047 : = adt_substitutions.emplace (make_adt_substitution_key (id, mappings),
134 : type);
135 6047 : rust_assert (inserted.second);
136 6047 : }
137 :
138 : bool
139 6313419 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
140 : {
141 6313419 : auto it = resolved.find (id);
142 6313419 : if (it == resolved.end ())
143 : return false;
144 :
145 6100152 : *type = it->second;
146 6100152 : return true;
147 : }
148 :
149 : void
150 3088 : TypeCheckContext::mark_function_body_pending (DefId id)
151 : {
152 3088 : function_bodies_pending.insert (id);
153 3088 : }
154 :
155 : void
156 15849 : TypeCheckContext::clear_function_body_pending (DefId id)
157 : {
158 15849 : function_bodies_pending.erase (id);
159 15849 : }
160 :
161 : bool
162 3096 : TypeCheckContext::function_body_pending (DefId id) const
163 : {
164 3096 : return function_bodies_pending.find (id) != function_bodies_pending.end ();
165 : }
166 :
167 : void
168 4406 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
169 : {
170 4406 : auto it = resolved.find (ty->get_ref ());
171 4406 : if (it == resolved.end ())
172 4406 : return;
173 :
174 4406 : resolved.erase (it);
175 : }
176 :
177 : void
178 0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
179 : {
180 0 : rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
181 0 : node_id_refs[ref] = id;
182 0 : }
183 :
184 : bool
185 0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
186 : {
187 0 : auto it = node_id_refs.find (ref);
188 0 : if (it == node_id_refs.end ())
189 : return false;
190 :
191 0 : *id = it->second;
192 0 : return true;
193 : }
194 :
195 : bool
196 18139 : TypeCheckContext::have_function_context () const
197 : {
198 18139 : return !return_type_stack.empty ();
199 : }
200 :
201 : TyTy::BaseType *
202 642 : TypeCheckContext::peek_return_type ()
203 : {
204 642 : rust_assert (!return_type_stack.empty ());
205 642 : return return_type_stack.back ().second;
206 : }
207 :
208 : void
209 15849 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
210 : TyTy::BaseType *return_type)
211 : {
212 15849 : return_type_stack.emplace_back (std::move (item), return_type);
213 : // a query can check another function body while an expression in the
214 : // caller has an expected type
215 15849 : push_expected_type (nullptr);
216 15849 : }
217 :
218 : void
219 15849 : TypeCheckContext::pop_return_type ()
220 : {
221 15849 : rust_assert (!return_type_stack.empty ());
222 15849 : pop_expected_type ();
223 15849 : return_type_stack.pop_back ();
224 15849 : }
225 :
226 : TypeCheckContextItem
227 17470 : TypeCheckContext::peek_context ()
228 : {
229 17470 : rust_assert (!return_type_stack.empty ());
230 17470 : return return_type_stack.back ().first;
231 : }
232 :
233 : void
234 72321 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
235 : {
236 72321 : expected_type_stack.push_back (expected);
237 72321 : }
238 :
239 : void
240 72321 : TypeCheckContext::pop_expected_type ()
241 : {
242 72321 : rust_assert (!expected_type_stack.empty ());
243 72321 : expected_type_stack.pop_back ();
244 72321 : }
245 :
246 : TyTy::BaseType *
247 37309 : TypeCheckContext::peek_expected_type () const
248 : {
249 37309 : if (expected_type_stack.empty ())
250 : return nullptr;
251 37022 : return expected_type_stack.back ();
252 : }
253 :
254 : StackedContexts<TypeCheckBlockContextItem> &
255 33348 : TypeCheckContext::block_context ()
256 : {
257 33348 : return block_stack;
258 : }
259 :
260 : void
261 4562 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
262 : {
263 541319 : for (auto it = resolved.begin (); it != resolved.end (); it++)
264 : {
265 536757 : if (!cb (it->first, it->second))
266 4562 : return;
267 : }
268 : }
269 :
270 : bool
271 148 : TypeCheckContext::have_loop_context () const
272 : {
273 148 : return !loop_type_stack.empty ();
274 : }
275 :
276 : void
277 155 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
278 : {
279 155 : TyTy::BaseType *infer_var
280 : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
281 155 : TyTy::InferType::TypeHint::Default (), locus);
282 155 : loop_type_stack.push_back (infer_var);
283 155 : }
284 :
285 : void
286 94 : TypeCheckContext::push_new_while_loop_context (HirId id)
287 : {
288 94 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
289 94 : loop_type_stack.push_back (infer_var);
290 94 : }
291 :
292 : TyTy::BaseType *
293 274 : TypeCheckContext::peek_loop_context ()
294 : {
295 274 : return loop_type_stack.back ();
296 : }
297 :
298 : TyTy::BaseType *
299 249 : TypeCheckContext::pop_loop_context ()
300 : {
301 249 : auto back = peek_loop_context ();
302 249 : loop_type_stack.pop_back ();
303 249 : return back;
304 : }
305 :
306 : void
307 21 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
308 : {
309 21 : loop_type_stack.pop_back ();
310 21 : loop_type_stack.push_back (val);
311 21 : }
312 :
313 : bool
314 3908 : TypeCheckContext::find_matching_impl_trait_frame (
315 : const TraitReference &tref, TyTy::BaseType &self,
316 : struct ImplTraitContextFrame *find) const
317 : {
318 3908 : if (!have_impl_trait_context ())
319 : return false;
320 :
321 2869 : for (auto it = impl_trait_frame_stack.rbegin ();
322 2869 : it != impl_trait_frame_stack.rend (); ++it)
323 : {
324 2088 : const auto &i = *it;
325 2088 : if (!i.trait->is_equal (tref))
326 675 : continue;
327 :
328 1413 : TyTy::BaseType *resolved_self = &self;
329 1413 : bool unresolved_trait_self = false;
330 1413 : if (auto param = self.try_as<TyTy::ParamType> ())
331 : {
332 85 : if (param->can_resolve ())
333 84 : resolved_self = param->resolve ();
334 : else
335 1 : unresolved_trait_self = param->is_implicit_self_trait ();
336 : }
337 :
338 : // Select an existing impl context without inferring a new Self
339 : // binding
340 1497 : bool compatible_self = unresolved_trait_self;
341 85 : if (!compatible_self)
342 : {
343 1412 : auto res
344 1412 : = unify_site_and (UNKNOWN_HIRID, TyTy::TyWithLocation (i.self),
345 1412 : TyTy::TyWithLocation (resolved_self),
346 : UNDEF_LOCATION, false /* emit_errors */,
347 : false /* commit */, false /* infer */,
348 : true /* cleanup */, false /* check_bounds */);
349 1412 : compatible_self = res->get_kind () != TyTy::TypeKind::ERROR;
350 : }
351 :
352 1412 : if (compatible_self)
353 : {
354 1280 : *find = i;
355 : return true;
356 : }
357 : }
358 :
359 : return false;
360 : }
361 :
362 : bool
363 3908 : TypeCheckContext::have_impl_trait_context () const
364 : {
365 3908 : return !impl_trait_frame_stack.empty ();
366 : }
367 :
368 : void
369 13554 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
370 : {
371 13554 : impl_trait_frame_stack.push_back (frame);
372 13554 : }
373 :
374 : struct ImplTraitContextFrame
375 13554 : TypeCheckContext::pop_impl_trait_context ()
376 : {
377 13554 : auto back = peek_impl_trait_context ();
378 13554 : impl_trait_frame_stack.pop_back ();
379 13554 : return back;
380 : }
381 :
382 : struct ImplTraitContextFrame
383 13554 : TypeCheckContext::peek_impl_trait_context ()
384 : {
385 13554 : return impl_trait_frame_stack.back ();
386 : }
387 :
388 : void
389 4242 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
390 : {
391 4242 : rust_assert (trait_context.find (id) == trait_context.end ());
392 4242 : trait_context.emplace (id, std::move (ref));
393 4242 : }
394 :
395 : bool
396 521006 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
397 : {
398 521006 : auto it = trait_context.find (id);
399 521006 : if (it == trait_context.end ())
400 : return false;
401 :
402 493333 : *ref = &it->second;
403 493333 : return true;
404 : }
405 :
406 : bool
407 5357 : TypeCheckContext::insert_associated_trait_impl (
408 : HirId id, AssociatedImplTrait &&associated)
409 : {
410 5357 : auto it = associated_impl_traits.find (id);
411 5357 : if (it != associated_impl_traits.end ())
412 : {
413 : return false;
414 : }
415 5356 : associated_impl_traits.emplace (id, std::move (associated));
416 5356 : return true;
417 : }
418 :
419 : bool
420 26638 : TypeCheckContext::lookup_associated_trait_impl (
421 : HirId id, AssociatedImplTrait **associated)
422 : {
423 26638 : auto it = associated_impl_traits.find (id);
424 26638 : if (it == associated_impl_traits.end ())
425 : return false;
426 :
427 10601 : *associated = &it->second;
428 10601 : return true;
429 : }
430 :
431 : void
432 0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
433 : {
434 0 : associated_type_mappings[id] = mapping;
435 0 : }
436 :
437 : void
438 0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
439 : {
440 0 : auto it = associated_type_mappings.find (id);
441 0 : if (it != associated_type_mappings.end ())
442 0 : associated_type_mappings.erase (it);
443 0 : }
444 :
445 : // lookup any associated type mappings, the out parameter of mapping is
446 : // allowed to be nullptr which allows this interface to do a simple does exist
447 : // check
448 : bool
449 0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
450 : {
451 0 : auto it = associated_type_mappings.find (id);
452 0 : if (it == associated_type_mappings.end ())
453 : return false;
454 :
455 0 : if (mapping != nullptr)
456 0 : *mapping = it->second;
457 :
458 : return true;
459 : }
460 :
461 : void
462 5357 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
463 : TyTy::BaseType *impl_type,
464 : HirId impl_id)
465 : {
466 5357 : auto it = associated_traits_to_impls.find (trait_id);
467 5357 : if (it == associated_traits_to_impls.end ())
468 : {
469 1974 : associated_traits_to_impls[trait_id] = {};
470 : }
471 :
472 5357 : associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
473 5357 : }
474 :
475 : bool
476 0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
477 : TyTy::BaseType *self,
478 : HirId *mapping)
479 : {
480 0 : auto it = associated_traits_to_impls.find (trait_id);
481 0 : if (it == associated_traits_to_impls.end ())
482 : return false;
483 :
484 0 : for (auto &item : it->second)
485 : {
486 0 : if (types_compatable (TyTy::TyWithLocation (item.first),
487 0 : TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
488 : false))
489 : {
490 0 : *mapping = item.second;
491 0 : return true;
492 : }
493 : }
494 : return false;
495 : }
496 :
497 : void
498 49322 : TypeCheckContext::insert_autoderef_mappings (
499 : HirId id, std::vector<Adjustment> &&adjustments)
500 : {
501 49322 : autoderef_mappings.emplace (id, std::move (adjustments));
502 49322 : }
503 :
504 : bool
505 51920 : TypeCheckContext::lookup_autoderef_mappings (
506 : HirId id, std::vector<Adjustment> **adjustments)
507 : {
508 51920 : auto it = autoderef_mappings.find (id);
509 51920 : if (it == autoderef_mappings.end ())
510 : return false;
511 :
512 38290 : *adjustments = &it->second;
513 38290 : return true;
514 : }
515 :
516 : void
517 5752 : TypeCheckContext::insert_cast_autoderef_mappings (
518 : HirId id, std::vector<Adjustment> &&adjustments)
519 : {
520 5752 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
521 5752 : }
522 :
523 : bool
524 5391 : TypeCheckContext::lookup_cast_autoderef_mappings (
525 : HirId id, std::vector<Adjustment> **adjustments)
526 : {
527 5391 : auto it = cast_autoderef_mappings.find (id);
528 5391 : if (it == cast_autoderef_mappings.end ())
529 : return false;
530 :
531 5391 : *adjustments = &it->second;
532 5391 : return true;
533 : }
534 :
535 : void
536 4600 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
537 : {
538 4600 : auto it = variants.find (id);
539 4600 : rust_assert (it == variants.end ());
540 :
541 4600 : variants[id] = variant;
542 4600 : }
543 :
544 : bool
545 9021 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
546 : {
547 9021 : auto it = variants.find (id);
548 9021 : if (it == variants.end ())
549 : return false;
550 :
551 9015 : *variant = it->second;
552 9015 : return true;
553 : }
554 :
555 : void
556 1415 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
557 : {
558 1415 : auto it = operator_overloads.find (id);
559 1415 : rust_assert (it == operator_overloads.end ());
560 :
561 1415 : operator_overloads[id] = call_site;
562 1415 : }
563 :
564 : bool
565 25735 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
566 : {
567 25735 : auto it = operator_overloads.find (id);
568 25735 : if (it == operator_overloads.end ())
569 : return false;
570 :
571 2512 : *call = it->second;
572 2512 : return true;
573 : }
574 :
575 : void
576 15 : TypeCheckContext::insert_deferred_operator_overload (
577 : DeferredOpOverload deferred)
578 : {
579 15 : HirId expr_id = deferred.expr_id;
580 15 : deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
581 15 : }
582 :
583 : bool
584 0 : TypeCheckContext::lookup_deferred_operator_overload (
585 : HirId id, DeferredOpOverload *deferred)
586 : {
587 0 : auto it = deferred_operator_overloads.find (id);
588 0 : if (it == deferred_operator_overloads.end ())
589 : return false;
590 :
591 0 : *deferred = it->second;
592 0 : return true;
593 : }
594 :
595 : void
596 0 : TypeCheckContext::iterate_deferred_operator_overloads (
597 : std::function<bool (HirId, DeferredOpOverload &)> cb)
598 : {
599 0 : for (auto it = deferred_operator_overloads.begin ();
600 0 : it != deferred_operator_overloads.end (); it++)
601 : {
602 0 : if (!cb (it->first, it->second))
603 0 : return;
604 : }
605 : }
606 :
607 : void
608 6463 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
609 : {
610 6463 : unconstrained[id] = status;
611 6463 : }
612 :
613 : bool
614 35038 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
615 : {
616 35038 : auto it = unconstrained.find (id);
617 35038 : bool found = it != unconstrained.end ();
618 35038 : if (!found)
619 : return false;
620 :
621 28575 : *result = it->second;
622 28575 : return true;
623 : }
624 :
625 : void
626 7974 : TypeCheckContext::insert_resolved_predicate (
627 : HirId id, const TyTy::TypeBoundPredicate &predicate)
628 : {
629 : // auto it = predicates.find (id);
630 : // rust_assert (it == predicates.end ());
631 :
632 7974 : predicates.emplace (id, predicate);
633 7974 : }
634 :
635 : bool
636 34344 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
637 : {
638 34344 : auto it = predicates.find (id);
639 34344 : bool found = it != predicates.end ();
640 34344 : if (!found)
641 : return false;
642 :
643 26022 : *result = it->second;
644 26022 : return true;
645 : }
646 :
647 : std::vector<TyTy::TypeBoundPredicate>
648 10505 : TypeCheckContext::predicates_for_type (const TyTy::BaseType *receiver) const
649 : {
650 10505 : std::vector<TyTy::TypeBoundPredicate> result
651 10505 : = receiver->get_specified_bounds ();
652 :
653 166826 : for (const auto &entry : predicates)
654 : {
655 156321 : const auto &predicate = entry.second;
656 156321 : const auto &args = predicate.get_substitution_arguments ();
657 156321 : if (args.get_mappings ().empty ())
658 156316 : continue;
659 :
660 156321 : TyTy::BaseType *bound_self = args.get_mappings ().front ().get_tyty ();
661 175551 : if (bound_self == nullptr
662 156321 : || bound_self->get_kind () == TyTy::TypeKind::ERROR)
663 19230 : continue;
664 :
665 137091 : if (receiver->get_kind () != TyTy::TypeKind::PROJECTION
666 137091 : || bound_self->get_kind () != TyTy::TypeKind::PROJECTION)
667 137083 : continue;
668 :
669 8 : const auto *receiver_projection
670 : = static_cast<const TyTy::ProjectionType *> (receiver);
671 8 : const auto *bound_projection
672 : = static_cast<const TyTy::ProjectionType *> (bound_self);
673 :
674 8 : DefId receiver_item_defid = receiver_projection->get_item_defid ();
675 8 : DefId bound_item_defid = bound_projection->get_item_defid ();
676 8 : bool same_item = receiver_item_defid == bound_item_defid;
677 8 : if (!same_item)
678 1 : continue;
679 :
680 7 : DefId receiver_trait_defid
681 7 : = receiver_projection->get_trait_ref ()->get_mappings ().get_defid ();
682 7 : DefId bound_trait_defid
683 7 : = bound_projection->get_trait_ref ()->get_mappings ().get_defid ();
684 7 : bool same_trait = receiver_trait_defid == bound_trait_defid;
685 7 : if (!same_trait)
686 0 : continue;
687 :
688 : // Compatibility can unify unrelated parameters. Match their declaration
689 : // identities instead; copies and synthetic bound parameters retain them.
690 7 : const TyTy::BaseType *receiver_self = receiver_projection->get_self ();
691 7 : const TyTy::BaseType *bound_self_ty = bound_projection->get_self ();
692 7 : const auto *receiver_param
693 7 : = receiver_self->try_as<const TyTy::ParamType> ();
694 7 : const auto *bound_param = bound_self_ty->try_as<const TyTy::ParamType> ();
695 :
696 7 : bool either_self_is_param
697 7 : = receiver_param != nullptr || bound_param != nullptr;
698 7 : if (either_self_is_param)
699 : {
700 7 : bool both_selfs_are_param
701 : = receiver_param != nullptr && bound_param != nullptr;
702 7 : bool same_declaration
703 : = both_selfs_are_param
704 7 : && receiver_param->get_decl_id () == bound_param->get_decl_id ();
705 2 : if (!same_declaration)
706 2 : continue;
707 : }
708 : else
709 : {
710 0 : bool selfs_compatible = types_compatable (
711 0 : TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (receiver_self)),
712 0 : TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (bound_self_ty)),
713 : UNKNOWN_LOCATION, false, false);
714 0 : if (!selfs_compatible)
715 0 : continue;
716 : }
717 :
718 5 : bool projections_compatible = types_compatable (
719 5 : TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (receiver)),
720 5 : TyTy::TyWithLocation (bound_self), UNKNOWN_LOCATION, false, false);
721 5 : if (projections_compatible)
722 5 : result.push_back (predicate);
723 : }
724 :
725 10505 : return result;
726 : }
727 :
728 : void
729 8127 : TypeCheckContext::insert_query (HirId id)
730 : {
731 8127 : querys_in_progress.insert (id);
732 8127 : }
733 :
734 : void
735 8127 : TypeCheckContext::query_completed (HirId id)
736 : {
737 8127 : querys_in_progress.erase (id);
738 8127 : }
739 :
740 : bool
741 8572 : TypeCheckContext::query_in_progress (HirId id) const
742 : {
743 8572 : return querys_in_progress.find (id) != querys_in_progress.end ();
744 : }
745 :
746 : void
747 4257 : TypeCheckContext::insert_trait_query (DefId id)
748 : {
749 4257 : trait_queries_in_progress.insert (id);
750 4257 : }
751 :
752 : void
753 4257 : TypeCheckContext::trait_query_completed (DefId id)
754 : {
755 4257 : trait_queries_in_progress.erase (id);
756 4257 : }
757 :
758 : bool
759 4261 : TypeCheckContext::trait_query_in_progress (DefId id) const
760 : {
761 4261 : return trait_queries_in_progress.find (id)
762 4261 : != trait_queries_in_progress.end ();
763 : }
764 :
765 : Lifetime
766 940 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
767 : {
768 940 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
769 : {
770 939 : auto maybe_interned = lookup_lifetime (lifetime);
771 939 : if (maybe_interned)
772 830 : return *maybe_interned;
773 :
774 109 : auto interned = next_lifetime_index.next ();
775 109 : lifetime_name_interner[lifetime.get_name ()] = interned;
776 109 : return interned;
777 : }
778 1 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
779 : {
780 1 : return next_lifetime_index.next ();
781 : }
782 0 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
783 : {
784 0 : return Lifetime::static_lifetime ();
785 : }
786 0 : rust_unreachable ();
787 : }
788 :
789 : tl::optional<Lifetime>
790 10833 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
791 : {
792 10833 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
793 : {
794 1257 : if (lifetime.get_name () == "static")
795 : {
796 1 : rich_location r (line_table, lifetime.get_locus ());
797 1 : r.add_fixit_insert_after (lifetime.get_locus (),
798 : "static is a reserved lifetime name");
799 1 : rust_error_at (r, ErrorCode::E0262,
800 : "invalid lifetime parameter name: %qs",
801 1 : lifetime.get_name ().c_str ());
802 1 : return tl::nullopt;
803 1 : }
804 1256 : const auto name = lifetime.get_name ();
805 1256 : auto it = lifetime_name_interner.find (name);
806 1256 : if (it == lifetime_name_interner.end ())
807 113 : return tl::nullopt;
808 1143 : return it->second;
809 1256 : }
810 9576 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
811 : {
812 9476 : return Lifetime::anonymous_lifetime ();
813 : }
814 100 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
815 : {
816 100 : return Lifetime::static_lifetime ();
817 : }
818 0 : rust_unreachable ();
819 : }
820 :
821 : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
822 9894 : TypeCheckContext::lookup_and_resolve_lifetime (
823 : const HIR::Lifetime &lifetime) const
824 : {
825 9894 : auto maybe_interned = lookup_lifetime (lifetime);
826 9894 : if (!maybe_interned)
827 5 : return tl::nullopt;
828 :
829 9889 : return get_lifetime_resolver ().resolve (maybe_interned.value ());
830 : }
831 : void
832 41 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
833 : {
834 41 : get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
835 41 : }
836 :
837 : WARN_UNUSED_RESULT std::vector<TyTy::Region>
838 11061 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
839 : {
840 11061 : std::vector<TyTy::Region> regions;
841 11103 : for (const auto &lifetime : args.get_lifetime_args ())
842 : {
843 43 : auto resolved = lookup_and_resolve_lifetime (lifetime);
844 43 : if (!resolved)
845 : {
846 1 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
847 1 : return {};
848 : }
849 42 : regions.push_back (*resolved);
850 : }
851 11060 : return regions;
852 11061 : }
853 :
854 : bool
855 15 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
856 : DeferredOpOverload &op)
857 : {
858 15 : rust_debug ("attempting resolution of deferred operator overload");
859 :
860 15 : TyTy::BaseType *lhs = nullptr;
861 15 : bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
862 15 : rust_assert (ok);
863 :
864 15 : TyTy::BaseType *rhs = nullptr;
865 15 : if (op.op.has_rvalue_mappings ())
866 : {
867 15 : bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
868 15 : rust_assert (ok);
869 : }
870 :
871 15 : TyTy::BaseType *current_result = op.result_type.get_tyty ();
872 15 : rust_assert (current_result != nullptr);
873 :
874 15 : rust_debug ("deferred operator expr=%u lhs=%s rhs=%s "
875 : "stored-result=%s current-result=%s result-ref=%u ty-ref=%u",
876 : id, lhs->debug_str ().c_str (),
877 : rhs == nullptr ? "<none>" : rhs->debug_str ().c_str (),
878 : current_result->debug_str ().c_str (),
879 : current_result->debug_str ().c_str (), op.result_type.get_ref (),
880 : current_result->get_ty_ref ());
881 :
882 15 : TyTy::BaseType *resolved
883 15 : = TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
884 15 : op.specified_segment, current_result);
885 15 : if (resolved == nullptr)
886 : return false;
887 :
888 15 : TyTy::BaseType *result
889 15 : = unify_site (id, TyTy::TyWithLocation (current_result),
890 15 : TyTy::TyWithLocation (resolved), op.op.get_locus ());
891 15 : rust_assert (result != nullptr);
892 15 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
893 :
894 : return true;
895 : }
896 :
897 : void
898 4562 : TypeCheckContext::compute_inference_variables (bool emit_error)
899 : {
900 9124 : auto resolve_deferred_operator_overloads = [this] () {
901 9139 : bool progress;
902 9139 : do
903 : {
904 9139 : progress = false;
905 9139 : for (auto it = deferred_operator_overloads.begin ();
906 9154 : it != deferred_operator_overloads.end ();)
907 : {
908 15 : if (compute_ambigious_op_overload (it->first, it->second))
909 : {
910 15 : it = deferred_operator_overloads.erase (it);
911 15 : progress = true;
912 : }
913 : else
914 0 : ++it;
915 : }
916 : }
917 : while (progress);
918 13686 : };
919 :
920 4562 : resolve_deferred_operator_overloads ();
921 :
922 4562 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
923 536757 : return compute_infer_var (id, ty, emit_error);
924 : });
925 :
926 4562 : resolve_deferred_operator_overloads ();
927 4562 : }
928 :
929 : bool
930 536757 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
931 : bool emit_error)
932 : {
933 536757 : auto &mappings = Analysis::Mappings::get ();
934 :
935 : // nothing to do
936 536757 : if (ty->get_kind () != TyTy::TypeKind::INFER)
937 : return true;
938 :
939 1616 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
940 1616 : TyTy::BaseType *default_type;
941 :
942 1616 : TyTy::BaseType *current = TyTy::TyVar (ty->get_ref ()).get_tyty ();
943 1616 : rust_assert (current != nullptr);
944 :
945 1616 : rust_debug_loc (mappings.lookup_location (id),
946 : "trying to default infer-var id=%u ref=%u ty-ref=%u "
947 : "stored=%s current=%s",
948 : id, ty->get_ref (), ty->get_ty_ref (),
949 : infer_var->debug_str ().c_str (),
950 : current->debug_str ().c_str ());
951 1616 : bool ok = infer_var->default_type (&default_type);
952 1616 : if (!ok)
953 : {
954 8 : if (emit_error)
955 8 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
956 : "type annotations needed");
957 : return true;
958 : }
959 :
960 1608 : rust_debug_loc (mappings.lookup_location (id), "default type selected: %s",
961 : default_type->debug_str ().c_str ());
962 :
963 1608 : auto result
964 1608 : = unify_site (id, TyTy::TyWithLocation (ty),
965 1608 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
966 1608 : rust_assert (result);
967 1608 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
968 1608 : result->set_ref (id);
969 1608 : insert_implicit_type (id, result);
970 :
971 1608 : return true;
972 : }
973 :
974 : TyTy::VarianceAnalysis::CrateCtx &
975 8893 : TypeCheckContext::get_variance_analysis_ctx ()
976 : {
977 8893 : return variance_analysis_ctx;
978 : }
979 :
980 : // TypeCheckContextItem
981 :
982 10278 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
983 :
984 7915 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
985 : HIR::Function *item)
986 7915 : : impl_item ({impl_block, item})
987 7915 : {}
988 :
989 869 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
990 869 : : trait_item (trait_item)
991 869 : {}
992 :
993 7065 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
994 7065 : : type (ItemType::ITEM), item (item)
995 7065 : {}
996 :
997 7915 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
998 : HIR::Function *item)
999 7915 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
1000 7915 : {}
1001 :
1002 869 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
1003 869 : : type (ItemType::TRAIT_ITEM), item (trait_item)
1004 869 : {}
1005 :
1006 33402 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
1007 33402 : : type (other.type), item (other.item)
1008 : {
1009 33402 : switch (other.type)
1010 : {
1011 15616 : case ITEM:
1012 15616 : item.item = other.item.item;
1013 15616 : break;
1014 :
1015 16353 : case IMPL_ITEM:
1016 16353 : item.impl_item = other.item.impl_item;
1017 16353 : break;
1018 :
1019 1433 : case TRAIT_ITEM:
1020 1433 : item.trait_item = other.item.trait_item;
1021 1433 : break;
1022 :
1023 0 : case ERROR:
1024 0 : item.item = nullptr;
1025 0 : break;
1026 : }
1027 33402 : }
1028 :
1029 3213 : TypeCheckContextItem::TypeCheckContextItem ()
1030 3213 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
1031 3213 : {}
1032 :
1033 : TypeCheckContextItem &
1034 3198 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
1035 : {
1036 3198 : type = other.type;
1037 3198 : switch (other.type)
1038 : {
1039 721 : case ITEM:
1040 721 : item.item = other.item.item;
1041 721 : break;
1042 :
1043 2363 : case IMPL_ITEM:
1044 2363 : item.impl_item = other.item.impl_item;
1045 2363 : break;
1046 :
1047 114 : case TRAIT_ITEM:
1048 114 : item.trait_item = other.item.trait_item;
1049 114 : break;
1050 :
1051 0 : case ERROR:
1052 0 : item.item = nullptr;
1053 0 : break;
1054 : }
1055 :
1056 3198 : return *this;
1057 : }
1058 :
1059 : TypeCheckContextItem
1060 3213 : TypeCheckContextItem::get_error ()
1061 : {
1062 3213 : return TypeCheckContextItem ();
1063 : }
1064 :
1065 : bool
1066 0 : TypeCheckContextItem::is_error () const
1067 : {
1068 0 : return type == ERROR;
1069 : }
1070 :
1071 : HIR::Function *
1072 63 : TypeCheckContextItem::get_item ()
1073 : {
1074 63 : rust_assert (get_type () == ItemType::ITEM);
1075 63 : return item.item;
1076 : }
1077 :
1078 : std::pair<HIR::ImplBlock *, HIR::Function *> &
1079 781 : TypeCheckContextItem::get_impl_item ()
1080 : {
1081 781 : rust_assert (get_type () == ItemType::IMPL_ITEM);
1082 781 : return item.impl_item;
1083 : }
1084 :
1085 : HIR::TraitItemFunc *
1086 1 : TypeCheckContextItem::get_trait_item ()
1087 : {
1088 1 : rust_assert (get_type () == ItemType::TRAIT_ITEM);
1089 1 : return item.trait_item;
1090 : }
1091 :
1092 : TypeCheckContextItem::ItemType
1093 20134 : TypeCheckContextItem::get_type () const
1094 : {
1095 20134 : return type;
1096 : }
1097 :
1098 : TyTy::FnType *
1099 64 : TypeCheckContextItem::get_context_type ()
1100 : {
1101 64 : auto &context = *TypeCheckContext::get ();
1102 :
1103 64 : HirId reference = UNKNOWN_HIRID;
1104 64 : switch (get_type ())
1105 : {
1106 63 : case ITEM:
1107 63 : reference = get_item ()->get_mappings ().get_hirid ();
1108 63 : break;
1109 :
1110 0 : case IMPL_ITEM:
1111 0 : reference = get_impl_item ().second->get_mappings ().get_hirid ();
1112 0 : break;
1113 :
1114 1 : case TRAIT_ITEM:
1115 1 : reference = get_trait_item ()->get_mappings ().get_hirid ();
1116 1 : break;
1117 :
1118 0 : case ERROR:
1119 0 : rust_unreachable ();
1120 : return nullptr;
1121 : }
1122 :
1123 64 : rust_assert (reference != UNKNOWN_HIRID);
1124 :
1125 64 : TyTy::BaseType *lookup = nullptr;
1126 64 : bool ok = context.lookup_type (reference, &lookup);
1127 64 : rust_assert (ok);
1128 64 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
1129 64 : return static_cast<TyTy::FnType *> (lookup);
1130 : }
1131 :
1132 : DefId
1133 3439 : TypeCheckContextItem::get_defid () const
1134 : {
1135 3439 : switch (get_type ())
1136 : {
1137 959 : case ITEM:
1138 959 : return item.item->get_mappings ().get_defid ();
1139 :
1140 2270 : case IMPL_ITEM:
1141 2270 : return item.impl_item.second->get_mappings ().get_defid ();
1142 :
1143 114 : case TRAIT_ITEM:
1144 114 : return item.trait_item->get_mappings ().get_defid ();
1145 :
1146 96 : case ERROR:
1147 96 : return UNKNOWN_DEFID;
1148 : }
1149 :
1150 0 : return UNKNOWN_DEFID;
1151 : }
1152 :
1153 : // TypeCheckBlockContextItem
1154 :
1155 11456 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
1156 :
1157 4242 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
1158 :
1159 11456 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
1160 11456 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
1161 11456 : {}
1162 :
1163 4242 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
1164 4242 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
1165 4242 : {}
1166 :
1167 : bool
1168 0 : TypeCheckBlockContextItem::is_impl_block () const
1169 : {
1170 0 : return type == IMPL_BLOCK;
1171 : }
1172 :
1173 : bool
1174 976 : TypeCheckBlockContextItem::is_trait_block () const
1175 : {
1176 976 : return type == TRAIT;
1177 : }
1178 :
1179 : HIR::ImplBlock &
1180 166 : TypeCheckBlockContextItem::get_impl_block ()
1181 : {
1182 166 : return *(item.block);
1183 : }
1184 :
1185 : HIR::Trait &
1186 810 : TypeCheckBlockContextItem::get_trait ()
1187 : {
1188 810 : return *(item.trait);
1189 : }
1190 :
1191 : } // namespace Resolver
1192 : } // namespace Rust
|