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 : 3499 : TraitItemReference::as_string () const
26 : : {
27 : 13996 : return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
28 : : }
29 : :
30 : : bool
31 : 92172 : TraitItemReference::is_error () const
32 : : {
33 : 92172 : return type == ERROR;
34 : : }
35 : :
36 : : bool
37 : 4244 : TraitItemReference::is_optional () const
38 : : {
39 : 4244 : return optional_flag;
40 : : }
41 : :
42 : : std::string
43 : 105761 : TraitItemReference::get_identifier () const
44 : : {
45 : 105761 : return identifier;
46 : : }
47 : :
48 : : TraitItemReference::TraitItemType
49 : 124172 : TraitItemReference::get_trait_item_type () const
50 : : {
51 : 124172 : return type;
52 : : }
53 : :
54 : : HIR::TraitItem *
55 : 9404 : TraitItemReference::get_hir_trait_item () const
56 : : {
57 : 9404 : return hir_trait_item;
58 : : }
59 : :
60 : : location_t
61 : 2028 : TraitItemReference::get_locus () const
62 : : {
63 : 2028 : return locus;
64 : : }
65 : :
66 : : const Analysis::NodeMapping
67 : 17722 : TraitItemReference::get_mappings () const
68 : : {
69 : 17722 : return hir_trait_item->get_mappings ();
70 : : }
71 : :
72 : : TyTy::BaseType *
73 : 20003 : TraitItemReference::get_tyty () const
74 : : {
75 : 20003 : rust_assert (hir_trait_item != nullptr);
76 : :
77 : 20003 : switch (type)
78 : : {
79 : 36 : case CONST:
80 : 36 : return get_type_from_constant (
81 : 36 : static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
82 : 10046 : break;
83 : :
84 : 10046 : case TYPE:
85 : 10046 : return get_type_from_typealias (
86 : 10046 : static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
87 : :
88 : 9921 : case FN:
89 : 9921 : return get_type_from_fn (
90 : 9921 : 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 : 4 : TraitItemReference::get_error () const
103 : : {
104 : 4 : return new TyTy::ErrorType (get_mappings ().get_hirid ());
105 : : }
106 : :
107 : 4952 : TraitReference::TraitReference (
108 : : const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
109 : : std::vector<TyTy::TypeBoundPredicate> super_traits,
110 : 4952 : std::vector<TyTy::SubstitutionParamMapping> substs)
111 : 4952 : : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
112 : 4952 : super_traits (super_traits)
113 : : {
114 : 4952 : trait_substs.clear ();
115 : 4952 : trait_substs.reserve (substs.size ());
116 : 8560 : for (const auto &p : substs)
117 : 3608 : trait_substs.push_back (p.clone ());
118 : 4952 : }
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 : 185817 : TraitReference::is_error () const
147 : : {
148 : 185817 : return hir_trait_ref == nullptr;
149 : : }
150 : :
151 : : location_t
152 : 2 : TraitReference::get_locus () const
153 : : {
154 : 2 : return hir_trait_ref->get_locus ();
155 : : }
156 : :
157 : : std::string
158 : 11879 : TraitReference::get_name () const
159 : : {
160 : 11879 : rust_assert (!is_error ());
161 : 23758 : return hir_trait_ref->get_name ().as_string ();
162 : : }
163 : :
164 : : std::string
165 : 2350 : TraitReference::as_string () const
166 : : {
167 : 2350 : if (is_error ())
168 : 0 : return "<trait-ref-error-node>";
169 : :
170 : 2350 : std::string item_buf;
171 : 5849 : for (auto &item : item_refs)
172 : : {
173 : 10497 : item_buf += item.as_string () + ", ";
174 : : }
175 : 4700 : return "HIR Trait: " + get_name () + "->"
176 : 11750 : + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
177 : 2350 : }
178 : :
179 : : const HIR::Trait *
180 : 6550 : TraitReference::get_hir_trait_ref () const
181 : : {
182 : 6550 : return hir_trait_ref;
183 : : }
184 : :
185 : : const Analysis::NodeMapping &
186 : 264684 : TraitReference::get_mappings () const
187 : : {
188 : 264684 : return hir_trait_ref->get_mappings ();
189 : : }
190 : :
191 : : DefId
192 : 188 : TraitReference::get_defid () const
193 : : {
194 : 188 : return get_mappings ().get_defid ();
195 : : }
196 : :
197 : : bool
198 : 158 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
199 : : TraitItemReference **ref)
200 : : {
201 : 158 : return lookup_trait_item (item.trait_identifier (), ref);
202 : : }
203 : :
204 : : bool
205 : 1831 : TraitReference::lookup_trait_item (const std::string &ident,
206 : : TraitItemReference **ref)
207 : : {
208 : 1988 : for (auto &item : item_refs)
209 : : {
210 : 1988 : if (ident.compare (item.get_identifier ()) == 0)
211 : : {
212 : 1831 : *ref = &item;
213 : 1831 : return true;
214 : : }
215 : : }
216 : : return false;
217 : : }
218 : :
219 : : bool
220 : 96 : TraitReference::lookup_trait_item_by_type (
221 : : const std::string &ident, TraitItemReference::TraitItemType type,
222 : : TraitItemReference **ref)
223 : : {
224 : 96 : for (auto &item : item_refs)
225 : : {
226 : 96 : if (item.get_trait_item_type () != type)
227 : 0 : continue;
228 : :
229 : 96 : if (ident.compare (item.get_identifier ()) == 0)
230 : : {
231 : 96 : *ref = &item;
232 : 96 : return true;
233 : : }
234 : : }
235 : : return false;
236 : : }
237 : :
238 : : bool
239 : 4245 : TraitReference::lookup_trait_item_by_type (
240 : : const std::string &ident, TraitItemReference::TraitItemType type,
241 : : const TraitItemReference **ref) const
242 : : {
243 : 6210 : for (auto &item : item_refs)
244 : : {
245 : 6204 : if (item.get_trait_item_type () != type)
246 : 1300 : continue;
247 : :
248 : 4904 : if (ident.compare (item.get_identifier ()) == 0)
249 : : {
250 : 4239 : *ref = &item;
251 : 4239 : 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 : 10451 : TraitReference::lookup_trait_item (const std::string &ident,
266 : : const TraitItemReference **ref,
267 : : bool lookup_supers) const
268 : : {
269 : 13931 : for (auto &item : item_refs)
270 : : {
271 : 12995 : if (ident.compare (item.get_identifier ()) == 0)
272 : : {
273 : 9515 : *ref = &item;
274 : 9515 : return true;
275 : : }
276 : : }
277 : :
278 : 936 : if (!lookup_supers)
279 : : return false;
280 : :
281 : : // lookup super traits
282 : 94 : for (const auto &super_trait : super_traits)
283 : : {
284 : 15 : bool found = super_trait.get ()->lookup_trait_item (ident, ref);
285 : 15 : if (found)
286 : 9530 : return true;
287 : : }
288 : :
289 : : return false;
290 : : }
291 : :
292 : : const TraitItemReference *
293 : 87933 : TraitReference::lookup_trait_item (const std::string &ident,
294 : : TraitItemReference::TraitItemType type) const
295 : : {
296 : 178463 : for (auto &item : item_refs)
297 : : {
298 : 93882 : if (item.get_trait_item_type () != type)
299 : 17225 : continue;
300 : :
301 : 76657 : if (ident.compare (item.get_identifier ()) == 0)
302 : 87933 : return &item;
303 : : }
304 : :
305 : : // lookup super traits
306 : 125378 : for (const auto &super_trait : super_traits)
307 : : {
308 : 41905 : const TraitItemReference *res
309 : 41905 : = super_trait.get ()->lookup_trait_item (ident, type);
310 : 41905 : if (!res->is_error ())
311 : 87933 : return res;
312 : : }
313 : :
314 : 83473 : return &TraitItemReference::error_node ();
315 : : }
316 : :
317 : : size_t
318 : 3946 : TraitReference::size () const
319 : : {
320 : 3946 : return item_refs.size ();
321 : : }
322 : :
323 : : const std::vector<TraitItemReference> &
324 : 1522 : TraitReference::get_trait_items () const
325 : : {
326 : 1522 : return item_refs;
327 : : }
328 : :
329 : : void
330 : 1317 : TraitReference::get_trait_items_and_supers (
331 : : std::vector<const TraitItemReference *> &result) const
332 : : {
333 : 2702 : for (const auto &item : item_refs)
334 : 1385 : result.push_back (&item);
335 : :
336 : 1730 : for (const auto &super_trait : super_traits)
337 : 413 : super_trait.get ()->get_trait_items_and_supers (result);
338 : 1317 : }
339 : :
340 : : void
341 : 3139 : TraitReference::on_resolved ()
342 : : {
343 : 5633 : for (auto &item : item_refs)
344 : : {
345 : 2494 : item.on_resolved ();
346 : : }
347 : 3139 : }
348 : :
349 : : void
350 : 3947 : TraitReference::clear_associated_types () const
351 : : {
352 : 9363 : for (const auto &item : item_refs)
353 : : {
354 : 5416 : bool is_assoc_type = item.get_trait_item_type ()
355 : 5416 : == TraitItemReference::TraitItemType::TYPE;
356 : 5416 : if (is_assoc_type)
357 : 1204 : item.associated_type_reset (false);
358 : : }
359 : 3947 : }
360 : :
361 : : void
362 : 1911 : TraitReference::clear_associated_type_projections () const
363 : : {
364 : 3326 : for (const auto &item : item_refs)
365 : : {
366 : 1415 : bool is_assoc_type = item.get_trait_item_type ()
367 : 1415 : == TraitItemReference::TraitItemType::TYPE;
368 : 1415 : if (is_assoc_type)
369 : 188 : item.associated_type_reset (true);
370 : : }
371 : 1911 : }
372 : :
373 : : bool
374 : 121296 : TraitReference::is_equal (const TraitReference &other) const
375 : : {
376 : 121296 : DefId this_id = get_mappings ().get_defid ();
377 : 121296 : DefId other_id = other.get_mappings ().get_defid ();
378 : 121296 : return this_id == other_id;
379 : : }
380 : :
381 : : std::vector<TyTy::TypeBoundPredicate>
382 : 17381 : TraitReference::get_super_traits () const
383 : : {
384 : 17381 : return super_traits;
385 : : }
386 : :
387 : : bool
388 : 251 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
389 : : {
390 : : // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
391 : 251 : std::vector<const TraitReference *> non_object_super_traits;
392 : 314 : for (auto &super_trait : super_traits)
393 : : {
394 : 63 : if (!super_trait.get ()->is_object_safe (false, UNDEF_LOCATION))
395 : 2 : non_object_super_traits.push_back (super_trait.get ());
396 : : }
397 : :
398 : 251 : std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
399 : 511 : for (auto &item : get_trait_items ())
400 : : {
401 : 260 : if (!item.is_object_safe ())
402 : 8 : non_object_safe_items.push_back (&item);
403 : : }
404 : :
405 : 251 : bool is_safe
406 : 251 : = non_object_super_traits.empty () && non_object_safe_items.empty ();
407 : 251 : if (emit_error && !is_safe)
408 : : {
409 : 4 : rich_location r (line_table, locus);
410 : 6 : for (auto &item : non_object_super_traits)
411 : 2 : r.add_range (item->get_locus ());
412 : 8 : for (auto &item : non_object_safe_items)
413 : 4 : r.add_range (item->get_locus ());
414 : :
415 : 4 : rust_error_at (r, "trait bound is not object safe");
416 : 4 : }
417 : :
418 : 251 : return is_safe;
419 : 251 : }
420 : :
421 : : bool
422 : 0 : TraitReference::trait_has_generics () const
423 : : {
424 : 0 : return !trait_substs.empty ();
425 : : }
426 : :
427 : : std::vector<TyTy::SubstitutionParamMapping>
428 : 34762 : TraitReference::get_trait_substs () const
429 : : {
430 : 34762 : return trait_substs;
431 : : }
432 : :
433 : : bool
434 : 47298 : TraitReference::satisfies_bound (const TraitReference &reference) const
435 : : {
436 : 47298 : if (is_equal (reference))
437 : : return true;
438 : :
439 : 27708 : for (const auto &super_trait : super_traits)
440 : : {
441 : 10468 : if (super_trait.get ()->satisfies_bound (reference))
442 : 30058 : return true;
443 : : }
444 : :
445 : : return false;
446 : : }
447 : :
448 : 3947 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
449 : : TyTy::TypeBoundPredicate predicate,
450 : : HIR::ImplBlock *impl,
451 : : TyTy::BaseType *self,
452 : 3947 : Resolver::TypeCheckContext *context)
453 : 3947 : : trait (trait), predicate (predicate), impl (impl), self (self),
454 : 3947 : context (context)
455 : 3947 : {}
456 : :
457 : : TyTy::TypeBoundPredicate &
458 : 18035 : AssociatedImplTrait::get_predicate ()
459 : : {
460 : 18035 : return predicate;
461 : : }
462 : :
463 : : HIR::ImplBlock *
464 : 3309 : AssociatedImplTrait::get_impl_block ()
465 : : {
466 : 3309 : return impl;
467 : : }
468 : :
469 : : TyTy::BaseType *
470 : 1459 : AssociatedImplTrait::get_self ()
471 : : {
472 : 1459 : return self;
473 : : }
474 : :
475 : : const TyTy::BaseType *
476 : 0 : AssociatedImplTrait::get_self () const
477 : : {
478 : 0 : return self;
479 : : }
480 : :
481 : : } // namespace Resolver
482 : : } // namespace Rust
|