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 : 20876319 : TypeCheckContext::get ()
28 : : {
29 : 20876319 : static TypeCheckContext *instance;
30 : 20876319 : if (instance == nullptr)
31 : 4449 : instance = new TypeCheckContext ();
32 : :
33 : 20876319 : return instance;
34 : : }
35 : :
36 : 4449 : 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 : 35769 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
57 : : {
58 : 478313 : for (auto &builtin : builtins)
59 : : {
60 : 478313 : if (name.compare (builtin->as_string ()) == 0)
61 : : {
62 : 35769 : *type = builtin.get ();
63 : 35769 : return true;
64 : : }
65 : : }
66 : : return false;
67 : : }
68 : :
69 : : void
70 : 168967 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
71 : : {
72 : 168967 : node_id_refs[ref] = id;
73 : 168967 : resolved[id] = type;
74 : 168967 : builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
75 : 168967 : }
76 : :
77 : : const std::vector<std::unique_ptr<TyTy::BaseType>> &
78 : 4260 : TypeCheckContext::get_builtins () const
79 : : {
80 : 4260 : return builtins;
81 : : }
82 : :
83 : : void
84 : 458341 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
85 : : TyTy::BaseType *type)
86 : : {
87 : 458341 : rust_assert (type != nullptr);
88 : 458341 : NodeId ref = mappings.get_nodeid ();
89 : 458341 : HirId id = mappings.get_hirid ();
90 : 458341 : node_id_refs[ref] = id;
91 : 458341 : resolved[id] = type;
92 : 458341 : }
93 : :
94 : : void
95 : 222867 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
96 : : {
97 : 222867 : rust_assert (type != nullptr);
98 : 222867 : resolved[id] = type;
99 : 222867 : }
100 : :
101 : : bool
102 : 14489455 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
103 : : {
104 : 14489455 : auto it = resolved.find (id);
105 : 14489455 : if (it == resolved.end ())
106 : : return false;
107 : :
108 : 14309445 : *type = it->second;
109 : 14309445 : return true;
110 : : }
111 : :
112 : : void
113 : 84975 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
114 : : {
115 : 84975 : auto it = resolved.find (ty->get_ref ());
116 : 84975 : if (it == resolved.end ())
117 : 84975 : return;
118 : :
119 : 84975 : 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 : 3404 : TypeCheckContext::have_function_context () const
142 : : {
143 : 3404 : return !return_type_stack.empty ();
144 : : }
145 : :
146 : : TyTy::BaseType *
147 : 521 : TypeCheckContext::peek_return_type ()
148 : : {
149 : 521 : rust_assert (!return_type_stack.empty ());
150 : 521 : return return_type_stack.back ().second;
151 : : }
152 : :
153 : : void
154 : 13959 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
155 : : TyTy::BaseType *return_type)
156 : : {
157 : 13959 : return_type_stack.emplace_back (std::move (item), return_type);
158 : 13959 : }
159 : :
160 : : void
161 : 13959 : TypeCheckContext::pop_return_type ()
162 : : {
163 : 13959 : rust_assert (!return_type_stack.empty ());
164 : 13959 : return_type_stack.pop_back ();
165 : 13959 : }
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 : : StackedContexts<TypeCheckBlockContextItem> &
175 : 25150 : TypeCheckContext::block_context ()
176 : : {
177 : 25150 : return block_stack;
178 : : }
179 : :
180 : : void
181 : 4089 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
182 : : {
183 : 528113 : for (auto it = resolved.begin (); it != resolved.end (); it++)
184 : : {
185 : 524024 : if (!cb (it->first, it->second))
186 : 4089 : return;
187 : : }
188 : : }
189 : :
190 : : bool
191 : 92 : TypeCheckContext::have_loop_context () const
192 : : {
193 : 92 : return !loop_type_stack.empty ();
194 : : }
195 : :
196 : : void
197 : 111 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
198 : : {
199 : 111 : TyTy::BaseType *infer_var
200 : : = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
201 : 111 : TyTy::InferType::TypeHint::Default (), locus);
202 : 111 : loop_type_stack.push_back (infer_var);
203 : 111 : }
204 : :
205 : : void
206 : 70 : TypeCheckContext::push_new_while_loop_context (HirId id)
207 : : {
208 : 70 : TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
209 : 70 : loop_type_stack.push_back (infer_var);
210 : 70 : }
211 : :
212 : : TyTy::BaseType *
213 : 200 : TypeCheckContext::peek_loop_context ()
214 : : {
215 : 200 : return loop_type_stack.back ();
216 : : }
217 : :
218 : : TyTy::BaseType *
219 : 181 : TypeCheckContext::pop_loop_context ()
220 : : {
221 : 181 : auto back = peek_loop_context ();
222 : 181 : loop_type_stack.pop_back ();
223 : 181 : 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 : 3662 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
235 : : {
236 : 3662 : rust_assert (trait_context.find (id) == trait_context.end ());
237 : 3662 : trait_context.emplace (id, std::move (ref));
238 : 3662 : }
239 : :
240 : : bool
241 : 1047976 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
242 : : {
243 : 1047976 : auto it = trait_context.find (id);
244 : 1047976 : if (it == trait_context.end ())
245 : : return false;
246 : :
247 : 1020686 : *ref = &it->second;
248 : 1020686 : return true;
249 : : }
250 : :
251 : : void
252 : 4642 : TypeCheckContext::insert_associated_trait_impl (
253 : : HirId id, AssociatedImplTrait &&associated)
254 : : {
255 : 4642 : rust_assert (associated_impl_traits.find (id)
256 : : == associated_impl_traits.end ());
257 : 4642 : associated_impl_traits.emplace (id, std::move (associated));
258 : 4642 : }
259 : :
260 : : bool
261 : 51177 : TypeCheckContext::lookup_associated_trait_impl (
262 : : HirId id, AssociatedImplTrait **associated)
263 : : {
264 : 51177 : auto it = associated_impl_traits.find (id);
265 : 51177 : if (it == associated_impl_traits.end ())
266 : : return false;
267 : :
268 : 26228 : *associated = &it->second;
269 : 26228 : return true;
270 : : }
271 : :
272 : : void
273 : 3045 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
274 : : {
275 : 3045 : associated_type_mappings[id] = mapping;
276 : 3045 : }
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 : 132956 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
291 : : {
292 : 132956 : auto it = associated_type_mappings.find (id);
293 : 132956 : if (it == associated_type_mappings.end ())
294 : : return false;
295 : :
296 : 49484 : if (mapping != nullptr)
297 : 49484 : *mapping = it->second;
298 : :
299 : : return true;
300 : : }
301 : :
302 : : void
303 : 4642 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
304 : : TyTy::BaseType *impl_type,
305 : : HirId impl_id)
306 : : {
307 : 4642 : auto it = associated_traits_to_impls.find (trait_id);
308 : 4642 : if (it == associated_traits_to_impls.end ())
309 : : {
310 : 1768 : associated_traits_to_impls[trait_id] = {};
311 : : }
312 : :
313 : 4642 : associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
314 : 4642 : }
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 : 42604 : TypeCheckContext::insert_autoderef_mappings (
340 : : HirId id, std::vector<Adjustment> &&adjustments)
341 : : {
342 : 42604 : autoderef_mappings.emplace (id, std::move (adjustments));
343 : 42604 : }
344 : :
345 : : bool
346 : 46353 : TypeCheckContext::lookup_autoderef_mappings (
347 : : HirId id, std::vector<Adjustment> **adjustments)
348 : : {
349 : 46353 : auto it = autoderef_mappings.find (id);
350 : 46353 : if (it == autoderef_mappings.end ())
351 : : return false;
352 : :
353 : 33408 : *adjustments = &it->second;
354 : 33408 : return true;
355 : : }
356 : :
357 : : void
358 : 5150 : TypeCheckContext::insert_cast_autoderef_mappings (
359 : : HirId id, std::vector<Adjustment> &&adjustments)
360 : : {
361 : 5150 : cast_autoderef_mappings.emplace (id, std::move (adjustments));
362 : 5150 : }
363 : :
364 : : bool
365 : 4842 : TypeCheckContext::lookup_cast_autoderef_mappings (
366 : : HirId id, std::vector<Adjustment> **adjustments)
367 : : {
368 : 4842 : auto it = cast_autoderef_mappings.find (id);
369 : 4842 : if (it == cast_autoderef_mappings.end ())
370 : : return false;
371 : :
372 : 4842 : *adjustments = &it->second;
373 : 4842 : return true;
374 : : }
375 : :
376 : : void
377 : 4235 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
378 : : {
379 : 4235 : auto it = variants.find (id);
380 : 4235 : rust_assert (it == variants.end ());
381 : :
382 : 4235 : variants[id] = variant;
383 : 4235 : }
384 : :
385 : : bool
386 : 8296 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
387 : : {
388 : 8296 : auto it = variants.find (id);
389 : 8296 : if (it == variants.end ())
390 : : return false;
391 : :
392 : 8290 : *variant = it->second;
393 : 8290 : return true;
394 : : }
395 : :
396 : : void
397 : 1330 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
398 : : {
399 : 1330 : auto it = operator_overloads.find (id);
400 : 1330 : rust_assert (it == operator_overloads.end ());
401 : :
402 : 1330 : operator_overloads[id] = call_site;
403 : 1330 : }
404 : :
405 : : bool
406 : 20910 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
407 : : {
408 : 20910 : auto it = operator_overloads.find (id);
409 : 20910 : if (it == operator_overloads.end ())
410 : : return false;
411 : :
412 : 2352 : *call = it->second;
413 : 2352 : 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 : 4089 : TypeCheckContext::iterate_deferred_operator_overloads (
438 : : std::function<bool (HirId, DeferredOpOverload &)> cb)
439 : : {
440 : 4097 : for (auto it = deferred_operator_overloads.begin ();
441 : 4097 : it != deferred_operator_overloads.end (); it++)
442 : : {
443 : 8 : if (!cb (it->first, it->second))
444 : 4089 : return;
445 : : }
446 : : }
447 : :
448 : : void
449 : 5632 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
450 : : {
451 : 5632 : unconstrained[id] = status;
452 : 5632 : }
453 : :
454 : : bool
455 : 41254 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
456 : : {
457 : 41254 : auto it = unconstrained.find (id);
458 : 41254 : bool found = it != unconstrained.end ();
459 : 41254 : if (!found)
460 : : return false;
461 : :
462 : 35622 : *result = it->second;
463 : 35622 : return true;
464 : : }
465 : :
466 : : void
467 : 6733 : 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 : 6733 : predicates.insert ({id, predicate});
474 : 6733 : }
475 : :
476 : : bool
477 : 38114 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
478 : : {
479 : 38114 : auto it = predicates.find (id);
480 : 38114 : bool found = it != predicates.end ();
481 : 38114 : if (!found)
482 : : return false;
483 : :
484 : 31369 : *result = it->second;
485 : 31369 : return true;
486 : : }
487 : :
488 : : void
489 : 11171 : TypeCheckContext::insert_query (HirId id)
490 : : {
491 : 11171 : querys_in_progress.insert (id);
492 : 11171 : }
493 : :
494 : : void
495 : 11171 : TypeCheckContext::query_completed (HirId id)
496 : : {
497 : 11171 : querys_in_progress.erase (id);
498 : 11171 : }
499 : :
500 : : bool
501 : 16708 : TypeCheckContext::query_in_progress (HirId id) const
502 : : {
503 : 16708 : return querys_in_progress.find (id) != querys_in_progress.end ();
504 : : }
505 : :
506 : : void
507 : 3670 : TypeCheckContext::insert_trait_query (DefId id)
508 : : {
509 : 3670 : trait_queries_in_progress.insert (id);
510 : 3670 : }
511 : :
512 : : void
513 : 3670 : TypeCheckContext::trait_query_completed (DefId id)
514 : : {
515 : 3670 : trait_queries_in_progress.erase (id);
516 : 3670 : }
517 : :
518 : : bool
519 : 3674 : TypeCheckContext::trait_query_in_progress (DefId id) const
520 : : {
521 : 3674 : return trait_queries_in_progress.find (id)
522 : 3674 : != trait_queries_in_progress.end ();
523 : : }
524 : :
525 : : Lifetime
526 : 901 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
527 : : {
528 : 901 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
529 : : {
530 : 900 : auto maybe_interned = lookup_lifetime (lifetime);
531 : 900 : if (maybe_interned)
532 : 816 : return *maybe_interned;
533 : :
534 : 84 : auto interned = next_lifetime_index.next ();
535 : 84 : lifetime_name_interner[lifetime.get_name ()] = interned;
536 : 84 : 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 : 30315 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
551 : : {
552 : 30315 : if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
553 : : {
554 : 1173 : 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 : 1172 : const auto name = lifetime.get_name ();
565 : 1172 : auto it = lifetime_name_interner.find (name);
566 : 1172 : if (it == lifetime_name_interner.end ())
567 : 89 : return tl::nullopt;
568 : 1083 : return it->second;
569 : 1172 : }
570 : 29142 : if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
571 : : {
572 : 29053 : return Lifetime::anonymous_lifetime ();
573 : : }
574 : 89 : if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
575 : : {
576 : 89 : return Lifetime::static_lifetime ();
577 : : }
578 : 0 : rust_unreachable ();
579 : : }
580 : :
581 : : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
582 : 29415 : TypeCheckContext::lookup_and_resolve_lifetime (
583 : : const HIR::Lifetime &lifetime) const
584 : : {
585 : 29415 : auto maybe_interned = lookup_lifetime (lifetime);
586 : 29415 : if (!maybe_interned)
587 : 6 : return tl::nullopt;
588 : :
589 : 29409 : 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 : 9221 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
599 : : {
600 : 9221 : std::vector<TyTy::Region> regions;
601 : 9250 : for (const auto &lifetime : args.get_lifetime_args ())
602 : : {
603 : 30 : auto resolved = lookup_and_resolve_lifetime (lifetime);
604 : 30 : if (!resolved)
605 : : {
606 : 1 : rust_error_at (lifetime.get_locus (), "unresolved lifetime");
607 : 1 : return {};
608 : : }
609 : 29 : regions.push_back (*resolved);
610 : : }
611 : 9220 : return regions;
612 : 9221 : }
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 : 4089 : TypeCheckContext::compute_inference_variables (bool emit_error)
640 : : {
641 : 4089 : iterate_deferred_operator_overloads (
642 : 4089 : [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
643 : 8 : return compute_ambigious_op_overload (id, op);
644 : : });
645 : :
646 : 4089 : iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
647 : 524024 : return compute_infer_var (id, ty, emit_error);
648 : : });
649 : 4089 : }
650 : :
651 : : bool
652 : 524024 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
653 : : bool emit_error)
654 : : {
655 : 524024 : auto &mappings = Analysis::Mappings::get ();
656 : :
657 : : // nothing to do
658 : 524024 : if (ty->get_kind () != TyTy::TypeKind::INFER)
659 : : return true;
660 : :
661 : 1826 : TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
662 : 1826 : TyTy::BaseType *default_type;
663 : :
664 : 1826 : rust_debug_loc (mappings.lookup_location (id),
665 : : "trying to default infer-var: %s",
666 : 1826 : infer_var->as_string ().c_str ());
667 : 1826 : bool ok = infer_var->default_type (&default_type);
668 : 1826 : 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 : 1814 : auto result
677 : 1814 : = unify_site (id, TyTy::TyWithLocation (ty),
678 : 1814 : TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
679 : 1814 : rust_assert (result);
680 : 1814 : rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
681 : 1814 : result->set_ref (id);
682 : 1814 : insert_implicit_type (id, result);
683 : :
684 : 1814 : return true;
685 : : }
686 : :
687 : : TyTy::VarianceAnalysis::CrateCtx &
688 : 7902 : TypeCheckContext::get_variance_analysis_ctx ()
689 : : {
690 : 7902 : return variance_analysis_ctx;
691 : : }
692 : :
693 : : // TypeCheckContextItem
694 : :
695 : 9087 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
696 : :
697 : 6834 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
698 : : HIR::Function *item)
699 : 6834 : : impl_item ({impl_block, item})
700 : 6834 : {}
701 : :
702 : 855 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
703 : 855 : : trait_item (trait_item)
704 : 855 : {}
705 : :
706 : 6270 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
707 : 6270 : : type (ItemType::ITEM), item (item)
708 : 6270 : {}
709 : :
710 : 6834 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
711 : 6834 : HIR::Function *item)
712 : 6834 : : type (ItemType::IMPL_ITEM), item (&impl_block, item)
713 : 6834 : {}
714 : :
715 : 855 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
716 : 855 : : type (ItemType::TRAIT_ITEM), item (trait_item)
717 : 855 : {}
718 : :
719 : 18430 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
720 : 18430 : : type (other.type), item (other.item)
721 : : {
722 : 18430 : switch (other.type)
723 : : {
724 : : case ITEM:
725 : : item.item = other.item.item;
726 : : break;
727 : :
728 : 9783 : case IMPL_ITEM:
729 : 9783 : item.impl_item = other.item.impl_item;
730 : 9783 : 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 : 18430 : }
741 : :
742 : 2817 : TypeCheckContextItem::TypeCheckContextItem ()
743 : 2817 : : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
744 : 2817 : {}
745 : :
746 : : TypeCheckContextItem &
747 : 2809 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
748 : : {
749 : 2809 : type = other.type;
750 : 2809 : switch (other.type)
751 : : {
752 : 630 : case ITEM:
753 : 630 : item.item = other.item.item;
754 : 630 : break;
755 : :
756 : 2065 : case IMPL_ITEM:
757 : 2065 : item.impl_item = other.item.impl_item;
758 : 2065 : 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 : 2809 : return *this;
770 : : }
771 : :
772 : : TypeCheckContextItem
773 : 2817 : TypeCheckContextItem::get_error ()
774 : : {
775 : 2817 : return TypeCheckContextItem ();
776 : : }
777 : :
778 : : bool
779 : 0 : TypeCheckContextItem::is_error () const
780 : : {
781 : 0 : return type == ERROR;
782 : : }
783 : :
784 : : HIR::Function *
785 : 63 : TypeCheckContextItem::get_item ()
786 : : {
787 : 63 : rust_assert (get_type () == ItemType::ITEM);
788 : 63 : return item.item;
789 : : }
790 : :
791 : : std::pair<HIR::ImplBlock *, HIR::Function *> &
792 : 771 : TypeCheckContextItem::get_impl_item ()
793 : : {
794 : 771 : rust_assert (get_type () == ItemType::IMPL_ITEM);
795 : 771 : 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 : 5245 : TypeCheckContextItem::get_type () const
807 : : {
808 : 5245 : return type;
809 : : }
810 : :
811 : : TyTy::FnType *
812 : 64 : TypeCheckContextItem::get_context_type ()
813 : : {
814 : 64 : auto &context = *TypeCheckContext::get ();
815 : :
816 : 64 : HirId reference = UNKNOWN_HIRID;
817 : 64 : switch (get_type ())
818 : : {
819 : 63 : case ITEM:
820 : 63 : reference = get_item ()->get_mappings ().get_hirid ();
821 : 63 : 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 : 64 : rust_assert (reference != UNKNOWN_HIRID);
837 : :
838 : 64 : TyTy::BaseType *lookup = nullptr;
839 : 64 : bool ok = context.lookup_type (reference, &lookup);
840 : 64 : rust_assert (ok);
841 : 64 : rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
842 : 64 : return static_cast<TyTy::FnType *> (lookup);
843 : : }
844 : :
845 : : DefId
846 : 2853 : TypeCheckContextItem::get_defid () const
847 : : {
848 : 2853 : switch (get_type ())
849 : : {
850 : 744 : case ITEM:
851 : 744 : return item.item->get_mappings ().get_defid ();
852 : :
853 : 1987 : case IMPL_ITEM:
854 : 1987 : 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 : 8070 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
869 : :
870 : 3662 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
871 : :
872 : 8070 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
873 : 8070 : : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
874 : 8070 : {}
875 : :
876 : 3662 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
877 : 3662 : : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
878 : 3662 : {}
879 : :
880 : : bool
881 : 0 : TypeCheckBlockContextItem::is_impl_block () const
882 : : {
883 : 0 : return type == IMPL_BLOCK;
884 : : }
885 : :
886 : : bool
887 : 843 : TypeCheckBlockContextItem::is_trait_block () const
888 : : {
889 : 843 : 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 : 696 : TypeCheckBlockContextItem::get_trait ()
900 : : {
901 : 696 : return *(item.trait);
902 : : }
903 : :
904 : : } // namespace Resolver
905 : : } // namespace Rust
|