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-system.h"
22 : : #include "rust-tyty.h"
23 : : #include "rust-hir-type-check.h"
24 : : #include "rust-substitution-mapper.h"
25 : : #include "rust-hir-type-check-type.h"
26 : : #include "rust-type-util.h"
27 : :
28 : : namespace Rust {
29 : : namespace TyTy {
30 : :
31 : 32359266 : SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic,
32 : 32359266 : ParamType *param)
33 : 32359266 : : generic (generic), param (param)
34 : 32359266 : {}
35 : :
36 : 33120814 : SubstitutionParamMapping::SubstitutionParamMapping (
37 : 33120814 : const SubstitutionParamMapping &other)
38 : 33120814 : : generic (other.generic), param (other.param)
39 : 33120814 : {}
40 : :
41 : : std::string
42 : 115296 : SubstitutionParamMapping::as_string () const
43 : : {
44 : 115296 : if (param == nullptr)
45 : 0 : return "nullptr";
46 : :
47 : 115296 : return param->get_name ();
48 : : }
49 : :
50 : : SubstitutionParamMapping
51 : 32347319 : SubstitutionParamMapping::clone () const
52 : : {
53 : 32347319 : return SubstitutionParamMapping (generic,
54 : 32347319 : static_cast<ParamType *> (param->clone ()));
55 : : }
56 : :
57 : : ParamType *
58 : 136107 : SubstitutionParamMapping::get_param_ty ()
59 : : {
60 : 136107 : return param;
61 : : }
62 : :
63 : : const ParamType *
64 : 31986979 : SubstitutionParamMapping::get_param_ty () const
65 : : {
66 : 31986979 : return param;
67 : : }
68 : :
69 : : HIR::TypeParam &
70 : 10055 : SubstitutionParamMapping::get_generic_param ()
71 : : {
72 : 10055 : return generic;
73 : : }
74 : :
75 : : bool
76 : 45553 : SubstitutionParamMapping::needs_substitution () const
77 : : {
78 : 45553 : return !(get_param_ty ()->is_concrete ());
79 : : }
80 : :
81 : : location_t
82 : 2008 : SubstitutionParamMapping::get_param_locus () const
83 : : {
84 : 2008 : return generic.get_locus ();
85 : : }
86 : :
87 : : bool
88 : 18893 : SubstitutionParamMapping::param_has_default_ty () const
89 : : {
90 : 18893 : return generic.has_type ();
91 : : }
92 : :
93 : : BaseType *
94 : 576 : SubstitutionParamMapping::get_default_ty () const
95 : : {
96 : 576 : TyVar var (generic.get_type_mappings ().get_hirid ());
97 : 576 : return var.get_tyty ();
98 : : }
99 : :
100 : : bool
101 : 0 : SubstitutionParamMapping::need_substitution () const
102 : : {
103 : 0 : if (!param->can_resolve ())
104 : : return true;
105 : :
106 : 0 : auto resolved = param->resolve ();
107 : 0 : return !resolved->is_concrete ();
108 : : }
109 : :
110 : : bool
111 : 27342 : SubstitutionParamMapping::fill_param_ty (
112 : : SubstitutionArgumentMappings &subst_mappings, location_t locus)
113 : : {
114 : 27342 : SubstitutionArg arg = SubstitutionArg::error ();
115 : 27342 : bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
116 : 27342 : if (!ok)
117 : : return true;
118 : :
119 : 27342 : TyTy::BaseType &type = *arg.get_tyty ();
120 : 27342 : if (type.get_kind () == TyTy::TypeKind::INFER)
121 : : {
122 : 8624 : type.inherit_bounds (*param);
123 : : }
124 : :
125 : 27342 : if (type.get_kind () == TypeKind::PARAM)
126 : : {
127 : : // delete param;
128 : 3911 : param = static_cast<ParamType *> (type.clone ());
129 : : }
130 : : else
131 : : {
132 : : // check the substitution is compatible with bounds
133 : 23431 : rust_debug_loc (locus,
134 : : "fill_param_ty bounds_compatible: param %s type %s",
135 : 46862 : param->get_name ().c_str (), type.get_name ().c_str ());
136 : :
137 : 23431 : if (!param->is_implicit_self_trait ())
138 : : {
139 : 12127 : if (!param->bounds_compatible (type, locus, true))
140 : : return false;
141 : : }
142 : :
143 : : // recursively pass this down to all HRTB's
144 : 52141 : for (auto &bound : param->get_specified_bounds ())
145 : 28720 : bound.handle_substitions (subst_mappings);
146 : :
147 : 23421 : param->set_ty_ref (type.get_ref ());
148 : 23421 : subst_mappings.on_param_subst (*param, arg);
149 : : }
150 : :
151 : : return true;
152 : : }
153 : :
154 : : void
155 : 5683 : SubstitutionParamMapping::override_context ()
156 : : {
157 : 5683 : if (!param->can_resolve ())
158 : : return;
159 : :
160 : 5667 : auto &mappings = Analysis::Mappings::get ();
161 : 5667 : auto context = Resolver::TypeCheckContext::get ();
162 : :
163 : 5667 : context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
164 : : UNKNOWN_NODEID,
165 : 5667 : param->get_ref (),
166 : 5667 : UNKNOWN_LOCAL_DEFID),
167 : 5667 : param->resolve ());
168 : : }
169 : :
170 : 32036629 : SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
171 : 32036629 : BaseType *argument)
172 : 32036629 : : param (param), argument (argument)
173 : : {
174 : 32036629 : if (param != nullptr)
175 : 31914643 : original_param = param->get_param_ty ();
176 : 32036629 : }
177 : :
178 : 128074271 : SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
179 : 128074271 : : param (other.param), original_param (other.original_param),
180 : 128074271 : argument (other.argument)
181 : 128074271 : {}
182 : :
183 : : SubstitutionArg &
184 : 116483 : SubstitutionArg::operator= (const SubstitutionArg &other)
185 : : {
186 : 116483 : param = other.param;
187 : 116483 : argument = other.argument;
188 : 116483 : original_param = other.original_param;
189 : :
190 : 116483 : return *this;
191 : : }
192 : :
193 : : BaseType *
194 : 123686 : SubstitutionArg::get_tyty ()
195 : : {
196 : 123686 : return argument;
197 : : }
198 : :
199 : : const BaseType *
200 : 32610011 : SubstitutionArg::get_tyty () const
201 : : {
202 : 32610011 : return argument;
203 : : }
204 : :
205 : : const SubstitutionParamMapping *
206 : 5533 : SubstitutionArg::get_param_mapping () const
207 : : {
208 : 5533 : return param;
209 : : }
210 : :
211 : : const ParamType *
212 : 127046 : SubstitutionArg::get_param_ty () const
213 : : {
214 : 127046 : return original_param;
215 : : }
216 : :
217 : : SubstitutionArg
218 : 121986 : SubstitutionArg::error ()
219 : : {
220 : 121986 : return SubstitutionArg (nullptr, nullptr);
221 : : }
222 : :
223 : : bool
224 : 41841 : SubstitutionArg::is_error () const
225 : : {
226 : 41841 : return param == nullptr || argument == nullptr;
227 : : }
228 : :
229 : : bool
230 : 0 : SubstitutionArg::is_conrete () const
231 : : {
232 : 0 : if (argument == nullptr)
233 : : return false;
234 : :
235 : 0 : if (argument->get_kind () == TyTy::TypeKind::PARAM)
236 : : return false;
237 : :
238 : 0 : return argument->is_concrete ();
239 : : }
240 : :
241 : : std::string
242 : 0 : SubstitutionArg::as_string () const
243 : : {
244 : 0 : return original_param->as_string ()
245 : 0 : + (argument != nullptr ? ":" + argument->as_string () : "");
246 : : }
247 : :
248 : : const RegionParamList &
249 : 31700905 : SubstitutionArgumentMappings::get_regions () const
250 : : {
251 : 31700905 : return regions;
252 : : }
253 : :
254 : : RegionParamList &
255 : 1060 : SubstitutionArgumentMappings::get_mut_regions ()
256 : : {
257 : 1060 : return regions;
258 : : }
259 : :
260 : : // SubstitutionArgumentMappings
261 : :
262 : 63513477 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
263 : : std::vector<SubstitutionArg> mappings,
264 : : std::map<std::string, BaseType *> binding_args, RegionParamList regions,
265 : : location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
266 : 63513477 : bool error_flag)
267 : 63513477 : : mappings (std::move (mappings)), binding_args (binding_args),
268 : 63513477 : regions (regions), locus (locus), param_subst_cb (param_subst_cb),
269 : 63513477 : trait_item_flag (trait_item_flag), error_flag (error_flag)
270 : 63513477 : {}
271 : :
272 : 32013730 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
273 : 32013730 : const SubstitutionArgumentMappings &other)
274 : 32013730 : : mappings (other.mappings), binding_args (other.binding_args),
275 : 32013730 : regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
276 : 32013730 : trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
277 : 32013730 : {}
278 : :
279 : : SubstitutionArgumentMappings &
280 : 29928 : SubstitutionArgumentMappings::operator= (
281 : : const SubstitutionArgumentMappings &other)
282 : : {
283 : 29928 : mappings = other.mappings;
284 : 29928 : binding_args = other.binding_args;
285 : 29928 : regions = other.regions;
286 : 29928 : locus = other.locus;
287 : 29928 : param_subst_cb = nullptr;
288 : 29928 : trait_item_flag = other.trait_item_flag;
289 : 29928 : error_flag = other.error_flag;
290 : :
291 : 29928 : return *this;
292 : : }
293 : :
294 : : SubstitutionArgumentMappings
295 : 25896 : SubstitutionArgumentMappings::error ()
296 : : {
297 : 51792 : return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
298 : 25896 : false, true);
299 : : }
300 : :
301 : : SubstitutionArgumentMappings
302 : 31794110 : SubstitutionArgumentMappings::empty (size_t num_regions)
303 : : {
304 : 63588220 : return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
305 : 31794110 : nullptr, false, false);
306 : : }
307 : :
308 : : bool
309 : 26347 : SubstitutionArgumentMappings::is_error () const
310 : : {
311 : 26347 : return error_flag;
312 : : }
313 : :
314 : : bool
315 : 110230 : SubstitutionArgumentMappings::get_argument_for_symbol (
316 : : const ParamType *param_to_find, SubstitutionArg *argument) const
317 : : {
318 : 138167 : for (const auto &mapping : mappings)
319 : : {
320 : 127046 : const ParamType *p = mapping.get_param_ty ();
321 : 127046 : if (p->get_symbol () == param_to_find->get_symbol ())
322 : : {
323 : 99109 : *argument = mapping;
324 : 99109 : return true;
325 : : }
326 : : }
327 : : return false;
328 : : }
329 : : tl::optional<size_t>
330 : 0 : SubstitutionArgumentMappings::find_symbol (const ParamType ¶m_to_find) const
331 : : {
332 : 0 : auto it = std::find_if (mappings.begin (), mappings.end (),
333 : 0 : [param_to_find] (const SubstitutionArg &arg) {
334 : 0 : return arg.get_param_ty ()->get_symbol ()
335 : 0 : == param_to_find.get_symbol ();
336 : : });
337 : 0 : if (it == mappings.end ())
338 : 0 : return tl::nullopt;
339 : 0 : return std::distance (mappings.begin (), it);
340 : : }
341 : :
342 : : bool
343 : 11756 : SubstitutionArgumentMappings::get_argument_at (size_t index,
344 : : SubstitutionArg *argument)
345 : : {
346 : 11756 : if (index > mappings.size ())
347 : : return false;
348 : :
349 : 11756 : *argument = mappings.at (index);
350 : 11756 : return true;
351 : : }
352 : :
353 : : bool
354 : 0 : SubstitutionArgumentMappings::is_concrete () const
355 : : {
356 : 0 : for (auto &mapping : mappings)
357 : : {
358 : 0 : if (!mapping.is_conrete ())
359 : 0 : return false;
360 : : }
361 : : return true;
362 : : }
363 : :
364 : : location_t
365 : 31704105 : SubstitutionArgumentMappings::get_locus () const
366 : : {
367 : 31704105 : return locus;
368 : : }
369 : :
370 : : size_t
371 : 32064 : SubstitutionArgumentMappings::size () const
372 : : {
373 : 32064 : return mappings.size ();
374 : : }
375 : :
376 : : bool
377 : 12137 : SubstitutionArgumentMappings::is_empty () const
378 : : {
379 : 12137 : return size () == 0;
380 : : }
381 : :
382 : : std::vector<SubstitutionArg> &
383 : 43462 : SubstitutionArgumentMappings::get_mappings ()
384 : : {
385 : 43462 : return mappings;
386 : : }
387 : :
388 : : const std::vector<SubstitutionArg> &
389 : 127054502 : SubstitutionArgumentMappings::get_mappings () const
390 : : {
391 : 127054502 : return mappings;
392 : : }
393 : :
394 : : std::map<std::string, BaseType *> &
395 : 47647 : SubstitutionArgumentMappings::get_binding_args ()
396 : : {
397 : 47647 : return binding_args;
398 : : }
399 : :
400 : : const std::map<std::string, BaseType *> &
401 : 0 : SubstitutionArgumentMappings::get_binding_args () const
402 : : {
403 : 0 : return binding_args;
404 : : }
405 : :
406 : : std::string
407 : 0 : SubstitutionArgumentMappings::as_string () const
408 : : {
409 : 0 : std::string buffer;
410 : 0 : for (auto &mapping : mappings)
411 : : {
412 : 0 : buffer += mapping.as_string () + ", ";
413 : : }
414 : 0 : return "<" + buffer + ">";
415 : 0 : }
416 : :
417 : : void
418 : 52760 : SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
419 : : const SubstitutionArg &a) const
420 : : {
421 : 52760 : if (param_subst_cb == nullptr)
422 : : return;
423 : :
424 : 598 : param_subst_cb (p, a);
425 : : }
426 : :
427 : : ParamSubstCb
428 : 14643 : SubstitutionArgumentMappings::get_subst_cb () const
429 : : {
430 : 14643 : return param_subst_cb;
431 : : }
432 : :
433 : : bool
434 : 10950 : SubstitutionArgumentMappings::trait_item_mode () const
435 : : {
436 : 10950 : return trait_item_flag;
437 : : }
438 : :
439 : : // SubstitutionRef
440 : :
441 : 31835078 : SubstitutionRef::SubstitutionRef (
442 : : std::vector<SubstitutionParamMapping> substitutions,
443 : 31835078 : SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
444 : 31835078 : : substitutions (substitutions), used_arguments (arguments),
445 : 63670156 : region_constraints (region_constraints)
446 : 31835078 : {}
447 : :
448 : : bool
449 : 102292 : SubstitutionRef::has_substitutions () const
450 : : {
451 : 102292 : return substitutions.size () > 0;
452 : : }
453 : :
454 : : std::string
455 : 236703 : SubstitutionRef::subst_as_string () const
456 : : {
457 : 236703 : std::string buffer;
458 : 351999 : for (size_t i = 0; i < substitutions.size (); i++)
459 : : {
460 : 115296 : const SubstitutionParamMapping &sub = substitutions.at (i);
461 : 230592 : buffer += sub.as_string ();
462 : :
463 : 115296 : if ((i + 1) < substitutions.size ())
464 : 13251 : buffer += ", ";
465 : : }
466 : :
467 : 338748 : return buffer.empty () ? "" : "<" + buffer + ">";
468 : 236703 : }
469 : :
470 : : bool
471 : 61 : SubstitutionRef::supports_associated_bindings () const
472 : : {
473 : 61 : return get_num_associated_bindings () > 0;
474 : : }
475 : :
476 : : size_t
477 : 2 : SubstitutionRef::get_num_associated_bindings () const
478 : : {
479 : 2 : return 0;
480 : : }
481 : :
482 : : TypeBoundPredicateItem
483 : 0 : SubstitutionRef::lookup_associated_type (const std::string &search)
484 : : {
485 : 0 : return TypeBoundPredicateItem::error ();
486 : : }
487 : :
488 : : size_t
489 : 35537 : SubstitutionRef::get_num_substitutions () const
490 : : {
491 : 35537 : return substitutions.size ();
492 : : }
493 : : size_t
494 : 135 : SubstitutionRef::get_num_lifetime_params () const
495 : : {
496 : 135 : return used_arguments.get_regions ().size ();
497 : : }
498 : : size_t
499 : 332 : SubstitutionRef::get_num_type_params () const
500 : : {
501 : 332 : return get_num_substitutions ();
502 : : }
503 : :
504 : : std::vector<SubstitutionParamMapping> &
505 : 101336 : SubstitutionRef::get_substs ()
506 : : {
507 : 101336 : return substitutions;
508 : : }
509 : :
510 : : const std::vector<SubstitutionParamMapping> &
511 : 31682581 : SubstitutionRef::get_substs () const
512 : : {
513 : 31682581 : return substitutions;
514 : : }
515 : :
516 : : std::vector<SubstitutionParamMapping>
517 : 93966 : SubstitutionRef::clone_substs () const
518 : : {
519 : 93966 : std::vector<SubstitutionParamMapping> clone;
520 : :
521 : 146361 : for (auto &sub : substitutions)
522 : 52395 : clone.push_back (sub.clone ());
523 : :
524 : 93966 : return clone;
525 : : }
526 : :
527 : : void
528 : 5262 : SubstitutionRef::override_context ()
529 : : {
530 : 10945 : for (auto &sub : substitutions)
531 : : {
532 : 5683 : sub.override_context ();
533 : : }
534 : 5262 : }
535 : :
536 : : bool
537 : 29359 : SubstitutionRef::needs_substitution () const
538 : : {
539 : 29359 : return std::any_of (substitutions.begin (), substitutions.end (),
540 : : std::mem_fn (
541 : 29359 : &SubstitutionParamMapping::needs_substitution));
542 : : }
543 : :
544 : : bool
545 : 64 : SubstitutionRef::was_substituted () const
546 : : {
547 : 64 : return !needs_substitution ();
548 : : }
549 : :
550 : : SubstitutionArgumentMappings &
551 : 32110 : SubstitutionRef::get_substitution_arguments ()
552 : : {
553 : 32110 : return used_arguments;
554 : : }
555 : :
556 : : const SubstitutionArgumentMappings &
557 : 19231 : SubstitutionRef::get_substitution_arguments () const
558 : : {
559 : 19231 : return used_arguments;
560 : : }
561 : :
562 : : size_t
563 : 7567 : SubstitutionRef::num_required_substitutions () const
564 : : {
565 : 7567 : size_t n = 0;
566 : 16765 : for (auto &p : substitutions)
567 : : {
568 : 9198 : if (p.needs_substitution ())
569 : 9150 : n++;
570 : : }
571 : 7567 : return n;
572 : : }
573 : :
574 : : size_t
575 : 15147 : SubstitutionRef::min_required_substitutions () const
576 : : {
577 : 15147 : size_t n = 0;
578 : 33560 : for (auto &p : substitutions)
579 : : {
580 : 18413 : if (p.needs_substitution () && !p.param_has_default_ty ())
581 : 16627 : n++;
582 : : }
583 : 15147 : return n;
584 : : }
585 : :
586 : : const SubstitutionArgumentMappings &
587 : 10221 : SubstitutionRef::get_used_arguments () const
588 : : {
589 : 10221 : return used_arguments;
590 : : }
591 : :
592 : : tl::optional<SubstitutionArg>
593 : 114 : SubstitutionRef::get_arg_at (size_t i) const
594 : : {
595 : 114 : auto param_ty = get_substs ().at (i).get_param_ty ();
596 : 114 : SubstitutionArg arg = SubstitutionArg::error ();
597 : 114 : get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
598 : 114 : if (arg.is_error ())
599 : 2 : return tl::nullopt;
600 : 112 : return arg;
601 : : }
602 : :
603 : : const RegionConstraints &
604 : 92275 : SubstitutionRef::get_region_constraints () const
605 : : {
606 : 92275 : return region_constraints;
607 : : }
608 : :
609 : : SubstitutionArgumentMappings
610 : 7580 : SubstitutionRef::get_mappings_from_generic_args (
611 : : HIR::GenericArgs &args, const std::vector<Region> ®ions)
612 : : {
613 : 7580 : std::map<std::string, BaseType *> binding_arguments;
614 : 7580 : if (args.get_binding_args ().size () > 0)
615 : : {
616 : 61 : if (supports_associated_bindings ())
617 : : {
618 : 59 : if (args.get_binding_args ().size () > get_num_associated_bindings ())
619 : : {
620 : 0 : rich_location r (line_table, args.get_locus ());
621 : :
622 : 0 : rust_error_at (r,
623 : : "generic item takes at most %lu type binding "
624 : : "arguments but %lu were supplied",
625 : 0 : (unsigned long) get_num_associated_bindings (),
626 : 0 : (unsigned long) args.get_binding_args ().size ());
627 : 0 : return SubstitutionArgumentMappings::error ();
628 : 0 : }
629 : :
630 : 118 : for (auto &binding : args.get_binding_args ())
631 : : {
632 : 59 : BaseType *resolved
633 : 59 : = Resolver::TypeCheckType::Resolve (binding.get_type ());
634 : 59 : if (resolved == nullptr
635 : 59 : || resolved->get_kind () == TyTy::TypeKind::ERROR)
636 : : {
637 : 0 : return SubstitutionArgumentMappings::error ();
638 : : }
639 : :
640 : : // resolve to relevant binding
641 : 59 : auto binding_item = lookup_associated_type (
642 : 59 : binding.get_identifier ().as_string ());
643 : 59 : if (binding_item.is_error ())
644 : : {
645 : 0 : rust_error_at (
646 : : binding.get_locus (), "unknown associated type binding: %s",
647 : 0 : binding.get_identifier ().as_string ().c_str ());
648 : 0 : return SubstitutionArgumentMappings::error ();
649 : : }
650 : :
651 : 59 : binding_arguments[binding.get_identifier ().as_string ()]
652 : 59 : = resolved;
653 : 59 : }
654 : : }
655 : : else
656 : : {
657 : 2 : rich_location r (line_table, args.get_locus ());
658 : 6 : for (auto &binding : args.get_binding_args ())
659 : 4 : r.add_range (binding.get_locus ());
660 : :
661 : 2 : rust_error_at (r, ErrorCode::E0229,
662 : : "associated type bindings are not allowed here");
663 : 2 : return SubstitutionArgumentMappings::error ();
664 : 2 : }
665 : : }
666 : :
667 : : // for inherited arguments
668 : 7578 : size_t offs = used_arguments.size ();
669 : 7578 : if (args.get_type_args ().size () + offs > substitutions.size ())
670 : : {
671 : 4 : rich_location r (line_table, args.get_locus ());
672 : 4 : if (!substitutions.empty ())
673 : 2 : r.add_range (substitutions.front ().get_param_locus ());
674 : :
675 : 8 : rust_error_at (
676 : : r,
677 : : "generic item takes at most %lu type arguments but %lu were supplied",
678 : 4 : (unsigned long) substitutions.size (),
679 : 4 : (unsigned long) args.get_type_args ().size ());
680 : 4 : return SubstitutionArgumentMappings::error ();
681 : 4 : }
682 : :
683 : 7574 : if (args.get_type_args ().size () + offs < min_required_substitutions ())
684 : : {
685 : 6 : rich_location r (line_table, args.get_locus ());
686 : 6 : r.add_range (substitutions.front ().get_param_locus ());
687 : :
688 : 12 : rust_error_at (
689 : : r, ErrorCode::E0107,
690 : : "generic item takes at least %lu type arguments but %lu were supplied",
691 : 6 : (unsigned long) (min_required_substitutions () - offs),
692 : 6 : (unsigned long) args.get_type_args ().size ());
693 : 6 : return SubstitutionArgumentMappings::error ();
694 : 6 : }
695 : :
696 : 7568 : std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
697 : 15857 : for (auto &arg : args.get_type_args ())
698 : : {
699 : 8290 : BaseType *resolved = Resolver::TypeCheckType::Resolve (*arg);
700 : 8290 : if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
701 : : {
702 : 1 : return SubstitutionArgumentMappings::error ();
703 : : }
704 : :
705 : 8289 : SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
706 : 8289 : offs++;
707 : 8289 : mappings.push_back (std::move (subst_arg));
708 : : }
709 : :
710 : : // we must need to fill out defaults
711 : 7567 : size_t left_over
712 : 7567 : = num_required_substitutions () - min_required_substitutions ();
713 : 7567 : if (left_over > 0)
714 : : {
715 : 1421 : for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
716 : : {
717 : 576 : SubstitutionParamMapping ¶m = substitutions.at (offs);
718 : 576 : rust_assert (param.param_has_default_ty ());
719 : :
720 : 576 : BaseType *resolved = param.get_default_ty ();
721 : 576 : if (resolved->get_kind () == TypeKind::ERROR)
722 : 0 : return SubstitutionArgumentMappings::error ();
723 : :
724 : : // this resolved default might already contain default parameters
725 : 576 : if (!resolved->is_concrete ())
726 : : {
727 : 560 : SubstitutionArgumentMappings intermediate (
728 : : mappings, binding_arguments,
729 : 560 : {used_arguments.get_regions ().size ()}, args.get_locus ());
730 : 560 : resolved = Resolver::SubstMapperInternal::Resolve (resolved,
731 : : intermediate);
732 : :
733 : 560 : if (resolved->get_kind () == TypeKind::ERROR)
734 : 0 : return SubstitutionArgumentMappings::error ();
735 : 560 : }
736 : :
737 : 576 : SubstitutionArg subst_arg (¶m, resolved);
738 : 576 : mappings.push_back (std::move (subst_arg));
739 : : }
740 : : }
741 : :
742 : 7567 : return {mappings, binding_arguments,
743 : 15134 : RegionParamList::from_subst (used_arguments.get_regions ().size (),
744 : : regions),
745 : 22701 : args.get_locus ()};
746 : 7568 : }
747 : :
748 : : BaseType *
749 : 4848 : SubstitutionRef::infer_substitions (location_t locus)
750 : : {
751 : 4848 : std::vector<SubstitutionArg> args;
752 : 4848 : std::map<std::string, BaseType *> argument_mappings;
753 : 10499 : for (auto &p : get_substs ())
754 : : {
755 : 5651 : if (p.needs_substitution ())
756 : : {
757 : 5578 : const std::string &symbol = p.get_param_ty ()->get_symbol ();
758 : 5578 : auto it = argument_mappings.find (symbol);
759 : 5578 : bool have_mapping = it != argument_mappings.end ();
760 : :
761 : 5578 : if (have_mapping)
762 : : {
763 : 8 : args.push_back (SubstitutionArg (&p, it->second));
764 : : }
765 : : else
766 : : {
767 : 5570 : TyVar infer_var = TyVar::get_implicit_infer_var (locus);
768 : 5570 : args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
769 : 5570 : argument_mappings[symbol] = infer_var.get_tyty ();
770 : : }
771 : 5578 : }
772 : : else
773 : : {
774 : 73 : args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
775 : : }
776 : : }
777 : :
778 : : // FIXME do we need to add inference variables to all the possible bindings?
779 : : // it might just lead to inference variable hell not 100% sure if rustc does
780 : : // this i think the language might needs this to be explicitly set
781 : :
782 : 4848 : SubstitutionArgumentMappings infer_arguments (std::move (args),
783 : : {} /* binding_arguments */,
784 : : used_arguments.get_regions (),
785 : 4848 : locus);
786 : 4848 : return handle_substitions (infer_arguments);
787 : 4848 : }
788 : :
789 : : SubstitutionArgumentMappings
790 : 10436 : SubstitutionRef::adjust_mappings_for_this (
791 : : SubstitutionArgumentMappings &mappings, bool trait_mode)
792 : : {
793 : 10436 : std::vector<SubstitutionArg> resolved_mappings;
794 : 22721 : for (size_t i = 0; i < substitutions.size (); i++)
795 : : {
796 : 12285 : auto &subst = substitutions.at (i);
797 : :
798 : 12285 : SubstitutionArg arg = SubstitutionArg::error ();
799 : 12285 : if (mappings.size () == substitutions.size ())
800 : : {
801 : 11756 : mappings.get_argument_at (i, &arg);
802 : : }
803 : : else
804 : : {
805 : 529 : if (subst.needs_substitution ())
806 : : {
807 : : // get from passed in mappings
808 : 435 : mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
809 : : }
810 : : else
811 : : {
812 : : // we should already have this somewhere
813 : 94 : used_arguments.get_argument_for_symbol (subst.get_param_ty (),
814 : : &arg);
815 : : }
816 : : }
817 : :
818 : 12285 : bool ok = !arg.is_error ();
819 : 12285 : if (ok || (trait_mode && i == 0))
820 : : {
821 : 12185 : SubstitutionArg adjusted (&subst, arg.get_tyty ());
822 : 12185 : resolved_mappings.push_back (std::move (adjusted));
823 : : }
824 : : }
825 : :
826 : 10436 : if (resolved_mappings.empty ())
827 : 9 : return SubstitutionArgumentMappings::error ();
828 : :
829 : 10427 : return SubstitutionArgumentMappings (resolved_mappings,
830 : 10427 : mappings.get_binding_args (),
831 : : mappings.get_regions (),
832 : : mappings.get_locus (),
833 : 10427 : mappings.get_subst_cb (),
834 : 20854 : mappings.trait_item_mode ());
835 : 10436 : }
836 : :
837 : : bool
838 : 0 : SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
839 : : {
840 : 0 : std::vector<SubstitutionArg> resolved_mappings;
841 : 0 : for (size_t i = 0; i < substitutions.size (); i++)
842 : : {
843 : 0 : auto &subst = substitutions.at (i);
844 : :
845 : 0 : SubstitutionArg arg = SubstitutionArg::error ();
846 : 0 : if (mappings.size () == substitutions.size ())
847 : : {
848 : 0 : mappings.get_argument_at (i, &arg);
849 : : }
850 : : else
851 : : {
852 : 0 : if (subst.needs_substitution ())
853 : : {
854 : : // get from passed in mappings
855 : 0 : mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
856 : : }
857 : : else
858 : : {
859 : : // we should already have this somewhere
860 : 0 : used_arguments.get_argument_for_symbol (subst.get_param_ty (),
861 : : &arg);
862 : : }
863 : : }
864 : :
865 : 0 : bool ok = !arg.is_error ();
866 : 0 : if (ok)
867 : : {
868 : 0 : SubstitutionArg adjusted (&subst, arg.get_tyty ());
869 : 0 : resolved_mappings.push_back (std::move (adjusted));
870 : : }
871 : : }
872 : :
873 : 0 : return !resolved_mappings.empty ();
874 : 0 : }
875 : :
876 : : // this function assumes that the mappings being passed are for the same type as
877 : : // this new substitution reference so ordering matters here
878 : : SubstitutionArgumentMappings
879 : 64 : SubstitutionRef::solve_mappings_from_receiver_for_self (
880 : : SubstitutionArgumentMappings &mappings) const
881 : : {
882 : 64 : std::vector<SubstitutionArg> resolved_mappings;
883 : :
884 : 64 : rust_assert (mappings.size () == get_num_substitutions ());
885 : 128 : for (size_t i = 0; i < get_num_substitutions (); i++)
886 : : {
887 : 64 : const SubstitutionParamMapping ¶m_mapping = substitutions.at (i);
888 : 64 : SubstitutionArg &arg = mappings.get_mappings ().at (i);
889 : :
890 : 64 : if (param_mapping.needs_substitution ())
891 : : {
892 : 64 : SubstitutionArg adjusted (¶m_mapping, arg.get_tyty ());
893 : 64 : resolved_mappings.push_back (std::move (adjusted));
894 : : }
895 : : }
896 : :
897 : 64 : return SubstitutionArgumentMappings (resolved_mappings,
898 : 64 : mappings.get_binding_args (),
899 : : mappings.get_regions (),
900 : 128 : mappings.get_locus ());
901 : 64 : }
902 : :
903 : : void
904 : 1963 : SubstitutionRef::prepare_higher_ranked_bounds ()
905 : : {
906 : 3489 : for (const auto &subst : get_substs ())
907 : : {
908 : 1526 : const TyTy::ParamType *pty = subst.get_param_ty ();
909 : 3437 : for (const auto &bound : pty->get_specified_bounds ())
910 : : {
911 : 1911 : const auto ref = bound.get ();
912 : 1911 : ref->clear_associated_type_projections ();
913 : : }
914 : : }
915 : 1963 : }
916 : :
917 : : bool
918 : 12278 : SubstitutionRef::monomorphize ()
919 : : {
920 : 20095 : for (const auto &subst : get_substs ())
921 : : {
922 : 7817 : const TyTy::ParamType *pty = subst.get_param_ty ();
923 : :
924 : 7817 : if (!pty->can_resolve ())
925 : 85 : continue;
926 : :
927 : 7732 : const TyTy::BaseType *binding = pty->resolve ();
928 : 7732 : if (binding->get_kind () == TyTy::TypeKind::PARAM)
929 : 1262 : continue;
930 : :
931 : 13670 : for (const auto &bound : pty->get_specified_bounds ())
932 : : {
933 : 7200 : bool ambigious = false;
934 : 7200 : auto associated
935 : 7200 : = Resolver::lookup_associated_impl_block (bound, binding,
936 : : &ambigious);
937 : 7200 : if (associated != nullptr)
938 : 1086 : associated->setup_associated_types (binding, bound);
939 : : }
940 : : }
941 : :
942 : 12278 : return true;
943 : : }
944 : :
945 : : } // namespace TyTy
946 : : } // namespace Rust
|