Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-hir-type-check.h"
20 : : #include "rust-type-util.h"
21 : : #include "rust-hir-type-check-expr.h"
22 : :
23 : : namespace Rust {
24 : : namespace Resolver {
25 : :
26 : : TypeCheckContext *
27 : 10230527 : TypeCheckContext::get ()
28 : : {
29 : 10230527 : static TypeCheckContext *instance;
30 : 10230527 : if (instance == nullptr)
31 : 4290 : instance = new TypeCheckContext ();
32 : :
33 : 10230527 : return instance;
34 : : }
35 : :
36 : 4290 : 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 : 34933 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : : {
58 : 465832 : for (auto &builtin : builtins)
59 : : {
60 : 465832 : if (name.compare (builtin->as_string ()) == 0)
61 : : {
62 : 34933 : *type = builtin.get ();
63 : 34933 : return true;
64 : : }
65 : : }
66 : : return false;
67 : : }
68 : :
69 : : void
70 : 162944 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : : {
72 : 162944 : node_id_refs[ref] = id;
73 : 162944 : resolved[id] = type;
74 : 162944 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 : 162944 : }
76 : :
77 : : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 : 4118 : TypeCheckContext::get_builtins () const
79 : : {
80 : 4118 : return builtins;
81 : : }
82 : :
83 : : void
84 : 448837 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : : TyTy::BaseType *type)
86 : : {
87 : 448837 : rust_assert (type != nullptr);
88 : 448837 : NodeId ref = mappings.get_nodeid ();
89 : 448837 : HirId id = mappings.get_hirid ();
90 : 448837 : node_id_refs[ref] = id;
91 : 448837 : resolved[id] = type;
92 : 448837 : }
93 : :
94 : : void
95 : 128873 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : : {
97 : 128873 : rust_assert (type != nullptr);
98 : 128873 : resolved[id] = type;
99 : 128873 : }
100 : :
101 : : bool
102 : 7617882 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
103 : : {
104 : 7617882 : auto it = resolved.find (id);
105 : 7617882 : if (it == resolved.end ())
106 : : return false;
107 : :
108 : 7443870 : *type = it->second;
109 : 7443870 : return true;
110 : : }
111 : :
112 : : void
113 : 2086 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
114 : : {
115 : 2086 : auto it = resolved.find (ty->get_ref ());
116 : 2086 : if (it == resolved.end ())
117 : 2086 : return;
118 : :
119 : 2086 : 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 : 3366 : TypeCheckContext::have_function_context () const
142 : : {
143 : 3366 : return !return_type_stack.empty ();
144 : : }
145 : :
146 : : TyTy::BaseType *
147 : 493 : TypeCheckContext::peek_return_type ()
148 : : {
149 : 493 : rust_assert (!return_type_stack.empty ());
150 : 493 : return return_type_stack.back ().second;
151 : : }
152 : :
153 : : void
154 : 13780 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
155 : : TyTy::BaseType *return_type)
156 : : {
157 : 13780 : return_type_stack.push_back ({std::move (item), return_type});
158 : 13780 : }
159 : :
160 : : void
161 : 13780 : TypeCheckContext::pop_return_type ()
162 : : {
163 : 13780 : rust_assert (!return_type_stack.empty ());
164 : 13780 : return_type_stack.pop_back ();
165 : 13780 : }
166 : :
167 : : TypeCheckContextItem
168 : 2863 : TypeCheckContext::peek_context ()
169 : : {
170 : 2863 : rust_assert (!return_type_stack.empty ());
171 : 2863 : return return_type_stack.back ().first;
172 : : }
173 : :
174 : : StackedContexts<TypeCheckBlockContextItem> &
175 : 24906 : TypeCheckContext::block_context ()
176 : : {
177 : 24906 : return block_stack;
178 : : }
179 : :
180 : : void
181 : 3961 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
182 : : {
183 : 514855 : for (auto it = resolved.begin (); it != resolved.end (); it++)
184 : : {
185 : 510894 : if (!cb (it->first, it->second))
186 : 3961 : return;
187 : : }
188 : : }
189 : :
190 : : bool
191 : 86 : TypeCheckContext::have_loop_context () const
192 : : {
193 : 86 : return !loop_type_stack.empty ();
194 : : }
195 : :
196 : : void
197 : 110 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
198 : : {
199 : 110 : TyTy::BaseType *infer_var
200 : : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
201 : 110 : TyTy::InferType::TypeHint::Default (), locus);
202 : 110 : loop_type_stack.push_back (infer_var);
203 : 110 : }
204 : :
205 : : void
206 : 66 : TypeCheckContext::push_new_while_loop_context (HirId id)
207 : : {
208 : 66 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
209 : 66 : loop_type_stack.push_back (infer_var);
210 : 66 : }
211 : :
212 : : TyTy::BaseType *
213 : 193 : TypeCheckContext::peek_loop_context ()
214 : : {
215 : 193 : return loop_type_stack.back ();
216 : : }
217 : :
218 : : TyTy::BaseType *
219 : 176 : TypeCheckContext::pop_loop_context ()
220 : : {
221 : 176 : auto back = peek_loop_context ();
222 : 176 : loop_type_stack.pop_back ();
223 : 176 : return back;
224 : : }
225 : :
226 : : void
227 : 15 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
228 : : {
229 : 15 : loop_type_stack.pop_back ();
230 : 15 : loop_type_stack.push_back (val);
231 : 15 : }
232 : :
233 : : void
234 : 3592 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
235 : : {
236 : 3592 : rust_assert (trait_context.find (id) == trait_context.end ());
237 : 3592 : trait_context.emplace (id, std::move (ref));
238 : 3592 : }
239 : :
240 : : bool
241 : 688538 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
242 : : {
243 : 688538 : auto it = trait_context.find (id);
244 : 688538 : if (it == trait_context.end ())
245 : : return false;
246 : :
247 : 660177 : *ref = &it->second;
248 : 660177 : return true;
249 : : }
250 : :
251 : : void
252 : 4614 : TypeCheckContext::insert_associated_trait_impl (
253 : : HirId id, AssociatedImplTrait &&associated)
254 : : {
255 : 4614 : rust_assert (associated_impl_traits.find (id)
256 : : == associated_impl_traits.end ());
257 : 4614 : associated_impl_traits.emplace (id, std::move (associated));
258 : 4614 : }
259 : :
260 : : bool
261 : 51127 : TypeCheckContext::lookup_associated_trait_impl (
262 : : HirId id, AssociatedImplTrait **associated)
263 : : {
264 : 51127 : auto it = associated_impl_traits.find (id);
265 : 51127 : if (it == associated_impl_traits.end ())
266 : : return false;
267 : :
268 : 26219 : *associated = &it->second;
269 : 26219 : return true;
270 : : }
271 : :
272 : : void
273 : 3044 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
274 : : {
275 : 3044 : associated_type_mappings[id] = mapping;
276 : 3044 : }
277 : :
278 : : void
279 : 1182 : TypeCheckContext::clear_associated_type_mapping (HirId id)
280 : : {
281 : 1182 : auto it = associated_type_mappings.find (id);
282 : 1182 : if (it != associated_type_mappings.end ())
283 : 1180 : associated_type_mappings.erase (it);
284 : 1182 : }
285 : :
286 : : // lookup any associated type mappings, the out parameter of mapping is
287 : : // allowed to be nullptr which allows this interface to do a simple does exist
288 : : // check
289 : : bool
290 : 43382 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
291 : : {
292 : 43382 : auto it = associated_type_mappings.find (id);
293 : 43382 : if (it == associated_type_mappings.end ())
294 : : return false;
295 : :
296 : 23802 : if (mapping != nullptr)
297 : 23802 : *mapping = it->second;
298 : :
299 : : return true;
300 : : }
301 : :
302 : : void
303 : 4614 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
304 : : TyTy::BaseType *impl_type,
305 : : HirId impl_id)
306 : : {
307 : 4614 : auto it = associated_traits_to_impls.find (trait_id);
308 : 4614 : if (it == associated_traits_to_impls.end ())
309 : : {
310 : 1750 : associated_traits_to_impls[trait_id] = {};
311 : : }
312 : :
313 : 4614 : associated_traits_to_impls[trait_id].push_back ({impl_type, impl_id});
314 : 4614 : }
315 : :
316 : : bool
317 : 0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
318 : : TyTy::BaseType *self,
319 : : HirId *mapping)
320 : : {
321 : 0 : auto it = associated_traits_to_impls.find (trait_id);
322 : 0 : if (it == associated_traits_to_impls.end ())
323 : : return false;
324 : :
325 : 0 : for (auto &item : it->second)
326 : : {
327 : 0 : if (types_compatable (TyTy::TyWithLocation (item.first),
328 : 0 : TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
329 : : false))
330 : : {
331 : 0 : *mapping = item.second;
332 : 0 : return true;
333 : : }
334 : : }
335 : : return false;
336 : : }
337 : :
338 : : void
339 : 41941 : TypeCheckContext::insert_autoderef_mappings (
340 : : HirId id, std::vector<Adjustment> &&adjustments)
341 : : {
342 : 41941 : autoderef_mappings.emplace (id, std::move (adjustments));
343 : 41941 : }
344 : :
345 : : bool
346 : 45470 : TypeCheckContext::lookup_autoderef_mappings (
347 : : HirId id, std::vector<Adjustment> **adjustments)
348 : : {
349 : 45470 : auto it = autoderef_mappings.find (id);
350 : 45470 : if (it == autoderef_mappings.end ())
351 : : return false;
352 : :
353 : 33007 : *adjustments = &it->second;
354 : 33007 : return true;
355 : : }
356 : :
357 : : void
358 : 4926 : TypeCheckContext::insert_cast_autoderef_mappings (
359 : : HirId id, std::vector<Adjustment> &&adjustments)
360 : : {
361 : 4926 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
362 : 4926 : }
363 : :
364 : : bool
365 : 4627 : TypeCheckContext::lookup_cast_autoderef_mappings (
366 : : HirId id, std::vector<Adjustment> **adjustments)
367 : : {
368 : 4627 : auto it = cast_autoderef_mappings.find (id);
369 : 4627 : if (it == cast_autoderef_mappings.end ())
370 : : return false;
371 : :
372 : 4627 : *adjustments = &it->second;
373 : 4627 : return true;
374 : : }
375 : :
376 : : void
377 : 4230 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
378 : : {
379 : 4230 : auto it = variants.find (id);
380 : 4230 : rust_assert (it == variants.end ());
381 : :
382 : 4230 : variants[id] = variant;
383 : 4230 : }
384 : :
385 : : bool
386 : 8285 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
387 : : {
388 : 8285 : auto it = variants.find (id);
389 : 8285 : if (it == variants.end ())
390 : : return false;
391 : :
392 : 8282 : *variant = it->second;
393 : 8282 : return true;
394 : : }
395 : :
396 : : void
397 : 1328 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
398 : : {
399 : 1328 : auto it = operator_overloads.find (id);
400 : 1328 : rust_assert (it == operator_overloads.end ());
401 : :
402 : 1328 : operator_overloads[id] = call_site;
403 : 1328 : }
404 : :
405 : : bool
406 : 20733 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
407 : : {
408 : 20733 : auto it = operator_overloads.find (id);
409 : 20733 : if (it == operator_overloads.end ())
410 : : return false;
411 : :
412 : 2348 : *call = it->second;
413 : 2348 : return true;
414 : : }
415 : :
416 : : void
417 : 8 : TypeCheckContext::insert_deferred_operator_overload (
418 : : DeferredOpOverload deferred)
419 : : {
420 : 8 : HirId expr_id = deferred.expr_id;
421 : 8 : deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
422 : 8 : }
423 : :
424 : : bool
425 : 0 : TypeCheckContext::lookup_deferred_operator_overload (
426 : : HirId id, DeferredOpOverload *deferred)
427 : : {
428 : 0 : auto it = deferred_operator_overloads.find (id);
429 : 0 : if (it == deferred_operator_overloads.end ())
430 : : return false;
431 : :
432 : 0 : *deferred = it->second;
433 : 0 : return true;
434 : : }
435 : :
436 : : void
437 : 3961 : TypeCheckContext::iterate_deferred_operator_overloads (
438 : : std::function<bool (HirId, DeferredOpOverload &)> cb)
439 : : {
440 : 3969 : for (auto it = deferred_operator_overloads.begin ();
441 : 3969 : it != deferred_operator_overloads.end (); it++)
442 : : {
443 : 8 : if (!cb (it->first, it->second))
444 : 3961 : return;
445 : : }
446 : : }
447 : :
448 : : void
449 : 5581 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
450 : : {
451 : 5581 : unconstrained[id] = status;
452 : 5581 : }
453 : :
454 : : bool
455 : 41822 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
456 : : {
457 : 41822 : auto it = unconstrained.find (id);
458 : 41822 : bool found = it != unconstrained.end ();
459 : 41822 : if (!found)
460 : : return false;
461 : :
462 : 36241 : *result = it->second;
463 : 36241 : return true;
464 : : }
465 : :
466 : : void
467 : 6694 : TypeCheckContext::insert_resolved_predicate (HirId id,
468 : : TyTy::TypeBoundPredicate predicate)
469 : : {
470 : : // auto it = predicates.find (id);
471 : : // rust_assert (it == predicates.end ());
472 : :
473 : 6694 : predicates.insert ({id, predicate});
474 : 6694 : }
475 : :
476 : : bool
477 : 38770 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
478 : : {
479 : 38770 : auto it = predicates.find (id);
480 : 38770 : bool found = it != predicates.end ();
481 : 38770 : if (!found)
482 : : return false;
483 : :
484 : 32067 : *result = it->second;
485 : 32067 : return true;
486 : : }
487 : :
488 : : void
489 : 8638 : TypeCheckContext::insert_query (HirId id)
490 : : {
491 : 8638 : querys_in_progress.insert (id);
492 : 8638 : }
493 : :
494 : : void
495 : 8638 : TypeCheckContext::query_completed (HirId id)
496 : : {
497 : 8638 : querys_in_progress.erase (id);
498 : 8638 : }
499 : :
500 : : bool
501 : 14168 : TypeCheckContext::query_in_progress (HirId id) const
502 : : {
503 : 14168 : return querys_in_progress.find (id) != querys_in_progress.end ();
504 : : }
505 : :
506 : : void
507 : 3600 : TypeCheckContext::insert_trait_query (DefId id)
508 : : {
509 : 3600 : trait_queries_in_progress.insert (id);
510 : 3600 : }
511 : :
512 : : void
513 : 3600 : TypeCheckContext::trait_query_completed (DefId id)
514 : : {
515 : 3600 : trait_queries_in_progress.erase (id);
516 : 3600 : }
517 : :
518 : : bool
519 : 3604 : TypeCheckContext::trait_query_in_progress (DefId id) const
520 : : {
521 : 3604 : return trait_queries_in_progress.find (id)
522 : 3604 : != trait_queries_in_progress.end ();
523 : : }
524 : :
525 : : Lifetime
526 : 894 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
527 : : {
528 : 894 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
529 : : {
530 : 893 : auto maybe_interned = lookup_lifetime (lifetime);
531 : 893 : if (maybe_interned)
532 : 811 : return *maybe_interned;
533 : :
534 : 82 : auto interned = next_lifetime_index.next ();
535 : 82 : lifetime_name_interner[lifetime.get_name ()] = interned;
536 : 82 : return interned;
537 : : }
538 : 1 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
539 : : {
540 : 1 : return next_lifetime_index.next ();
541 : : }
542 : 0 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
543 : : {
544 : 0 : return Lifetime::static_lifetime ();
545 : : }
546 : 0 : rust_unreachable ();
547 : : }
548 : :
549 : : tl::optional<Lifetime>
550 : 30131 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
551 : : {
552 : 30131 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
553 : : {
554 : 1156 : if (lifetime.get_name () == "static")
555 : : {
556 : 1 : rich_location r (line_table, lifetime.get_locus ());
557 : 1 : r.add_fixit_insert_after (lifetime.get_locus (),
558 : : "static is a reserved lifetime name");
559 : 1 : rust_error_at (r, ErrorCode::E0262,
560 : : "invalid lifetime parameter name: %qs",
561 : 1 : lifetime.get_name ().c_str ());
562 : 1 : return tl::nullopt;
563 : 1 : }
564 : 1155 : const auto name = lifetime.get_name ();
565 : 1155 : auto it = lifetime_name_interner.find (name);
566 : 1155 : if (it == lifetime_name_interner.end ())
567 : 84 : return tl::nullopt;
568 : 1071 : return it->second;
569 : 1155 : }
570 : 28975 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
571 : : {
572 : 28888 : return Lifetime::anonymous_lifetime ();
573 : : }
574 : 87 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
575 : : {
576 : 87 : return Lifetime::static_lifetime ();
577 : : }
578 : 0 : rust_unreachable ();
579 : : }
580 : :
581 : : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
582 : 29238 : TypeCheckContext::lookup_and_resolve_lifetime (
583 : : const HIR::Lifetime &lifetime) const
584 : : {
585 : 29238 : auto maybe_interned = lookup_lifetime (lifetime);
586 : 29238 : if (!maybe_interned)
587 : 3 : return tl::nullopt;
588 : :
589 : 29235 : return get_lifetime_resolver ().resolve (maybe_interned.value ());
590 : : }
591 : : void
592 : 15 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
593 : : {
594 : 15 : get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
595 : 15 : }
596 : :
597 : : WARN_UNUSED_RESULT std::vector<TyTy::Region>
598 : 9097 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
599 : : {
600 : 9097 : std::vector<TyTy::Region> regions;
601 : 9122 : for (const auto &lifetime : args.get_lifetime_args ())
602 : : {
603 : 26 : auto resolved = lookup_and_resolve_lifetime (lifetime);
604 : 26 : if (!resolved)
605 : : {
606 : 1 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
607 : 1 : return {};
608 : : }
609 : 25 : regions.push_back (*resolved);
610 : : }
611 : 9096 : return regions;
612 : 9097 : }
613 : :
614 : : bool
615 : 8 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
616 : : DeferredOpOverload &op)
617 : : {
618 : 8 : rust_debug ("attempting resolution of op overload: %s",
619 : : op.predicate.as_string ().c_str ());
620 : :
621 : 8 : TyTy::BaseType *lhs = nullptr;
622 : 8 : bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
623 : 8 : rust_assert (ok);
624 : :
625 : 8 : TyTy::BaseType *rhs = nullptr;
626 : 8 : if (op.op.has_rvalue_mappings ())
627 : : {
628 : 8 : bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
629 : 8 : rust_assert (ok);
630 : : }
631 : :
632 : 8 : TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
633 : 8 : op.specified_segment);
634 : :
635 : 8 : return true;
636 : : }
637 : :
638 : : void
639 : 3961 : TypeCheckContext::compute_inference_variables (bool emit_error)
640 : : {
641 : 3961 : iterate_deferred_operator_overloads (
642 : 3961 : [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
643 : 8 : return compute_ambigious_op_overload (id, op);
644 : : });
645 : :
646 : 3961 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
647 : 510894 : return compute_infer_var (id, ty, emit_error);
648 : : });
649 : 3961 : }
650 : :
651 : : bool
652 : 510894 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
653 : : bool emit_error)
654 : : {
655 : 510894 : auto &mappings = Analysis::Mappings::get ();
656 : :
657 : : // nothing to do
658 : 510894 : if (ty->get_kind () != TyTy::TypeKind::INFER)
659 : : return true;
660 : :
661 : 2013 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
662 : 2013 : TyTy::BaseType *default_type;
663 : :
664 : 2013 : rust_debug_loc (mappings.lookup_location (id),
665 : : "trying to default infer-var: %s",
666 : 2013 : infer_var->as_string ().c_str ());
667 : 2013 : bool ok = infer_var->default_type (&default_type);
668 : 2013 : if (!ok)
669 : : {
670 : 12 : if (emit_error)
671 : 12 : rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
672 : : "type annotations needed");
673 : 12 : return true;
674 : : }
675 : :
676 : 2001 : auto result
677 : 2001 : = unify_site (id, TyTy::TyWithLocation (ty),
678 : 2001 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
679 : 2001 : rust_assert (result);
680 : 2001 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
681 : 2001 : result->set_ref (id);
682 : 2001 : insert_implicit_type (id, result);
683 : :
684 : 2001 : return true;
685 : : }
686 : :
687 : : TyTy::VarianceAnalysis::CrateCtx &
688 : 7689 : TypeCheckContext::get_variance_analysis_ctx ()
689 : : {
690 : 7689 : return variance_analysis_ctx;
691 : : }
692 : :
693 : : // TypeCheckContextItem
694 : :
695 : 8926 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
696 : :
697 : 6814 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
698 : : HIR::Function *item)
699 : 6814 : : impl_item ({impl_block, item})
700 : 6814 : {}
701 : :
702 : 849 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
703 : 849 : : trait_item (trait_item)
704 : 849 : {}
705 : :
706 : 6117 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
707 : 6117 : : type (ItemType::ITEM), item (item)
708 : 6117 : {}
709 : :
710 : 6814 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
711 : 6814 : HIR::Function *item)
712 : 6814 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
713 : 6814 : {}
714 : :
715 : 849 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
716 : 849 : : type (ItemType::TRAIT_ITEM), item (trait_item)
717 : 849 : {}
718 : :
719 : 32010 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
720 : 32010 : : type (other.type), item (other.item)
721 : : {
722 : 32010 : switch (other.type)
723 : : {
724 : : case ITEM:
725 : : item.item = other.item.item;
726 : : break;
727 : :
728 : 16564 : case IMPL_ITEM:
729 : 16564 : item.impl_item = other.item.impl_item;
730 : 16564 : break;
731 : :
732 : : case TRAIT_ITEM:
733 : : item.trait_item = other.item.trait_item;
734 : : break;
735 : :
736 : 0 : case ERROR:
737 : 0 : item.item = nullptr;
738 : 0 : break;
739 : : }
740 : 32010 : }
741 : :
742 : 2809 : TypeCheckContextItem::TypeCheckContextItem ()
743 : 2809 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
744 : 2809 : {}
745 : :
746 : : TypeCheckContextItem &
747 : 2801 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
748 : : {
749 : 2801 : type = other.type;
750 : 2801 : switch (other.type)
751 : : {
752 : 630 : case ITEM:
753 : 630 : item.item = other.item.item;
754 : 630 : break;
755 : :
756 : 2057 : case IMPL_ITEM:
757 : 2057 : item.impl_item = other.item.impl_item;
758 : 2057 : break;
759 : :
760 : 114 : case TRAIT_ITEM:
761 : 114 : item.trait_item = other.item.trait_item;
762 : 114 : break;
763 : :
764 : 0 : case ERROR:
765 : 0 : item.item = nullptr;
766 : 0 : break;
767 : : }
768 : :
769 : 2801 : return *this;
770 : : }
771 : :
772 : : TypeCheckContextItem
773 : 2809 : TypeCheckContextItem::get_error ()
774 : : {
775 : 2809 : return TypeCheckContextItem ();
776 : : }
777 : :
778 : : bool
779 : 0 : TypeCheckContextItem::is_error () const
780 : : {
781 : 0 : return type == ERROR;
782 : : }
783 : :
784 : : HIR::Function *
785 : 61 : TypeCheckContextItem::get_item ()
786 : : {
787 : 61 : rust_assert (get_type () == ItemType::ITEM);
788 : 61 : return item.item;
789 : : }
790 : :
791 : : std::pair<HIR::ImplBlock *, HIR::Function *> &
792 : 769 : TypeCheckContextItem::get_impl_item ()
793 : : {
794 : 769 : rust_assert (get_type () == ItemType::IMPL_ITEM);
795 : 769 : return item.impl_item;
796 : : }
797 : :
798 : : HIR::TraitItemFunc *
799 : 1 : TypeCheckContextItem::get_trait_item ()
800 : : {
801 : 1 : rust_assert (get_type () == ItemType::TRAIT_ITEM);
802 : 1 : return item.trait_item;
803 : : }
804 : :
805 : : TypeCheckContextItem::ItemType
806 : 5235 : TypeCheckContextItem::get_type () const
807 : : {
808 : 5235 : return type;
809 : : }
810 : :
811 : : TyTy::FnType *
812 : 62 : TypeCheckContextItem::get_context_type ()
813 : : {
814 : 62 : auto &context = *TypeCheckContext::get ();
815 : :
816 : 62 : HirId reference = UNKNOWN_HIRID;
817 : 62 : switch (get_type ())
818 : : {
819 : 61 : case ITEM:
820 : 61 : reference = get_item ()->get_mappings ().get_hirid ();
821 : 61 : break;
822 : :
823 : 0 : case IMPL_ITEM:
824 : 0 : reference = get_impl_item ().second->get_mappings ().get_hirid ();
825 : 0 : break;
826 : :
827 : 1 : case TRAIT_ITEM:
828 : 1 : reference = get_trait_item ()->get_mappings ().get_hirid ();
829 : 1 : break;
830 : :
831 : 0 : case ERROR:
832 : 0 : rust_unreachable ();
833 : : return nullptr;
834 : : }
835 : :
836 : 62 : rust_assert (reference != UNKNOWN_HIRID);
837 : :
838 : 62 : TyTy::BaseType *lookup = nullptr;
839 : 62 : bool ok = context.lookup_type (reference, &lookup);
840 : 62 : rust_assert (ok);
841 : 62 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
842 : 62 : return static_cast<TyTy::FnType *> (lookup);
843 : : }
844 : :
845 : : DefId
846 : 2851 : TypeCheckContextItem::get_defid () const
847 : : {
848 : 2851 : switch (get_type ())
849 : : {
850 : 744 : case ITEM:
851 : 744 : return item.item->get_mappings ().get_defid ();
852 : :
853 : 1985 : case IMPL_ITEM:
854 : 1985 : return item.impl_item.second->get_mappings ().get_defid ();
855 : :
856 : 114 : case TRAIT_ITEM:
857 : 114 : return item.trait_item->get_mappings ().get_defid ();
858 : :
859 : 8 : case ERROR:
860 : 8 : return UNKNOWN_DEFID;
861 : : }
862 : :
863 : 0 : return UNKNOWN_DEFID;
864 : : }
865 : :
866 : : // TypeCheckBlockContextItem
867 : :
868 : 8020 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
869 : :
870 : 3592 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
871 : :
872 : 8020 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
873 : 8020 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
874 : 8020 : {}
875 : :
876 : 3592 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
877 : 3592 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
878 : 3592 : {}
879 : :
880 : : bool
881 : 0 : TypeCheckBlockContextItem::is_impl_block () const
882 : : {
883 : 0 : return type == IMPL_BLOCK;
884 : : }
885 : :
886 : : bool
887 : 841 : TypeCheckBlockContextItem::is_trait_block () const
888 : : {
889 : 841 : return type == TRAIT;
890 : : }
891 : :
892 : : HIR::ImplBlock &
893 : 147 : TypeCheckBlockContextItem::get_impl_block ()
894 : : {
895 : 147 : return *(item.block);
896 : : }
897 : :
898 : : HIR::Trait &
899 : 694 : TypeCheckBlockContextItem::get_trait ()
900 : : {
901 : 694 : return *(item.trait);
902 : : }
903 : :
904 : : } // namespace Resolver
905 : : } // namespace Rust
|