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 : 2352 : TraitItemReference::as_string () const
26 : : {
27 : 9408 : return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
28 : : }
29 : :
30 : : bool
31 : 33132 : TraitItemReference::is_error () const
32 : : {
33 : 33132 : return type == ERROR;
34 : : }
35 : :
36 : : bool
37 : 2649 : TraitItemReference::is_optional () const
38 : : {
39 : 2649 : return optional_flag;
40 : : }
41 : :
42 : : std::string
43 : 44107 : TraitItemReference::get_identifier () const
44 : : {
45 : 44107 : return identifier;
46 : : }
47 : :
48 : : TraitItemReference::TraitItemType
49 : 51752 : TraitItemReference::get_trait_item_type () const
50 : : {
51 : 51752 : return type;
52 : : }
53 : :
54 : : HIR::TraitItem *
55 : 4757 : TraitItemReference::get_hir_trait_item () const
56 : : {
57 : 4757 : return hir_trait_item;
58 : : }
59 : :
60 : : location_t
61 : 1391 : TraitItemReference::get_locus () const
62 : : {
63 : 1391 : return locus;
64 : : }
65 : :
66 : : const Analysis::NodeMapping
67 : 9823 : TraitItemReference::get_mappings () const
68 : : {
69 : 9823 : return hir_trait_item->get_mappings ();
70 : : }
71 : :
72 : : TyTy::BaseType *
73 : 11336 : TraitItemReference::get_tyty () const
74 : : {
75 : 11336 : rust_assert (hir_trait_item != nullptr);
76 : :
77 : 11336 : switch (type)
78 : : {
79 : 29 : case CONST:
80 : 29 : return get_type_from_constant (
81 : 29 : static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
82 : 5986 : break;
83 : :
84 : 5986 : case TYPE:
85 : 5986 : return get_type_from_typealias (
86 : 5986 : static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
87 : :
88 : 5321 : case FN:
89 : 5321 : return get_type_from_fn (
90 : 5321 : 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 : 0 : TraitItemReference::get_error () const
103 : : {
104 : 0 : return new TyTy::ErrorType (get_mappings ().get_hirid ());
105 : : }
106 : :
107 : 3364 : TraitReference::TraitReference (
108 : : const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
109 : : std::vector<const TraitReference *> super_traits,
110 : 3364 : std::vector<TyTy::SubstitutionParamMapping> substs)
111 : 3364 : : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
112 : 3364 : super_traits (super_traits)
113 : : {
114 : 3364 : trait_substs.clear ();
115 : 3364 : trait_substs.reserve (substs.size ());
116 : 5737 : for (const auto &p : substs)
117 : 2373 : trait_substs.push_back (p.clone ());
118 : 3364 : }
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 : 70255 : TraitReference::is_error () const
147 : : {
148 : 70255 : 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 : 6489 : TraitReference::get_name () const
159 : : {
160 : 6489 : rust_assert (!is_error ());
161 : 6489 : return hir_trait_ref->get_name ().as_string ();
162 : : }
163 : :
164 : : std::string
165 : 1558 : TraitReference::as_string () const
166 : : {
167 : 1558 : if (is_error ())
168 : 0 : return "<trait-ref-error-node>";
169 : :
170 : 1558 : std::string item_buf;
171 : 3910 : for (auto &item : item_refs)
172 : : {
173 : 4704 : item_buf += item.as_string () + ", ";
174 : : }
175 : 3116 : return "HIR Trait: " + get_name () + "->"
176 : 7790 : + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
177 : 1558 : }
178 : :
179 : : const HIR::Trait *
180 : 3689 : TraitReference::get_hir_trait_ref () const
181 : : {
182 : 3689 : return hir_trait_ref;
183 : : }
184 : :
185 : : const Analysis::NodeMapping &
186 : 108466 : TraitReference::get_mappings () const
187 : : {
188 : 108466 : return hir_trait_ref->get_mappings ();
189 : : }
190 : :
191 : : DefId
192 : 131 : TraitReference::get_defid () const
193 : : {
194 : 131 : return get_mappings ().get_defid ();
195 : : }
196 : :
197 : : bool
198 : 116 : TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
199 : : TraitItemReference **ref)
200 : : {
201 : 116 : return lookup_trait_item (item.trait_identifier (), ref);
202 : : }
203 : :
204 : : bool
205 : 1072 : TraitReference::lookup_trait_item (const std::string &ident,
206 : : TraitItemReference **ref)
207 : : {
208 : 1164 : for (auto &item : item_refs)
209 : : {
210 : 1164 : if (ident.compare (item.get_identifier ()) == 0)
211 : : {
212 : 1072 : *ref = &item;
213 : 1072 : return true;
214 : : }
215 : : }
216 : : return false;
217 : : }
218 : :
219 : : bool
220 : 89 : TraitReference::lookup_trait_item_by_type (
221 : : const std::string &ident, TraitItemReference::TraitItemType type,
222 : : TraitItemReference **ref)
223 : : {
224 : 89 : for (auto &item : item_refs)
225 : : {
226 : 89 : if (item.get_trait_item_type () != type)
227 : 0 : continue;
228 : :
229 : 89 : if (ident.compare (item.get_identifier ()) == 0)
230 : : {
231 : 89 : *ref = &item;
232 : 89 : return true;
233 : : }
234 : : }
235 : : return false;
236 : : }
237 : :
238 : : bool
239 : 2465 : TraitReference::lookup_trait_item_by_type (
240 : : const std::string &ident, TraitItemReference::TraitItemType type,
241 : : const TraitItemReference **ref) const
242 : : {
243 : 3567 : for (auto &item : item_refs)
244 : : {
245 : 3564 : if (item.get_trait_item_type () != type)
246 : 787 : continue;
247 : :
248 : 2777 : if (ident.compare (item.get_identifier ()) == 0)
249 : : {
250 : 2462 : *ref = &item;
251 : 2462 : 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 : 6163 : TraitReference::lookup_trait_item (const std::string &ident,
266 : : const TraitItemReference **ref) const
267 : : {
268 : 8081 : for (auto &item : item_refs)
269 : : {
270 : 7463 : if (ident.compare (item.get_identifier ()) == 0)
271 : : {
272 : 5545 : *ref = &item;
273 : 5545 : return true;
274 : : }
275 : : }
276 : :
277 : : // lookup super traits
278 : 626 : for (const auto &super_trait : super_traits)
279 : : {
280 : 50 : bool found = super_trait->lookup_trait_item (ident, ref);
281 : 50 : if (found)
282 : 5587 : return true;
283 : : }
284 : :
285 : : return false;
286 : : }
287 : :
288 : : const TraitItemReference *
289 : 30670 : TraitReference::lookup_trait_item (const std::string &ident,
290 : : TraitItemReference::TraitItemType type) const
291 : : {
292 : 63187 : for (auto &item : item_refs)
293 : : {
294 : 34013 : if (item.get_trait_item_type () != type)
295 : 6866 : continue;
296 : :
297 : 27147 : if (ident.compare (item.get_identifier ()) == 0)
298 : 30670 : return &item;
299 : : }
300 : :
301 : : // lookup super traits
302 : 42738 : for (const auto &super_trait : super_traits)
303 : : {
304 : 14250 : const TraitItemReference *res
305 : 14250 : = super_trait->lookup_trait_item (ident, type);
306 : 14250 : if (!res->is_error ())
307 : 30670 : return res;
308 : : }
309 : :
310 : 28488 : return &TraitItemReference::error_node ();
311 : : }
312 : :
313 : : size_t
314 : 2318 : TraitReference::size () const
315 : : {
316 : 2318 : return item_refs.size ();
317 : : }
318 : :
319 : : const std::vector<TraitItemReference> &
320 : 939 : TraitReference::get_trait_items () const
321 : : {
322 : 939 : return item_refs;
323 : : }
324 : :
325 : : void
326 : 489 : TraitReference::get_trait_items_and_supers (
327 : : std::vector<const TraitItemReference *> &result) const
328 : : {
329 : 1039 : for (const auto &item : item_refs)
330 : 550 : result.push_back (&item);
331 : :
332 : 489 : for (const auto &super_trait : super_traits)
333 : 0 : super_trait->get_trait_items_and_supers (result);
334 : 489 : }
335 : :
336 : : void
337 : 2074 : TraitReference::on_resolved ()
338 : : {
339 : 3595 : for (auto &item : item_refs)
340 : : {
341 : 1521 : item.on_resolved ();
342 : : }
343 : 2074 : }
344 : :
345 : : void
346 : 2318 : TraitReference::clear_associated_types () const
347 : : {
348 : 5534 : for (const auto &item : item_refs)
349 : : {
350 : 3216 : bool is_assoc_type = item.get_trait_item_type ()
351 : 3216 : == TraitItemReference::TraitItemType::TYPE;
352 : 3216 : if (is_assoc_type)
353 : 711 : item.associated_type_reset (false);
354 : : }
355 : 2318 : }
356 : :
357 : : void
358 : 1410 : TraitReference::clear_associated_type_projections () const
359 : : {
360 : 2325 : for (const auto &item : item_refs)
361 : : {
362 : 915 : bool is_assoc_type = item.get_trait_item_type ()
363 : 915 : == TraitItemReference::TraitItemType::TYPE;
364 : 915 : if (is_assoc_type)
365 : 176 : item.associated_type_reset (true);
366 : : }
367 : 1410 : }
368 : :
369 : : bool
370 : 46997 : TraitReference::is_equal (const TraitReference &other) const
371 : : {
372 : 46997 : DefId this_id = get_mappings ().get_defid ();
373 : 46997 : DefId other_id = other.get_mappings ().get_defid ();
374 : 46997 : return this_id == other_id;
375 : : }
376 : :
377 : : const std::vector<const TraitReference *>
378 : 0 : TraitReference::get_super_traits () const
379 : : {
380 : 0 : return super_traits;
381 : : }
382 : :
383 : : bool
384 : 111 : TraitReference::is_object_safe (bool emit_error, location_t locus) const
385 : : {
386 : : // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
387 : 111 : std::vector<const TraitReference *> non_object_super_traits;
388 : 112 : for (auto &item : super_traits)
389 : : {
390 : 1 : if (!item->is_object_safe (false, UNDEF_LOCATION))
391 : 1 : non_object_super_traits.push_back (item);
392 : : }
393 : :
394 : 111 : std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
395 : 239 : for (auto &item : get_trait_items ())
396 : : {
397 : 128 : if (!item.is_object_safe ())
398 : 4 : non_object_safe_items.push_back (&item);
399 : : }
400 : :
401 : 111 : bool is_safe
402 : 111 : = non_object_super_traits.empty () && non_object_safe_items.empty ();
403 : 111 : if (emit_error && !is_safe)
404 : : {
405 : 2 : rich_location r (line_table, locus);
406 : 3 : for (auto &item : non_object_super_traits)
407 : 1 : r.add_range (item->get_locus ());
408 : 4 : for (auto &item : non_object_safe_items)
409 : 2 : r.add_range (item->get_locus ());
410 : :
411 : 2 : rust_error_at (r, "trait bound is not object safe");
412 : 2 : }
413 : :
414 : 111 : return is_safe;
415 : 111 : }
416 : :
417 : : bool
418 : 0 : TraitReference::trait_has_generics () const
419 : : {
420 : 0 : return !trait_substs.empty ();
421 : : }
422 : :
423 : : std::vector<TyTy::SubstitutionParamMapping>
424 : 23516 : TraitReference::get_trait_substs () const
425 : : {
426 : 23516 : return trait_substs;
427 : : }
428 : :
429 : : bool
430 : 22472 : TraitReference::satisfies_bound (const TraitReference &reference) const
431 : : {
432 : 22472 : if (is_equal (reference))
433 : : return true;
434 : :
435 : 9626 : for (const auto &super_trait : super_traits)
436 : : {
437 : 3088 : if (super_trait->satisfies_bound (reference))
438 : 15934 : return true;
439 : : }
440 : :
441 : : return false;
442 : : }
443 : :
444 : 2318 : AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
445 : : TyTy::TypeBoundPredicate predicate,
446 : : HIR::ImplBlock *impl,
447 : : TyTy::BaseType *self,
448 : 2318 : Resolver::TypeCheckContext *context)
449 : 2318 : : trait (trait), predicate (predicate), impl (impl), self (self),
450 : 2318 : context (context)
451 : 2318 : {}
452 : :
453 : : TyTy::TypeBoundPredicate &
454 : 6983 : AssociatedImplTrait::get_predicate ()
455 : : {
456 : 6983 : return predicate;
457 : : }
458 : :
459 : : HIR::ImplBlock *
460 : 2322 : AssociatedImplTrait::get_impl_block ()
461 : : {
462 : 2322 : return impl;
463 : : }
464 : :
465 : : TyTy::BaseType *
466 : 1026 : AssociatedImplTrait::get_self ()
467 : : {
468 : 1026 : return self;
469 : : }
470 : :
471 : : const TyTy::BaseType *
472 : 0 : AssociatedImplTrait::get_self () const
473 : : {
474 : 0 : return self;
475 : : }
476 : :
477 : : } // namespace Resolver
478 : : } // namespace Rust
|