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 26293946 : TypeCheckContext::get ()
28 : {
29 26293946 : static TypeCheckContext *instance;
30 26293946 : if (instance == nullptr)
31 4767 : instance = new TypeCheckContext ();
32 :
33 26293946 : return instance;
34 : }
35 :
36 4767 : 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 35401 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : {
58 401401 : for (auto &builtin : builtins)
59 : {
60 401401 : if (name.compare (builtin->as_string ()) == 0)
61 : {
62 35401 : *type = builtin.get ();
63 35401 : return true;
64 : }
65 : }
66 : return false;
67 : }
68 :
69 : void
70 90573 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : {
72 90573 : node_id_refs[ref] = id;
73 90573 : resolved[id] = type;
74 90573 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 90573 : }
76 :
77 : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 4538 : TypeCheckContext::get_builtins () const
79 : {
80 4538 : return builtins;
81 : }
82 :
83 : void
84 488919 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : TyTy::BaseType *type)
86 : {
87 488919 : rust_assert (type != nullptr);
88 488919 : NodeId ref = mappings.get_nodeid ();
89 488919 : HirId id = mappings.get_hirid ();
90 488919 : node_id_refs[ref] = id;
91 488919 : resolved[id] = type;
92 488919 : }
93 :
94 : void
95 288058 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : {
97 288058 : rust_assert (type != nullptr);
98 288058 : resolved[id] = type;
99 288058 : }
100 :
101 : bool
102 18823457 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
103 : {
104 18823457 : auto it = resolved.find (id);
105 18823457 : if (it == resolved.end ())
106 : return false;
107 :
108 18622453 : *type = it->second;
109 18622453 : return true;
110 : }
111 :
112 : void
113 127124 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
114 : {
115 127124 : auto it = resolved.find (ty->get_ref ());
116 127124 : if (it == resolved.end ())
117 127124 : return;
118 :
119 127124 : 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 3413 : TypeCheckContext::have_function_context () const
142 : {
143 3413 : return !return_type_stack.empty ();
144 : }
145 :
146 : TyTy::BaseType *
147 530 : TypeCheckContext::peek_return_type ()
148 : {
149 530 : rust_assert (!return_type_stack.empty ());
150 530 : return return_type_stack.back ().second;
151 : }
152 :
153 : void
154 14363 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
155 : TyTy::BaseType *return_type)
156 : {
157 14363 : return_type_stack.emplace_back (std::move (item), return_type);
158 14363 : }
159 :
160 : void
161 14363 : TypeCheckContext::pop_return_type ()
162 : {
163 14363 : rust_assert (!return_type_stack.empty ());
164 14363 : return_type_stack.pop_back ();
165 14363 : }
166 :
167 : TypeCheckContextItem
168 2873 : TypeCheckContext::peek_context ()
169 : {
170 2873 : rust_assert (!return_type_stack.empty ());
171 2873 : return return_type_stack.back ().first;
172 : }
173 :
174 : void
175 50820 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
176 : {
177 50820 : expected_type_stack.push_back (expected);
178 50820 : }
179 :
180 : void
181 50820 : TypeCheckContext::pop_expected_type ()
182 : {
183 50820 : rust_assert (!expected_type_stack.empty ());
184 50820 : expected_type_stack.pop_back ();
185 50820 : }
186 :
187 : TyTy::BaseType *
188 33863 : TypeCheckContext::peek_expected_type () const
189 : {
190 33863 : if (expected_type_stack.empty ())
191 : return nullptr;
192 23015 : return expected_type_stack.back ();
193 : }
194 :
195 : StackedContexts<TypeCheckBlockContextItem> &
196 25976 : TypeCheckContext::block_context ()
197 : {
198 25976 : return block_stack;
199 : }
200 :
201 : void
202 4346 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
203 : {
204 504698 : for (auto it = resolved.begin (); it != resolved.end (); it++)
205 : {
206 500352 : if (!cb (it->first, it->second))
207 4346 : return;
208 : }
209 : }
210 :
211 : bool
212 107 : TypeCheckContext::have_loop_context () const
213 : {
214 107 : return !loop_type_stack.empty ();
215 : }
216 :
217 : void
218 130 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
219 : {
220 130 : TyTy::BaseType *infer_var
221 : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
222 130 : TyTy::InferType::TypeHint::Default (), locus);
223 130 : loop_type_stack.push_back (infer_var);
224 130 : }
225 :
226 : void
227 78 : TypeCheckContext::push_new_while_loop_context (HirId id)
228 : {
229 78 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
230 78 : loop_type_stack.push_back (infer_var);
231 78 : }
232 :
233 : TyTy::BaseType *
234 231 : TypeCheckContext::peek_loop_context ()
235 : {
236 231 : return loop_type_stack.back ();
237 : }
238 :
239 : TyTy::BaseType *
240 208 : TypeCheckContext::pop_loop_context ()
241 : {
242 208 : auto back = peek_loop_context ();
243 208 : loop_type_stack.pop_back ();
244 208 : return back;
245 : }
246 :
247 : void
248 19 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
249 : {
250 19 : loop_type_stack.pop_back ();
251 19 : loop_type_stack.push_back (val);
252 19 : }
253 :
254 : bool
255 11109 : TypeCheckContext::find_matching_impl_trait_frame (
256 : const TraitReference &tref, struct ImplTraitContextFrame *find) const
257 : {
258 11109 : if (!have_impl_trait_context ())
259 : return false;
260 :
261 5814 : for (auto it = impl_trait_frame_stack.rbegin ();
262 5814 : it != impl_trait_frame_stack.rend (); ++it)
263 : {
264 5134 : const auto &i = *it;
265 5134 : if (i.trait->is_equal (tref))
266 : {
267 4450 : *find = i;
268 4450 : return true;
269 : }
270 : }
271 :
272 : return false;
273 : }
274 :
275 : bool
276 11109 : TypeCheckContext::have_impl_trait_context () const
277 : {
278 11109 : return !impl_trait_frame_stack.empty ();
279 : }
280 :
281 : void
282 13326 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
283 : {
284 13326 : impl_trait_frame_stack.push_back (frame);
285 13326 : }
286 :
287 : struct ImplTraitContextFrame
288 13326 : TypeCheckContext::pop_impl_trait_context ()
289 : {
290 13326 : auto back = peek_impl_trait_context ();
291 13326 : impl_trait_frame_stack.pop_back ();
292 13326 : return back;
293 : }
294 :
295 : struct ImplTraitContextFrame
296 13326 : TypeCheckContext::peek_impl_trait_context ()
297 : {
298 13326 : return impl_trait_frame_stack.back ();
299 : }
300 :
301 : void
302 3915 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
303 : {
304 3915 : rust_assert (trait_context.find (id) == trait_context.end ());
305 3915 : trait_context.emplace (id, std::move (ref));
306 3915 : }
307 :
308 : bool
309 1197955 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
310 : {
311 1197955 : auto it = trait_context.find (id);
312 1197955 : if (it == trait_context.end ())
313 : return false;
314 :
315 1172428 : *ref = &it->second;
316 1172428 : return true;
317 : }
318 :
319 : bool
320 4719 : TypeCheckContext::insert_associated_trait_impl (
321 : HirId id, AssociatedImplTrait &&associated)
322 : {
323 4719 : auto it = associated_impl_traits.find (id);
324 4719 : if (it != associated_impl_traits.end ())
325 : {
326 : return false;
327 : }
328 4718 : associated_impl_traits.emplace (id, std::move (associated));
329 4718 : return true;
330 : }
331 :
332 : bool
333 50761 : TypeCheckContext::lookup_associated_trait_impl (
334 : HirId id, AssociatedImplTrait **associated)
335 : {
336 50761 : auto it = associated_impl_traits.find (id);
337 50761 : if (it == associated_impl_traits.end ())
338 : return false;
339 :
340 27013 : *associated = &it->second;
341 27013 : 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 4719 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
376 : TyTy::BaseType *impl_type,
377 : HirId impl_id)
378 : {
379 4719 : auto it = associated_traits_to_impls.find (trait_id);
380 4719 : if (it == associated_traits_to_impls.end ())
381 : {
382 1824 : associated_traits_to_impls[trait_id] = {};
383 : }
384 :
385 4719 : associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
386 4719 : }
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 44876 : TypeCheckContext::insert_autoderef_mappings (
412 : HirId id, std::vector<Adjustment> &&adjustments)
413 : {
414 44876 : autoderef_mappings.emplace (id, std::move (adjustments));
415 44876 : }
416 :
417 : bool
418 47983 : TypeCheckContext::lookup_autoderef_mappings (
419 : HirId id, std::vector<Adjustment> **adjustments)
420 : {
421 47983 : auto it = autoderef_mappings.find (id);
422 47983 : if (it == autoderef_mappings.end ())
423 : return false;
424 :
425 34757 : *adjustments = &it->second;
426 34757 : return true;
427 : }
428 :
429 : void
430 5274 : TypeCheckContext::insert_cast_autoderef_mappings (
431 : HirId id, std::vector<Adjustment> &&adjustments)
432 : {
433 5274 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
434 5274 : }
435 :
436 : bool
437 4954 : TypeCheckContext::lookup_cast_autoderef_mappings (
438 : HirId id, std::vector<Adjustment> **adjustments)
439 : {
440 4954 : auto it = cast_autoderef_mappings.find (id);
441 4954 : if (it == cast_autoderef_mappings.end ())
442 : return false;
443 :
444 4954 : *adjustments = &it->second;
445 4954 : return true;
446 : }
447 :
448 : void
449 4274 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
450 : {
451 4274 : auto it = variants.find (id);
452 4274 : rust_assert (it == variants.end ());
453 :
454 4274 : variants[id] = variant;
455 4274 : }
456 :
457 : bool
458 8363 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
459 : {
460 8363 : auto it = variants.find (id);
461 8363 : if (it == variants.end ())
462 : return false;
463 :
464 8357 : *variant = it->second;
465 8357 : return true;
466 : }
467 :
468 : void
469 1330 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
470 : {
471 1330 : auto it = operator_overloads.find (id);
472 1330 : rust_assert (it == operator_overloads.end ());
473 :
474 1330 : operator_overloads[id] = call_site;
475 1330 : }
476 :
477 : bool
478 23435 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
479 : {
480 23435 : auto it = operator_overloads.find (id);
481 23435 : if (it == operator_overloads.end ())
482 : return false;
483 :
484 2352 : *call = it->second;
485 2352 : 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 4346 : TypeCheckContext::iterate_deferred_operator_overloads (
510 : std::function<bool (HirId, DeferredOpOverload &)> cb)
511 : {
512 4354 : for (auto it = deferred_operator_overloads.begin ();
513 4354 : it != deferred_operator_overloads.end (); it++)
514 : {
515 8 : if (!cb (it->first, it->second))
516 4346 : return;
517 : }
518 : }
519 :
520 : void
521 5740 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
522 : {
523 5740 : unconstrained[id] = status;
524 5740 : }
525 :
526 : bool
527 43721 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
528 : {
529 43721 : auto it = unconstrained.find (id);
530 43721 : bool found = it != unconstrained.end ();
531 43721 : if (!found)
532 : return false;
533 :
534 37981 : *result = it->second;
535 37981 : return true;
536 : }
537 :
538 : void
539 6921 : 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 6921 : predicates.insert ({id, predicate});
546 6921 : }
547 :
548 : bool
549 43199 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
550 : {
551 43199 : auto it = predicates.find (id);
552 43199 : bool found = it != predicates.end ();
553 43199 : if (!found)
554 : return false;
555 :
556 36269 : *result = it->second;
557 36269 : return true;
558 : }
559 :
560 : void
561 10960 : TypeCheckContext::insert_query (HirId id)
562 : {
563 10960 : querys_in_progress.insert (id);
564 10960 : }
565 :
566 : void
567 10960 : TypeCheckContext::query_completed (HirId id)
568 : {
569 10960 : querys_in_progress.erase (id);
570 10960 : }
571 :
572 : bool
573 16538 : TypeCheckContext::query_in_progress (HirId id) const
574 : {
575 16538 : return querys_in_progress.find (id) != querys_in_progress.end ();
576 : }
577 :
578 : void
579 3934 : TypeCheckContext::insert_trait_query (DefId id)
580 : {
581 3934 : trait_queries_in_progress.insert (id);
582 3934 : }
583 :
584 : void
585 3934 : TypeCheckContext::trait_query_completed (DefId id)
586 : {
587 3934 : trait_queries_in_progress.erase (id);
588 3934 : }
589 :
590 : bool
591 3938 : TypeCheckContext::trait_query_in_progress (DefId id) const
592 : {
593 3938 : return trait_queries_in_progress.find (id)
594 3938 : != trait_queries_in_progress.end ();
595 : }
596 :
597 : Lifetime
598 967 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
599 : {
600 967 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
601 : {
602 966 : auto maybe_interned = lookup_lifetime (lifetime);
603 966 : if (maybe_interned)
604 870 : return *maybe_interned;
605 :
606 96 : auto interned = next_lifetime_index.next ();
607 96 : lifetime_name_interner[lifetime.get_name ()] = interned;
608 96 : 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 30692 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
623 : {
624 30692 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
625 : {
626 1243 : 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 1242 : const auto name = lifetime.get_name ();
637 1242 : auto it = lifetime_name_interner.find (name);
638 1242 : if (it == lifetime_name_interner.end ())
639 100 : return tl::nullopt;
640 1142 : return it->second;
641 1242 : }
642 29449 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
643 : {
644 29360 : 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 29726 : TypeCheckContext::lookup_and_resolve_lifetime (
655 : const HIR::Lifetime &lifetime) const
656 : {
657 29726 : auto maybe_interned = lookup_lifetime (lifetime);
658 29726 : if (!maybe_interned)
659 5 : return tl::nullopt;
660 :
661 29721 : 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 9379 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
671 : {
672 9379 : std::vector<TyTy::Region> regions;
673 9408 : 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 9378 : return regions;
684 9379 : }
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 4346 : TypeCheckContext::compute_inference_variables (bool emit_error)
712 : {
713 4346 : iterate_deferred_operator_overloads (
714 4346 : [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
715 8 : return compute_ambigious_op_overload (id, op);
716 : });
717 :
718 4346 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
719 500352 : return compute_infer_var (id, ty, emit_error);
720 : });
721 4346 : }
722 :
723 : bool
724 500352 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
725 : bool emit_error)
726 : {
727 500352 : auto &mappings = Analysis::Mappings::get ();
728 :
729 : // nothing to do
730 500352 : if (ty->get_kind () != TyTy::TypeKind::INFER)
731 : return true;
732 :
733 1683 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
734 1683 : TyTy::BaseType *default_type;
735 :
736 1683 : rust_debug_loc (mappings.lookup_location (id),
737 : "trying to default infer-var: %s",
738 1683 : infer_var->as_string ().c_str ());
739 1683 : bool ok = infer_var->default_type (&default_type);
740 1683 : if (!ok)
741 : {
742 11 : if (emit_error)
743 11 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
744 : "type annotations needed");
745 11 : return true;
746 : }
747 :
748 1672 : auto result
749 1672 : = unify_site (id, TyTy::TyWithLocation (ty),
750 1672 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
751 1672 : rust_assert (result);
752 1672 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
753 1672 : result->set_ref (id);
754 1672 : insert_implicit_type (id, result);
755 :
756 1672 : return true;
757 : }
758 :
759 : TyTy::VarianceAnalysis::CrateCtx &
760 8286 : TypeCheckContext::get_variance_analysis_ctx ()
761 : {
762 8286 : return variance_analysis_ctx;
763 : }
764 :
765 : // TypeCheckContextItem
766 :
767 9394 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
768 :
769 6928 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
770 : HIR::Function *item)
771 6928 : : impl_item ({impl_block, item})
772 6928 : {}
773 :
774 858 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
775 858 : : trait_item (trait_item)
776 858 : {}
777 :
778 6577 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
779 6577 : : type (ItemType::ITEM), item (item)
780 6577 : {}
781 :
782 6928 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
783 6928 : HIR::Function *item)
784 6928 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
785 6928 : {}
786 :
787 858 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
788 858 : : type (ItemType::TRAIT_ITEM), item (trait_item)
789 858 : {}
790 :
791 18836 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
792 18836 : : type (other.type), item (other.item)
793 : {
794 18836 : switch (other.type)
795 : {
796 : case ITEM:
797 : item.item = other.item.item;
798 : break;
799 :
800 9877 : case IMPL_ITEM:
801 9877 : item.impl_item = other.item.impl_item;
802 9877 : break;
803 :
804 : case TRAIT_ITEM:
805 : item.trait_item = other.item.trait_item;
806 : break;
807 :
808 0 : case ERROR:
809 0 : item.item = nullptr;
810 0 : break;
811 : }
812 18836 : }
813 :
814 2817 : TypeCheckContextItem::TypeCheckContextItem ()
815 2817 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
816 2817 : {}
817 :
818 : TypeCheckContextItem &
819 2809 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
820 : {
821 2809 : type = other.type;
822 2809 : switch (other.type)
823 : {
824 630 : case ITEM:
825 630 : item.item = other.item.item;
826 630 : 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 2809 : return *this;
842 : }
843 :
844 : TypeCheckContextItem
845 2817 : TypeCheckContextItem::get_error ()
846 : {
847 2817 : 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 5245 : TypeCheckContextItem::get_type () const
879 : {
880 5245 : 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 2853 : TypeCheckContextItem::get_defid () const
919 : {
920 2853 : switch (get_type ())
921 : {
922 744 : case ITEM:
923 744 : 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 8182 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
941 :
942 3915 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
943 :
944 8182 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
945 8182 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
946 8182 : {}
947 :
948 3915 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
949 3915 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
950 3915 : {}
951 :
952 : bool
953 0 : TypeCheckBlockContextItem::is_impl_block () const
954 : {
955 0 : return type == IMPL_BLOCK;
956 : }
957 :
958 : bool
959 891 : TypeCheckBlockContextItem::is_trait_block () const
960 : {
961 891 : 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 733 : TypeCheckBlockContextItem::get_trait ()
972 : {
973 733 : return *(item.trait);
974 : }
975 :
976 : } // namespace Resolver
977 : } // namespace Rust
|