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-trait-reference.h"
20 : :
21 : : namespace Rust {
22 : : namespace Resolver {
23 : :
24 : : std::string
25 : 5922 : TraitItemReference::as_string () const
26 : : {
27 : 23688 : return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
28 : : }
29 : :
30 : : bool
31 : 165109 : TraitItemReference::is_error () const
32 : : {
33 : 165109 : return type == ERROR;
34 : : }
35 : :
36 : : bool
37 : 6303 : TraitItemReference::is_optional () const
38 : : {
39 : 6303 : return optional_flag;
40 : : }
41 : :
42 : : std::string
43 : 251049 : TraitItemReference::get_identifier () const
44 : : {
45 : 251049 : return identifier;
46 : : }
47 : :
48 : : TraitItemReference::TraitItemType
49 : 285725 : TraitItemReference::get_trait_item_type () const
50 : : {
51 : 285725 : return type;
52 : : }
53 : :
54 : : HIR::TraitItem *
55 : 22638 : TraitItemReference::get_hir_trait_item () const
56 : : {
57 : 22638 : return hir_trait_item;
58 : : }
59 : :
60 : : location_t
61 : 1947 : TraitItemReference::get_locus () const
62 : : {
63 : 1947 : return locus;
64 : : }
65 : :
66 : : const Analysis::NodeMapping
67 : 11718 : TraitItemReference::get_mappings () const
68 : : {
69 : 11718 : return hir_trait_item->get_mappings ();
70 : : }
71 : :
72 : : TyTy::BaseType *
73 : 31574 : TraitItemReference::get_tyty () const
74 : : {
75 : 31574 : rust_assert (hir_trait_item != nullptr);
76 : :
77 : 31574 : switch (type)
78 : : {
79 : 31 : case CONST:
80 : 31 : return get_type_from_constant (
81 : 31 : static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
82 : 6938 : break;
83 : :
84 : 6938 : case TYPE:
85 : 6938 : return get_type_from_typealias (
86 : 6938 : static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
87 : :
88 : 24605 : case FN:
89 : 24605 : return get_type_from_fn (
90 : 24605 : static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
91 : 0 : break;
92 : :
93 : 0 : default:
94 : 0 : return get_error ();
95 : : }
96 : :
97 : : rust_unreachable ();
98 : : return get_error ();
99 : : }
100 : :
101 : : TyTy::ErrorType *
102 : 2 : TraitItemReference::get_error () const
103 : : {
104 : 2 : return new TyTy::ErrorType (get_mappings ().get_hirid ());
105 : : }
106 : :
107 : 5327 : TraitReference::TraitReference (
108 : : const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
109 : : std::vector<TyTy::TypeBoundPredicate> super_traits,
110 : 5327 : std::vector<TyTy::SubstitutionParamMapping> substs)
111 : 5327 : : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
112 : 5327 : super_traits (super_traits)
113 : : {
114 : 5327 : trait_substs.clear ();
115 : 5327 : trait_substs.reserve (substs.size ());
116 : 9555 : for (const auto &p : substs)
117 : 4228 : trait_substs.push_back (p.clone ());
118 : 5327 : }
119 : :
120 : 0 : TraitReference::TraitReference (TraitReference const &other)
121 : 0 : : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
122 : 0 : super_traits (other.super_traits)
123 : : {
124 : 0 : trait_substs.clear ();
125 : 0 : trait_substs.reserve (other.trait_substs.size ());
126 : 0 : for (const auto &p : other.trait_substs)
127 : 0 : trait_substs.push_back (p.clone ());
128 : 0 : }
129 : :
130 : : TraitReference &
131 : 0 : TraitReference::operator= (TraitReference const &other)
132 : : {
133 : 0 : hir_trait_ref = other.hir_trait_ref;
134 : 0 : item_refs = other.item_refs;
135 : 0 : super_traits = other.super_traits;
136 : :
137 : 0 : trait_substs.clear ();
138 : 0 : trait_substs.reserve (other.trait_substs.size ());
139 : 0 : for (const auto &p : other.trait_substs)
140 : 0 : trait_substs.push_back (p.clone ());
141 : :
142 : 0 : return *this;
143 : : }
144 : :
145 : : bool
146 : 283349 : TraitReference::is_error () const
147 : : {
148 : 283349 : return hir_trait_ref == nullptr;
149 : : }
150 : :
151 : : location_t
152 : 1 : TraitReference::get_locus () const
153 : : {
154 : 1 : return hir_trait_ref->get_locus ();
155 : : }
156 : :
157 : : std::string
158 : 15941 : TraitReference::get_name () const
159 : : {
160 : 15941 : rust_assert (!is_error ());
161 : 31882 : return hir_trait_ref->get_name ().as_string ();
162 : : }
163 : :
164 : : std::string
165 : 3264 : TraitReference::as_string () const
166 : : {
167 : 3264 : if (is_error ())
168 : 0 : return "<trait-ref-error-node>";
169 : :
170 : 3264 : std::string item_buf;
171 : 9186 : for (auto &item : item_refs)
172 : : {
173 : 17766 : item_buf += item.as_string () + ", ";
174 : : }
175 : 6528 : return "HIR Trait: " + get_name () + "->"
176 : 16320 : + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
177 : 3264 : }
178 : :
179 : : const HIR::Trait *
180 : 19517 : TraitReference::get_hir_trait_ref () const
181 : : {
182 : 19517 : return hir_trait_ref;
183 : : }
184 : :
185 : : const Analysis::NodeMapping &
186 : 347132 : TraitReference::get_mappings () const
187 : : {
188 : 347132 : return hir_trait_ref->get_mappings ();
189 : : }
190 : :
191 : : DefId
192 : 165 : TraitReference::get_defid () const
193 : : {
194 : 165 : return get_mappings ().get_defid ();
195 : : }
196 : :
197 : : bool
198 : 241 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
199 : : TraitItemReference **ref)
200 : : {
201 : 241 : return lookup_trait_item (item.trait_identifier (), ref);
202 : : }
203 : :
204 : : bool
205 : 1830 : TraitReference::lookup_trait_item (const std::string &ident,
206 : : TraitItemReference **ref)
207 : : {
208 : 2197 : for (auto &item : item_refs)
209 : : {
210 : 2197 : if (ident.compare (item.get_identifier ()) == 0)
211 : : {
212 : 1830 : *ref = &item;
213 : 1830 : return true;
214 : : }
215 : : }
216 : : return false;
217 : : }
218 : :
219 : : bool
220 : 99 : TraitReference::lookup_trait_item_by_type (
221 : : const std::string &ident, TraitItemReference::TraitItemType type,
222 : : TraitItemReference **ref)
223 : : {
224 : 99 : for (auto &item : item_refs)
225 : : {
226 : 99 : if (item.get_trait_item_type () != type)
227 : 0 : continue;
228 : :
229 : 99 : if (ident.compare (item.get_identifier ()) == 0)
230 : : {
231 : 99 : *ref = &item;
232 : 99 : return true;
233 : : }
234 : : }
235 : : return false;
236 : : }
237 : :
238 : : bool
239 : 5321 : TraitReference::lookup_trait_item_by_type (
240 : : const std::string &ident, TraitItemReference::TraitItemType type,
241 : : const TraitItemReference **ref) const
242 : : {
243 : 8513 : for (auto &item : item_refs)
244 : : {
245 : 8510 : if (item.get_trait_item_type () != type)
246 : 1265 : continue;
247 : :
248 : 7245 : if (ident.compare (item.get_identifier ()) == 0)
249 : : {
250 : 5318 : *ref = &item;
251 : 5318 : return true;
252 : : }
253 : : }
254 : : return false;
255 : : }
256 : :
257 : : bool
258 : 0 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
259 : : const TraitItemReference **ref) const
260 : : {
261 : 0 : return lookup_trait_item (item.trait_identifier (), ref);
262 : : }
263 : :
264 : : bool
265 : 10589 : TraitReference::lookup_trait_item (const std::string &ident,
266 : : const TraitItemReference **ref,
267 : : bool lookup_supers) const
268 : : {
269 : 16666 : for (auto &item : item_refs)
270 : : {
271 : 15101 : if (ident.compare (item.get_identifier ()) == 0)
272 : : {
273 : 9024 : *ref = &item;
274 : 9024 : return true;
275 : : }
276 : : }
277 : :
278 : 1565 : if (!lookup_supers)
279 : : return false;
280 : :
281 : : // lookup super traits
282 : 85 : for (const auto &super_trait : super_traits)
283 : : {
284 : 14 : bool found = super_trait.get ()->lookup_trait_item (ident, ref);
285 : 14 : if (found)
286 : 9038 : return true;
287 : : }
288 : :
289 : : return false;
290 : : }
291 : :
292 : : const TraitItemReference *
293 : 159791 : TraitReference::lookup_trait_item (const std::string &ident,
294 : : TraitItemReference::TraitItemType type) const
295 : : {
296 : 384870 : for (auto &item : item_refs)
297 : : {
298 : 240556 : if (item.get_trait_item_type () != type)
299 : 26514 : continue;
300 : :
301 : 214042 : if (ident.compare (item.get_identifier ()) == 0)
302 : 159791 : return &item;
303 : : }
304 : :
305 : : // lookup super traits
306 : 197321 : for (const auto &super_trait : super_traits)
307 : : {
308 : 67316 : const TraitItemReference *res
309 : 67316 : = super_trait.get ()->lookup_trait_item (ident, type);
310 : 67316 : if (!res->is_error ())
311 : 159791 : return res;
312 : : }
313 : :
314 : 130005 : return &TraitItemReference::error_node ();
315 : : }
316 : :
317 : : size_t
318 : 4613 : TraitReference::size () const
319 : : {
320 : 4613 : return item_refs.size ();
321 : : }
322 : :
323 : : const std::vector<TraitItemReference> &
324 : 1987 : TraitReference::get_trait_items () const
325 : : {
326 : 1987 : return item_refs;
327 : : }
328 : :
329 : : void
330 : 1229 : TraitReference::get_trait_items_and_supers (
331 : : std::vector<const TraitItemReference *> &result) const
332 : : {
333 : 2548 : for (const auto &item : item_refs)
334 : 1319 : result.push_back (&item);
335 : :
336 : 1600 : for (const auto &super_trait : super_traits)
337 : 371 : super_trait.get ()->get_trait_items_and_supers (result);
338 : 1229 : }
339 : :
340 : : void
341 : 3592 : TraitReference::on_resolved ()
342 : : {
343 : 6870 : for (auto &item : item_refs)
344 : : {
345 : 3278 : if (item.get_trait_item_type ()
346 : : == TraitItemReference::TraitItemType::TYPE)
347 : 724 : item.on_resolved ();
348 : : }
349 : 6870 : for (auto &item : item_refs)
350 : : {
351 : 3278 : if (item.get_trait_item_type ()
352 : : != TraitItemReference::TraitItemType::TYPE)
353 : 2554 : item.on_resolved ();
354 : : }
355 : 3592 : }
356 : :
357 : : void
358 : 4614 : TraitReference::clear_associated_types () const
359 : : {
360 : 11970 : for (const auto &item : item_refs)
361 : : {
362 : 7356 : bool is_assoc_type = item.get_trait_item_type ()
363 : 7356 : == TraitItemReference::TraitItemType::TYPE;
364 : 7356 : if (is_assoc_type)
365 : 1168 : item.associated_type_reset (false);
366 : : }
367 : 4614 : }
368 : :
369 : : void
370 : 3379 : TraitReference::clear_associated_type_projections () const
371 : : {
372 : 8894 : for (const auto &item : item_refs)
373 : : {
374 : 5515 : bool is_assoc_type = item.get_trait_item_type ()
375 : 5515 : == TraitItemReference::TraitItemType::TYPE;
376 : 5515 : if (is_assoc_type)
377 : 176 : item.associated_type_reset (true);
378 : : }
379 : 3379 : }
380 : :
381 : : bool
382 : 160950 : TraitReference::is_equal (const TraitReference &other) const
383 : : {
384 : 160950 : DefId this_id = get_mappings ().get_defid ();
385 : 160950 : DefId other_id = other.get_mappings ().get_defid ();
386 : 160950 : return this_id == other_id;
387 : : }
388 : :
389 : : std::vector<TyTy::TypeBoundPredicate>
390 : 20120 : TraitReference::get_super_traits () const
391 : : {
392 : 20120 : return super_traits;
393 : : }
394 : :
395 : : bool
396 : 256 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
397 : : {
398 : : // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
399 : 256 : std::vector<const TraitReference *> non_object_super_traits;
400 : 312 : for (auto &super_trait : super_traits)
401 : : {
402 : 56 : if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
403 : 1 : non_object_super_traits.push_back (super_trait.get ());
404 : : }
405 : :
406 : 256 : std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
407 : 527 : for (auto &item : get_trait_items ())
408 : : {
409 : 271 : if (!item.is_object_safe ())
410 : 4 : non_object_safe_items.push_back (&item);
411 : : }
412 : :
413 : 256 : bool is_safe
414 : 256 : = non_object_super_traits.empty () && non_object_safe_items.empty ();
415 : 256 : if (emit_error && !is_safe)
416 : : {
417 : 2 : rich_location r (line_table, locus);
418 : 3 : for (auto &item : non_object_super_traits)
419 : 1 : r.add_range (item->get_locus ());
420 : 4 : for (auto &item : non_object_safe_items)
421 : 2 : r.add_range (item->get_locus ());
422 : :
423 : 2 : rust_error_at (r, "trait bound is not object safe");
424 : 2 : }
425 : :
426 : 256 : return is_safe;
427 : 256 : }
428 : :
429 : : bool
430 : 0 : TraitReference::trait_has_generics () const
431 : : {
432 : 0 : return !trait_substs.empty ();
433 : : }
434 : :
435 : : std::vector<TyTy::SubstitutionParamMapping> &
436 : 8 : TraitReference::get_trait_substs ()
437 : : {
438 : 8 : return trait_substs;
439 : : }
440 : :
441 : : const std::vector<TyTy::SubstitutionParamMapping> &
442 : 40240 : TraitReference::get_trait_substs () const
443 : : {
444 : 40240 : return trait_substs;
445 : : }
446 : :
447 : : bool
448 : 67485 : TraitReference::satisfies_bound (const TraitReference &reference) const
449 : : {
450 : 67485 : if (is_equal (reference))
451 : : return true;
452 : :
453 : 36361 : for (const auto &super_trait : super_traits)
454 : : {
455 : 10982 : if (super_trait.get ()->satisfies_bound (reference))
456 : 42106 : return true;
457 : : }
458 : :
459 : : return false;
460 : : }
461 : :
462 : 4614 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
463 : : TyTy::TypeBoundPredicate predicate,
464 : : HIR::ImplBlock *impl,
465 : : TyTy::BaseType *self,
466 : 4614 : Resolver::TypeCheckContext *context)
467 : 4614 : : trait (trait), predicate (predicate), impl (impl), self (self),
468 : 4614 : context (context)
469 : 4614 : {}
470 : :
471 : : TyTy::TypeBoundPredicate &
472 : 20526 : AssociatedImplTrait::get_predicate ()
473 : : {
474 : 20526 : return predicate;
475 : : }
476 : :
477 : : HIR::ImplBlock *
478 : 4776 : AssociatedImplTrait::get_impl_block ()
479 : : {
480 : 4776 : return impl;
481 : : }
482 : :
483 : : TyTy::BaseType *
484 : 2236 : AssociatedImplTrait::get_self ()
485 : : {
486 : 2236 : return self;
487 : : }
488 : :
489 : : const TyTy::BaseType *
490 : 0 : AssociatedImplTrait::get_self () const
491 : : {
492 : 0 : return self;
493 : : }
494 : :
495 : : } // namespace Resolver
496 : : } // namespace Rust
|