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-tyty-subst.h"
20 : :
21 : : #include "rust-hir-generic-param.h"
22 : : #include "rust-system.h"
23 : : #include "rust-tyty.h"
24 : : #include "rust-hir-type-check.h"
25 : : #include "rust-substitution-mapper.h"
26 : : #include "rust-hir-type-check-type.h"
27 : : #include "rust-hir-type-check-expr.h"
28 : : #include "rust-compile-base.h"
29 : : #include "rust-type-util.h"
30 : : #include "tree.h"
31 : :
32 : : namespace Rust {
33 : : namespace TyTy {
34 : :
35 : 76811036 : SubstitutionParamMapping::SubstitutionParamMapping (HIR::GenericParam &generic,
36 : 76811036 : BaseGeneric *param)
37 : 76811036 : : generic (generic), param (param)
38 : 76811036 : {}
39 : :
40 : 86144834 : SubstitutionParamMapping::SubstitutionParamMapping (
41 : 86144834 : const SubstitutionParamMapping &other)
42 : 86144834 : : generic (other.generic), param (other.param)
43 : 86144834 : {}
44 : :
45 : : std::string
46 : 171805 : SubstitutionParamMapping::as_string () const
47 : : {
48 : 171805 : if (param == nullptr)
49 : 0 : return "nullptr";
50 : :
51 : 171805 : return param->get_name ();
52 : : }
53 : :
54 : : SubstitutionParamMapping
55 : 76797766 : SubstitutionParamMapping::clone () const
56 : : {
57 : 76797766 : return SubstitutionParamMapping (generic,
58 : 76797766 : static_cast<ParamType *> (param->clone ()));
59 : : }
60 : :
61 : : BaseGeneric *
62 : 187593 : SubstitutionParamMapping::get_param_ty ()
63 : : {
64 : 187593 : return param;
65 : : }
66 : :
67 : : const BaseGeneric *
68 : 69387135 : SubstitutionParamMapping::get_param_ty () const
69 : : {
70 : 69387135 : return param;
71 : : }
72 : :
73 : : HIR::GenericParam &
74 : 16646 : SubstitutionParamMapping::get_generic_param ()
75 : : {
76 : 16646 : return generic;
77 : : }
78 : :
79 : : const HIR::GenericParam &
80 : 9754 : SubstitutionParamMapping::get_generic_param () const
81 : : {
82 : 9754 : return generic;
83 : : }
84 : :
85 : : bool
86 : 62008 : SubstitutionParamMapping::needs_substitution () const
87 : : {
88 : 62008 : return !(get_param_ty ()->is_concrete ());
89 : : }
90 : :
91 : : Identifier
92 : 2296 : SubstitutionParamMapping::get_type_representation () const
93 : : {
94 : 4592 : return param->get_symbol ();
95 : : }
96 : :
97 : : location_t
98 : 1908 : SubstitutionParamMapping::get_param_locus () const
99 : : {
100 : 1908 : return generic.get_locus ();
101 : : }
102 : :
103 : : bool
104 : 23347 : SubstitutionParamMapping::param_has_default_ty () const
105 : : {
106 : 23347 : if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
107 : : {
108 : 23205 : const auto &type_param = static_cast<const HIR::TypeParam &> (generic);
109 : 23205 : return type_param.has_type ();
110 : : }
111 : :
112 : 142 : rust_assert (generic.get_kind () == HIR::GenericParam::GenericKind::CONST);
113 : 142 : const auto &const_param
114 : : = static_cast<const HIR::ConstGenericParam &> (generic);
115 : 142 : return const_param.has_default_expression ();
116 : : }
117 : :
118 : : BaseType *
119 : 1129 : SubstitutionParamMapping::get_default_ty () const
120 : : {
121 : 1129 : if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
122 : : {
123 : 1124 : const auto &type_param = static_cast<const HIR::TypeParam &> (generic);
124 : 1124 : TyVar var (type_param.get_type_mappings ().get_hirid ());
125 : 1124 : return var.get_tyty ();
126 : : }
127 : :
128 : 5 : rust_assert (generic.get_kind () == HIR::GenericParam::GenericKind::CONST);
129 : 5 : const auto &const_param
130 : : = static_cast<const HIR::ConstGenericParam &> (generic);
131 : 5 : rust_assert (const_param.has_default_expression ());
132 : :
133 : 5 : const auto &expr = const_param.get_default_expression ();
134 : 5 : TyVar var (expr.get_mappings ().get_hirid ());
135 : 5 : return var.get_tyty ();
136 : : }
137 : :
138 : : bool
139 : 0 : SubstitutionParamMapping::need_substitution () const
140 : : {
141 : 0 : if (!param->can_resolve ())
142 : : return true;
143 : :
144 : 0 : auto resolved = param->resolve ();
145 : 0 : return !resolved->is_concrete ();
146 : : }
147 : :
148 : : bool
149 : 35735 : SubstitutionParamMapping::fill_param_ty (
150 : : SubstitutionArgumentMappings &subst_mappings, location_t locus,
151 : : bool needs_bounds_check)
152 : : {
153 : 35735 : SubstitutionArg arg = SubstitutionArg::error ();
154 : 35735 : bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
155 : 35735 : if (!ok)
156 : : return true;
157 : :
158 : 35735 : TyTy::BaseType &type = *arg.get_tyty ();
159 : 35735 : if (type.get_kind () == TyTy::TypeKind::INFER)
160 : : {
161 : 10649 : type.inherit_bounds (*param);
162 : : }
163 : :
164 : 35735 : if (type.get_kind () == TypeKind::PARAM)
165 : : {
166 : 7253 : param = static_cast<BaseGeneric *> (type.clone ());
167 : : }
168 : 28482 : else if (type.get_kind () == TyTy::TypeKind::CONST)
169 : : {
170 : 80 : param = static_cast<BaseGeneric *> (type.clone ());
171 : : }
172 : 28402 : else if (param->get_kind () == TypeKind::PARAM)
173 : : {
174 : 28402 : auto &p = *static_cast<TyTy::ParamType *> (param);
175 : :
176 : : // check the substitution is compatible with bounds
177 : 28402 : rust_debug_loc (locus,
178 : : "fill_param_ty bounds_compatible: param %s type %s",
179 : 56804 : param->get_name ().c_str (), type.get_name ().c_str ());
180 : 28402 : if (needs_bounds_check && !p.is_implicit_self_trait ())
181 : : {
182 : 13416 : if (!param->bounds_compatible (type, locus, true))
183 : : return false;
184 : : }
185 : :
186 : : // recursively pass this down to all HRTB's
187 : 63663 : for (auto &bound : param->get_specified_bounds ())
188 : 35267 : bound.handle_substitions (subst_mappings);
189 : :
190 : 28396 : param->set_ty_ref (type.get_ref ());
191 : 28396 : subst_mappings.on_param_subst (p, arg);
192 : : }
193 : :
194 : : return true;
195 : : }
196 : :
197 : : void
198 : 4435 : SubstitutionParamMapping::override_context ()
199 : : {
200 : 4435 : if (!param->can_resolve ())
201 : : return;
202 : :
203 : 4421 : auto &mappings = Analysis::Mappings::get ();
204 : 4421 : auto context = Resolver::TypeCheckContext::get ();
205 : :
206 : 4421 : context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
207 : : UNKNOWN_NODEID,
208 : 4421 : param->get_ref (),
209 : 4421 : UNKNOWN_LOCAL_DEFID),
210 : 4421 : param->resolve ());
211 : : }
212 : :
213 : 69449347 : SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
214 : 69449347 : BaseType *argument)
215 : 69449347 : : param (param), argument (argument)
216 : : {
217 : 69449347 : if (param != nullptr)
218 : 69288038 : original_param = param->get_param_ty ();
219 : 69449347 : }
220 : :
221 : 280491708 : SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
222 : 280491708 : : param (other.param), original_param (other.original_param),
223 : 280491708 : argument (other.argument)
224 : 280491708 : {}
225 : :
226 : : SubstitutionArg &
227 : 155362 : SubstitutionArg::operator= (const SubstitutionArg &other)
228 : : {
229 : 155362 : param = other.param;
230 : 155362 : argument = other.argument;
231 : 155362 : original_param = other.original_param;
232 : :
233 : 155362 : return *this;
234 : : }
235 : :
236 : : BaseType *
237 : 71894096 : SubstitutionArg::get_tyty () const
238 : : {
239 : 71894096 : return argument;
240 : : }
241 : :
242 : : const SubstitutionParamMapping *
243 : 8312 : SubstitutionArg::get_param_mapping () const
244 : : {
245 : 8312 : return param;
246 : : }
247 : :
248 : : const BaseGeneric *
249 : 174597 : SubstitutionArg::get_param_ty () const
250 : : {
251 : 174597 : return original_param;
252 : : }
253 : :
254 : : SubstitutionArg
255 : 161309 : SubstitutionArg::error ()
256 : : {
257 : 161309 : return SubstitutionArg (nullptr, nullptr);
258 : : }
259 : :
260 : : bool
261 : 62004 : SubstitutionArg::is_error () const
262 : : {
263 : 62004 : return param == nullptr || argument == nullptr;
264 : : }
265 : :
266 : : bool
267 : 0 : SubstitutionArg::is_conrete () const
268 : : {
269 : 0 : if (argument == nullptr)
270 : : return false;
271 : :
272 : 0 : if (argument->get_kind () == TyTy::TypeKind::PARAM)
273 : : return false;
274 : :
275 : 0 : return argument->is_concrete ();
276 : : }
277 : :
278 : : std::string
279 : 0 : SubstitutionArg::as_string () const
280 : : {
281 : 0 : return original_param->as_string ()
282 : 0 : + (argument != nullptr ? ":" + argument->as_string () : "");
283 : : }
284 : :
285 : : const RegionParamList &
286 : 67637464 : SubstitutionArgumentMappings::get_regions () const
287 : : {
288 : 67637464 : return regions;
289 : : }
290 : :
291 : : RegionParamList &
292 : 2039 : SubstitutionArgumentMappings::get_mut_regions ()
293 : : {
294 : 2039 : return regions;
295 : : }
296 : :
297 : : // SubstitutionArgumentMappings
298 : :
299 : 135460127 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
300 : : std::vector<SubstitutionArg> mappings,
301 : : std::map<std::string, BaseType *> binding_args, RegionParamList regions,
302 : : location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
303 : 135460127 : bool error_flag)
304 : 135460127 : : mappings (std::move (mappings)), binding_args (binding_args),
305 : 135460127 : regions (regions), locus (locus), param_subst_cb (param_subst_cb),
306 : 135460127 : trait_item_flag (trait_item_flag), error_flag (error_flag)
307 : 135460127 : {}
308 : :
309 : 68229178 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
310 : 68229178 : const SubstitutionArgumentMappings &other)
311 : 68229178 : : mappings (other.mappings), binding_args (other.binding_args),
312 : 68229178 : regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
313 : 68229178 : trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
314 : 68229178 : {}
315 : :
316 : : SubstitutionArgumentMappings &
317 : 38784 : SubstitutionArgumentMappings::operator= (
318 : : const SubstitutionArgumentMappings &other)
319 : : {
320 : 38784 : mappings = other.mappings;
321 : 38784 : binding_args = other.binding_args;
322 : 38784 : regions = other.regions;
323 : 38784 : locus = other.locus;
324 : 38784 : param_subst_cb = nullptr;
325 : 38784 : trait_item_flag = other.trait_item_flag;
326 : 38784 : error_flag = other.error_flag;
327 : :
328 : 38784 : return *this;
329 : : }
330 : :
331 : : SubstitutionArgumentMappings
332 : 46504 : SubstitutionArgumentMappings::error ()
333 : : {
334 : 93008 : return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
335 : 46504 : false, true);
336 : : }
337 : :
338 : : SubstitutionArgumentMappings
339 : 67783490 : SubstitutionArgumentMappings::empty (size_t num_regions)
340 : : {
341 : 135566980 : return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
342 : 67783490 : nullptr, false, false);
343 : : }
344 : :
345 : : bool
346 : 31362 : SubstitutionArgumentMappings::is_error () const
347 : : {
348 : 31362 : return error_flag;
349 : : }
350 : :
351 : : bool
352 : 146749 : SubstitutionArgumentMappings::get_argument_for_symbol (
353 : : const BaseGeneric *param_to_find, SubstitutionArg *argument) const
354 : : {
355 : 188277 : for (const auto &mapping : mappings)
356 : : {
357 : 174597 : const auto *p = mapping.get_param_ty ();
358 : 174597 : if (p->get_symbol () == param_to_find->get_symbol ())
359 : : {
360 : 133069 : *argument = mapping;
361 : 133069 : return true;
362 : : }
363 : : }
364 : : return false;
365 : : }
366 : : tl::optional<size_t>
367 : 0 : SubstitutionArgumentMappings::find_symbol (const ParamType ¶m_to_find) const
368 : : {
369 : 0 : auto it = std::find_if (mappings.begin (), mappings.end (),
370 : 0 : [param_to_find] (const SubstitutionArg &arg) {
371 : 0 : return arg.get_param_ty ()->get_symbol ()
372 : 0 : == param_to_find.get_symbol ();
373 : : });
374 : 0 : if (it == mappings.end ())
375 : 0 : return tl::nullopt;
376 : 0 : return std::distance (mappings.begin (), it);
377 : : }
378 : :
379 : : bool
380 : 14560 : SubstitutionArgumentMappings::get_argument_at (size_t index,
381 : : SubstitutionArg *argument)
382 : : {
383 : 14560 : if (index > mappings.size ())
384 : : return false;
385 : :
386 : 14560 : *argument = mappings.at (index);
387 : 14560 : return true;
388 : : }
389 : :
390 : : bool
391 : 0 : SubstitutionArgumentMappings::is_concrete () const
392 : : {
393 : 0 : for (auto &mapping : mappings)
394 : : {
395 : 0 : if (!mapping.is_conrete ())
396 : 0 : return false;
397 : : }
398 : : return true;
399 : : }
400 : :
401 : : location_t
402 : 67643767 : SubstitutionArgumentMappings::get_locus () const
403 : : {
404 : 67643767 : return locus;
405 : : }
406 : :
407 : : size_t
408 : 42571 : SubstitutionArgumentMappings::size () const
409 : : {
410 : 42571 : return mappings.size ();
411 : : }
412 : :
413 : : bool
414 : 16587 : SubstitutionArgumentMappings::is_empty () const
415 : : {
416 : 16587 : return size () == 0;
417 : : }
418 : :
419 : : std::vector<SubstitutionArg> &
420 : 55385 : SubstitutionArgumentMappings::get_mappings ()
421 : : {
422 : 55385 : return mappings;
423 : : }
424 : :
425 : : const std::vector<SubstitutionArg> &
426 : 273628456 : SubstitutionArgumentMappings::get_mappings () const
427 : : {
428 : 273628456 : return mappings;
429 : : }
430 : :
431 : : std::map<std::string, BaseType *> &
432 : 58329 : SubstitutionArgumentMappings::get_binding_args ()
433 : : {
434 : 58329 : return binding_args;
435 : : }
436 : :
437 : : const std::map<std::string, BaseType *> &
438 : 0 : SubstitutionArgumentMappings::get_binding_args () const
439 : : {
440 : 0 : return binding_args;
441 : : }
442 : :
443 : : std::string
444 : 0 : SubstitutionArgumentMappings::as_string () const
445 : : {
446 : 0 : std::string buffer;
447 : 0 : for (auto &mapping : mappings)
448 : : {
449 : 0 : buffer += mapping.as_string () + ", ";
450 : : }
451 : 0 : return "<" + buffer + ">";
452 : 0 : }
453 : :
454 : : void
455 : 73279 : SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
456 : : const SubstitutionArg &a) const
457 : : {
458 : 73279 : if (param_subst_cb == nullptr)
459 : : return;
460 : :
461 : 575 : param_subst_cb (p, a);
462 : : }
463 : :
464 : : ParamSubstCb
465 : 18443 : SubstitutionArgumentMappings::get_subst_cb () const
466 : : {
467 : 18443 : return param_subst_cb;
468 : : }
469 : :
470 : : bool
471 : 13084 : SubstitutionArgumentMappings::trait_item_mode () const
472 : : {
473 : 13084 : return trait_item_flag;
474 : : }
475 : :
476 : : // SubstitutionRef
477 : :
478 : 67889046 : SubstitutionRef::SubstitutionRef (
479 : : std::vector<SubstitutionParamMapping> substitutions,
480 : 67889046 : SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
481 : 67889046 : : substitutions (substitutions), used_arguments (arguments),
482 : 135778092 : region_constraints (region_constraints)
483 : 67889046 : {}
484 : :
485 : : bool
486 : 170528 : SubstitutionRef::has_substitutions () const
487 : : {
488 : 170528 : return substitutions.size () > 0;
489 : : }
490 : :
491 : : std::string
492 : 477897 : SubstitutionRef::subst_as_string () const
493 : : {
494 : 477897 : std::string buffer;
495 : 649702 : for (size_t i = 0; i < substitutions.size (); i++)
496 : : {
497 : 171805 : const SubstitutionParamMapping &sub = substitutions.at (i);
498 : 343610 : buffer += sub.as_string ();
499 : :
500 : 171805 : if ((i + 1) < substitutions.size ())
501 : 21435 : buffer += ", ";
502 : : }
503 : :
504 : 628267 : return buffer.empty () ? "" : "<" + buffer + ">";
505 : 477897 : }
506 : :
507 : : bool
508 : 73 : SubstitutionRef::supports_associated_bindings () const
509 : : {
510 : 73 : return get_num_associated_bindings () > 0;
511 : : }
512 : :
513 : : size_t
514 : 1 : SubstitutionRef::get_num_associated_bindings () const
515 : : {
516 : 1 : return 0;
517 : : }
518 : :
519 : : TypeBoundPredicateItem
520 : 0 : SubstitutionRef::lookup_associated_type (const std::string &search)
521 : : {
522 : 0 : return TypeBoundPredicateItem::error ();
523 : : }
524 : :
525 : : size_t
526 : 62152 : SubstitutionRef::get_num_substitutions () const
527 : : {
528 : 62152 : return substitutions.size ();
529 : : }
530 : : size_t
531 : 135 : SubstitutionRef::get_num_lifetime_params () const
532 : : {
533 : 135 : return used_arguments.get_regions ().size ();
534 : : }
535 : : size_t
536 : 538 : SubstitutionRef::get_num_type_params () const
537 : : {
538 : 538 : return get_num_substitutions ();
539 : : }
540 : :
541 : : std::vector<SubstitutionParamMapping> &
542 : 123107 : SubstitutionRef::get_substs ()
543 : : {
544 : 123107 : return substitutions;
545 : : }
546 : :
547 : : const std::vector<SubstitutionParamMapping> &
548 : 67617251 : SubstitutionRef::get_substs () const
549 : : {
550 : 67617251 : return substitutions;
551 : : }
552 : :
553 : : std::vector<SubstitutionParamMapping>
554 : 194157 : SubstitutionRef::clone_substs () const
555 : : {
556 : 194157 : std::vector<SubstitutionParamMapping> clone;
557 : :
558 : 273477 : for (auto &sub : substitutions)
559 : 79320 : clone.push_back (sub.clone ());
560 : :
561 : 194157 : return clone;
562 : : }
563 : :
564 : : void
565 : 3912 : SubstitutionRef::override_context ()
566 : : {
567 : 8347 : for (auto &sub : substitutions)
568 : : {
569 : 4435 : sub.override_context ();
570 : : }
571 : 3912 : }
572 : :
573 : : bool
574 : 47594 : SubstitutionRef::needs_substitution () const
575 : : {
576 : 47594 : return std::any_of (substitutions.begin (), substitutions.end (),
577 : : std::mem_fn (
578 : 47594 : &SubstitutionParamMapping::needs_substitution));
579 : : }
580 : :
581 : : bool
582 : 63 : SubstitutionRef::was_substituted () const
583 : : {
584 : 63 : return !needs_substitution ();
585 : : }
586 : :
587 : : SubstitutionArgumentMappings &
588 : 55120 : SubstitutionRef::get_substitution_arguments ()
589 : : {
590 : 55120 : return used_arguments;
591 : : }
592 : :
593 : : const SubstitutionArgumentMappings &
594 : 26880 : SubstitutionRef::get_substitution_arguments () const
595 : : {
596 : 26880 : return used_arguments;
597 : : }
598 : :
599 : : size_t
600 : 9104 : SubstitutionRef::num_required_substitutions () const
601 : : {
602 : 9104 : size_t n = 0;
603 : 20533 : for (auto &p : substitutions)
604 : : {
605 : 11429 : if (p.needs_substitution ())
606 : 11102 : n++;
607 : : }
608 : 9104 : return n;
609 : : }
610 : :
611 : : size_t
612 : 18218 : SubstitutionRef::min_required_substitutions () const
613 : : {
614 : 18218 : size_t n = 0;
615 : 41090 : for (auto &p : substitutions)
616 : : {
617 : 22872 : if (p.needs_substitution () && !p.param_has_default_ty ())
618 : 19087 : n++;
619 : : }
620 : 18218 : return n;
621 : : }
622 : :
623 : : const SubstitutionArgumentMappings &
624 : 13772 : SubstitutionRef::get_used_arguments () const
625 : : {
626 : 13772 : return used_arguments;
627 : : }
628 : :
629 : : tl::optional<SubstitutionArg>
630 : 166 : SubstitutionRef::get_arg_at (size_t i) const
631 : : {
632 : 166 : auto param_ty = get_substs ().at (i).get_param_ty ();
633 : 166 : SubstitutionArg arg = SubstitutionArg::error ();
634 : 166 : get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
635 : 166 : if (arg.is_error ())
636 : 8 : return tl::nullopt;
637 : 158 : return arg;
638 : : }
639 : :
640 : : const RegionConstraints &
641 : 192706 : SubstitutionRef::get_region_constraints () const
642 : : {
643 : 192706 : return region_constraints;
644 : : }
645 : :
646 : : SubstitutionArgumentMappings
647 : 9115 : SubstitutionRef::get_mappings_from_generic_args (
648 : : HIR::GenericArgs &args, const std::vector<Region> ®ions)
649 : : {
650 : 9115 : std::map<std::string, BaseType *> binding_arguments;
651 : 9115 : if (args.get_binding_args ().size () > 0)
652 : : {
653 : 73 : if (supports_associated_bindings ())
654 : : {
655 : 72 : if (args.get_binding_args ().size () > get_num_associated_bindings ())
656 : : {
657 : 0 : rich_location r (line_table, args.get_locus ());
658 : 0 : rust_error_at (r,
659 : : "generic item takes at most %lu type binding "
660 : : "arguments but %lu were supplied",
661 : 0 : (unsigned long) get_num_associated_bindings (),
662 : 0 : (unsigned long) args.get_binding_args ().size ());
663 : 0 : return SubstitutionArgumentMappings::error ();
664 : 0 : }
665 : :
666 : 144 : for (auto &binding : args.get_binding_args ())
667 : : {
668 : 72 : BaseType *resolved
669 : 72 : = Resolver::TypeCheckType::Resolve (binding.get_type ());
670 : 72 : if (resolved == nullptr
671 : 72 : || resolved->get_kind () == TyTy::TypeKind::ERROR)
672 : : {
673 : 0 : return SubstitutionArgumentMappings::error ();
674 : : }
675 : :
676 : : // resolve to relevant binding
677 : 72 : auto binding_item = lookup_associated_type (
678 : 72 : binding.get_identifier ().as_string ());
679 : 72 : if (binding_item.is_error ())
680 : : {
681 : 0 : rust_error_at (
682 : : binding.get_locus (), "unknown associated type binding: %s",
683 : 0 : binding.get_identifier ().as_string ().c_str ());
684 : 0 : return SubstitutionArgumentMappings::error ();
685 : : }
686 : :
687 : 72 : binding_arguments[binding.get_identifier ().as_string ()]
688 : 72 : = resolved;
689 : 72 : }
690 : : }
691 : : else
692 : : {
693 : 1 : rich_location r (line_table, args.get_locus ());
694 : 3 : for (auto &binding : args.get_binding_args ())
695 : 2 : r.add_range (binding.get_locus ());
696 : :
697 : 1 : rust_error_at (r, ErrorCode::E0229,
698 : : "associated type bindings are not allowed here");
699 : 1 : return SubstitutionArgumentMappings::error ();
700 : 1 : }
701 : : }
702 : :
703 : : // for inherited arguments
704 : 9114 : size_t offs = used_arguments.size ();
705 : 9114 : size_t total_arguments
706 : 9114 : = args.get_type_args ().size () + args.get_const_args ().size () + offs;
707 : 9114 : if (total_arguments > substitutions.size ())
708 : : {
709 : 3 : rich_location r (line_table, args.get_locus ());
710 : 3 : if (!substitutions.empty ())
711 : : {
712 : 2 : const auto &subst = substitutions.front ();
713 : 2 : const auto &generic = subst.get_generic_param ();
714 : 2 : r.add_range (generic.get_locus ());
715 : : }
716 : :
717 : 6 : rust_error_at (
718 : : r,
719 : : "generic item takes at most %lu type arguments but %lu were supplied",
720 : 3 : (unsigned long) substitutions.size (),
721 : 3 : (unsigned long) args.get_type_args ().size ());
722 : 3 : return SubstitutionArgumentMappings::error ();
723 : 3 : }
724 : :
725 : 9111 : if (total_arguments < min_required_substitutions ())
726 : : {
727 : 3 : rich_location r (line_table, args.get_locus ());
728 : 3 : if (!substitutions.empty ())
729 : : {
730 : 3 : const auto &subst = substitutions.front ();
731 : 3 : const auto &generic = subst.get_generic_param ();
732 : 3 : r.add_range (generic.get_locus ());
733 : : }
734 : :
735 : 6 : rust_error_at (
736 : : r, ErrorCode::E0107,
737 : : "generic item takes at least %lu type arguments but %lu were supplied",
738 : 3 : (unsigned long) (min_required_substitutions () - offs),
739 : 3 : (unsigned long) args.get_type_args ().size ());
740 : 3 : return SubstitutionArgumentMappings::error ();
741 : 3 : }
742 : :
743 : 9108 : std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
744 : 18791 : for (auto &arg : args.get_type_args ())
745 : : {
746 : 9687 : BaseType *resolved = Resolver::TypeCheckType::Resolve (*arg);
747 : 9687 : if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
748 : : {
749 : 4 : return SubstitutionArgumentMappings::error ();
750 : : }
751 : :
752 : 9687 : const auto ¶m_mapping = substitutions.at (offs);
753 : 9687 : const auto &generic = param_mapping.get_generic_param ();
754 : 9687 : if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
755 : : {
756 : 9684 : const auto &type_param
757 : : = static_cast<const HIR::TypeParam &> (generic);
758 : 9684 : if (type_param.from_impl_trait ())
759 : : {
760 : 1 : rich_location r (line_table, arg->get_locus ());
761 : 1 : r.add_fixit_remove (arg->get_locus ());
762 : 1 : rust_error_at (r, ErrorCode::E0632,
763 : : "cannot provide explicit generic arguments when "
764 : : "%<impl Trait%> is used in argument position");
765 : 1 : return SubstitutionArgumentMappings::error ();
766 : 1 : }
767 : : }
768 : 3 : else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
769 : : {
770 : 3 : if (!resolved->is<ConstType> ())
771 : : {
772 : 3 : rich_location r (line_table, arg->get_locus ());
773 : 3 : r.add_fixit_remove (arg->get_locus ());
774 : 3 : rust_error_at (r, ErrorCode::E0747,
775 : : "type provided when a constant was expected");
776 : 3 : return SubstitutionArgumentMappings::error ();
777 : 3 : }
778 : : }
779 : :
780 : 9683 : SubstitutionArg subst_arg (¶m_mapping, resolved);
781 : 9683 : offs++;
782 : 9683 : mappings.push_back (std::move (subst_arg));
783 : : }
784 : :
785 : 9166 : for (auto &arg : args.get_const_args ())
786 : : {
787 : 62 : auto &expr = *arg.get_expression ().get ();
788 : 62 : BaseType *expr_type = Resolver::TypeCheckExpr::Resolve (expr);
789 : 124 : if (expr_type == nullptr || expr_type->is<ErrorType> ())
790 : 0 : return SubstitutionArgumentMappings::error ();
791 : :
792 : : // validate this param is really a const generic
793 : 62 : const auto ¶m_mapping = substitutions.at (offs);
794 : 62 : const auto &generic = param_mapping.get_generic_param ();
795 : 62 : if (generic.get_kind () != HIR::GenericParam::GenericKind::CONST)
796 : : {
797 : 0 : rich_location r (line_table, arg.get_locus ());
798 : 0 : r.add_fixit_remove (expr.get_locus ());
799 : 0 : rust_error_at (r, "invalid position for a const generic argument");
800 : 0 : return SubstitutionArgumentMappings::error ();
801 : 0 : }
802 : :
803 : : // get the const generic specified type
804 : 62 : const auto base_generic = param_mapping.get_param_ty ();
805 : 62 : rust_assert (base_generic->is<ConstType> ());
806 : 62 : const auto const_param
807 : : = static_cast<const TyTy::ConstType *> (base_generic);
808 : 62 : auto specified_type = const_param->get_ty ();
809 : :
810 : : // validate this const generic is of the correct type
811 : 62 : auto coereced_type
812 : 62 : = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
813 : 62 : TyTy::TyWithLocation (specified_type),
814 : : TyTy::TyWithLocation (expr_type,
815 : 62 : expr.get_locus ()),
816 : : arg.get_locus ());
817 : 62 : if (coereced_type->is<ErrorType> ())
818 : 0 : return SubstitutionArgumentMappings::error ();
819 : :
820 : : // const fold it
821 : 62 : auto ctx = Compile::Context::get ();
822 : 62 : tree folded
823 : 62 : = Compile::HIRCompileBase::query_compile_const_expr (ctx, coereced_type,
824 : : expr);
825 : :
826 : 62 : if (folded == error_mark_node)
827 : 0 : return SubstitutionArgumentMappings::error ();
828 : :
829 : : // create const type
830 : 62 : auto const_value
831 : 62 : = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
832 : 62 : coereced_type, folded, {}, expr.get_locus (),
833 : 62 : expr.get_mappings ().get_hirid (),
834 : 62 : expr.get_mappings ().get_hirid (), {});
835 : :
836 : 62 : SubstitutionArg subst_arg (¶m_mapping, const_value);
837 : 62 : offs++;
838 : 62 : mappings.push_back (std::move (subst_arg));
839 : : }
840 : :
841 : : // we must need to fill out defaults
842 : 9104 : size_t left_over
843 : 9104 : = num_required_substitutions () - min_required_substitutions ();
844 : 9104 : if (left_over > 0)
845 : : {
846 : 2694 : for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
847 : : {
848 : 1129 : SubstitutionParamMapping ¶m = substitutions.at (offs);
849 : 1129 : rust_assert (param.param_has_default_ty ());
850 : :
851 : 1129 : BaseType *resolved = param.get_default_ty ();
852 : 1129 : if (resolved->get_kind () == TypeKind::ERROR)
853 : 0 : return SubstitutionArgumentMappings::error ();
854 : :
855 : : // this resolved default might already contain default parameters
856 : 1129 : if (!resolved->is_concrete ())
857 : : {
858 : 1110 : SubstitutionArgumentMappings intermediate (
859 : : mappings, binding_arguments,
860 : 1110 : {used_arguments.get_regions ().size ()}, args.get_locus ());
861 : 1110 : resolved = Resolver::SubstMapperInternal::Resolve (resolved,
862 : : intermediate);
863 : :
864 : 1110 : if (resolved->get_kind () == TypeKind::ERROR)
865 : 0 : return SubstitutionArgumentMappings::error ();
866 : 1110 : }
867 : :
868 : 1129 : SubstitutionArg subst_arg (¶m, resolved);
869 : 1129 : mappings.push_back (std::move (subst_arg));
870 : : }
871 : : }
872 : :
873 : 9104 : return {mappings, binding_arguments,
874 : 18208 : RegionParamList::from_subst (used_arguments.get_regions ().size (),
875 : : regions),
876 : 27312 : args.get_locus ()};
877 : 9108 : }
878 : :
879 : : BaseType *
880 : 6518 : SubstitutionRef::infer_substitions (location_t locus)
881 : : {
882 : 6518 : std::vector<SubstitutionArg> args;
883 : 6518 : std::map<std::string, BaseType *> argument_mappings;
884 : 14497 : for (auto &p : get_substs ())
885 : : {
886 : 7979 : if (p.needs_substitution ())
887 : : {
888 : 7910 : const HIR::GenericParam &generic = p.get_generic_param ();
889 : 7910 : const std::string &symbol = p.get_param_ty ()->get_symbol ();
890 : 7910 : auto it = argument_mappings.find (symbol);
891 : 7910 : bool have_mapping = it != argument_mappings.end ();
892 : :
893 : 7910 : if (have_mapping)
894 : : {
895 : 121 : args.push_back (SubstitutionArg (&p, it->second));
896 : : }
897 : 7789 : else if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
898 : : {
899 : 7777 : TyVar infer_var = TyVar::get_implicit_infer_var (locus);
900 : 7777 : args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
901 : 7777 : argument_mappings[symbol] = infer_var.get_tyty ();
902 : : }
903 : 12 : else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
904 : : {
905 : 12 : const auto const_param = p.get_param_ty ();
906 : 12 : rust_assert (const_param->is<TyTy::ConstType> ());
907 : 12 : const auto &const_type
908 : : = *static_cast<const TyTy::ConstType *> (const_param);
909 : :
910 : 12 : TyVar infer_var
911 : 12 : = TyVar::get_implicit_const_infer_var (const_type, locus);
912 : 12 : args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
913 : 12 : argument_mappings[symbol] = infer_var.get_tyty ();
914 : : }
915 : 7910 : }
916 : : else
917 : : {
918 : 69 : args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
919 : : }
920 : : }
921 : :
922 : : // FIXME do we need to add inference variables to all the possible bindings?
923 : : // it might just lead to inference variable hell not 100% sure if rustc does
924 : : // this i think the language might needs this to be explicitly set
925 : :
926 : 6518 : SubstitutionArgumentMappings infer_arguments (std::move (args),
927 : : {} /* binding_arguments */,
928 : : used_arguments.get_regions (),
929 : 6518 : locus);
930 : 6518 : return handle_substitions (infer_arguments);
931 : 6518 : }
932 : :
933 : : SubstitutionArgumentMappings
934 : 12595 : SubstitutionRef::adjust_mappings_for_this (
935 : : SubstitutionArgumentMappings &mappings, bool trait_mode)
936 : : {
937 : 12595 : std::vector<SubstitutionArg> resolved_mappings;
938 : 29402 : for (size_t i = 0; i < substitutions.size (); i++)
939 : : {
940 : 16807 : auto &subst = substitutions.at (i);
941 : :
942 : 16807 : SubstitutionArg arg = SubstitutionArg::error ();
943 : 16807 : if (mappings.size () == substitutions.size ())
944 : : {
945 : 14560 : mappings.get_argument_at (i, &arg);
946 : : }
947 : : else
948 : : {
949 : 2247 : if (subst.needs_substitution ())
950 : : {
951 : : // get from passed in mappings
952 : 2159 : mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
953 : : }
954 : : else
955 : : {
956 : : // we should already have this somewhere
957 : 88 : used_arguments.get_argument_for_symbol (subst.get_param_ty (),
958 : : &arg);
959 : : }
960 : : }
961 : :
962 : 16807 : bool ok = !arg.is_error ();
963 : 16807 : if (ok || (trait_mode && i == 0))
964 : : {
965 : 16321 : SubstitutionArg adjusted (&subst, arg.get_tyty ());
966 : 16321 : resolved_mappings.push_back (std::move (adjusted));
967 : : }
968 : : }
969 : :
970 : 12595 : if (resolved_mappings.empty ())
971 : 8 : return SubstitutionArgumentMappings::error ();
972 : :
973 : 12587 : return SubstitutionArgumentMappings (resolved_mappings,
974 : 12587 : mappings.get_binding_args (),
975 : : mappings.get_regions (),
976 : : mappings.get_locus (),
977 : 12587 : mappings.get_subst_cb (),
978 : 25174 : mappings.trait_item_mode ());
979 : 12595 : }
980 : :
981 : : bool
982 : 0 : SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
983 : : {
984 : 0 : std::vector<SubstitutionArg> resolved_mappings;
985 : 0 : for (size_t i = 0; i < substitutions.size (); i++)
986 : : {
987 : 0 : auto &subst = substitutions.at (i);
988 : :
989 : 0 : SubstitutionArg arg = SubstitutionArg::error ();
990 : 0 : if (mappings.size () == substitutions.size ())
991 : : {
992 : 0 : mappings.get_argument_at (i, &arg);
993 : : }
994 : : else
995 : : {
996 : 0 : if (subst.needs_substitution ())
997 : : {
998 : : // get from passed in mappings
999 : 0 : mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
1000 : : }
1001 : : else
1002 : : {
1003 : : // we should already have this somewhere
1004 : 0 : used_arguments.get_argument_for_symbol (subst.get_param_ty (),
1005 : : &arg);
1006 : : }
1007 : : }
1008 : :
1009 : 0 : bool ok = !arg.is_error ();
1010 : 0 : if (ok)
1011 : : {
1012 : 0 : SubstitutionArg adjusted (&subst, arg.get_tyty ());
1013 : 0 : resolved_mappings.push_back (std::move (adjusted));
1014 : : }
1015 : : }
1016 : :
1017 : 0 : return !resolved_mappings.empty ();
1018 : 0 : }
1019 : :
1020 : : // this function assumes that the mappings being passed are for the same type as
1021 : : // this new substitution reference so ordering matters here
1022 : : SubstitutionArgumentMappings
1023 : 63 : SubstitutionRef::solve_mappings_from_receiver_for_self (
1024 : : SubstitutionArgumentMappings &mappings) const
1025 : : {
1026 : 63 : std::vector<SubstitutionArg> resolved_mappings;
1027 : :
1028 : 63 : rust_assert (mappings.size () == get_num_substitutions ());
1029 : 126 : for (size_t i = 0; i < get_num_substitutions (); i++)
1030 : : {
1031 : 63 : const SubstitutionParamMapping ¶m_mapping = substitutions.at (i);
1032 : 63 : SubstitutionArg &arg = mappings.get_mappings ().at (i);
1033 : :
1034 : 63 : if (param_mapping.needs_substitution ())
1035 : : {
1036 : 63 : SubstitutionArg adjusted (¶m_mapping, arg.get_tyty ());
1037 : 63 : resolved_mappings.push_back (std::move (adjusted));
1038 : : }
1039 : : }
1040 : :
1041 : 63 : return SubstitutionArgumentMappings (resolved_mappings,
1042 : 63 : mappings.get_binding_args (),
1043 : : mappings.get_regions (),
1044 : 126 : mappings.get_locus ());
1045 : 63 : }
1046 : :
1047 : : void
1048 : 4293 : SubstitutionRef::prepare_higher_ranked_bounds ()
1049 : : {
1050 : 7183 : for (const auto &subst : get_substs ())
1051 : : {
1052 : 2890 : const auto pty = subst.get_param_ty ();
1053 : 6269 : for (const auto &bound : pty->get_specified_bounds ())
1054 : : {
1055 : 3379 : const auto ref = bound.get ();
1056 : 3379 : ref->clear_associated_type_projections ();
1057 : : }
1058 : : }
1059 : 4293 : }
1060 : :
1061 : : bool
1062 : 15246 : SubstitutionRef::monomorphize ()
1063 : : {
1064 : 24777 : for (const auto &subst : get_substs ())
1065 : : {
1066 : 9531 : const auto pty = subst.get_param_ty ();
1067 : 9531 : if (!pty->can_resolve ())
1068 : 100 : continue;
1069 : :
1070 : 9431 : const TyTy::BaseType *binding = pty->resolve ();
1071 : 9431 : if (binding->get_kind () == TyTy::TypeKind::PARAM)
1072 : 2243 : continue;
1073 : :
1074 : 15526 : for (const auto &bound : pty->get_specified_bounds ())
1075 : : {
1076 : 8338 : bool ambigious = false;
1077 : 8338 : auto associated
1078 : 8338 : = Resolver::lookup_associated_impl_block (bound, binding,
1079 : : &ambigious);
1080 : 8338 : if (associated != nullptr)
1081 : 1947 : associated->setup_associated_types (binding, bound);
1082 : : }
1083 : : }
1084 : :
1085 : 15246 : return true;
1086 : : }
1087 : :
1088 : : } // namespace TyTy
1089 : : } // namespace Rust
|