Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / rust / typecheck / rust-hir-trait-reference.cc
bloba1229adc06c5ff361db576be6c92a1d9d4c8d98f
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #include "rust-hir-trait-reference.h"
21 namespace Rust {
22 namespace Resolver {
24 std::string
25 TraitItemReference::as_string () const
27 return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
30 bool
31 TraitItemReference::is_error () const
33 return type == ERROR;
36 bool
37 TraitItemReference::is_optional () const
39 return optional_flag;
42 std::string
43 TraitItemReference::get_identifier () const
45 return identifier;
48 TraitItemReference::TraitItemType
49 TraitItemReference::get_trait_item_type () const
51 return type;
54 HIR::TraitItem *
55 TraitItemReference::get_hir_trait_item () const
57 return hir_trait_item;
60 Location
61 TraitItemReference::get_locus () const
63 return locus;
66 const Analysis::NodeMapping
67 TraitItemReference::get_mappings () const
69 return hir_trait_item->get_mappings ();
72 TyTy::BaseType *
73 TraitItemReference::get_tyty () const
75 rust_assert (hir_trait_item != nullptr);
77 switch (type)
79 case CONST:
80 return get_type_from_constant (
81 static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
82 break;
84 case TYPE:
85 return get_type_from_typealias (
86 static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
88 case FN:
89 return get_type_from_fn (
90 static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
91 break;
93 default:
94 return get_error ();
97 gcc_unreachable ();
98 return get_error ();
101 TyTy::ErrorType *
102 TraitItemReference::get_error () const
104 return new TyTy::ErrorType (get_mappings ().get_hirid ());
107 TraitReference::TraitReference (
108 const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
109 std::vector<const TraitReference *> super_traits,
110 std::vector<TyTy::SubstitutionParamMapping> substs)
111 : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
112 super_traits (super_traits)
114 trait_substs.clear ();
115 trait_substs.reserve (substs.size ());
116 for (const auto &p : substs)
117 trait_substs.push_back (p.clone ());
120 TraitReference::TraitReference (TraitReference const &other)
121 : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
122 super_traits (other.super_traits)
124 trait_substs.clear ();
125 trait_substs.reserve (other.trait_substs.size ());
126 for (const auto &p : other.trait_substs)
127 trait_substs.push_back (p.clone ());
130 TraitReference &
131 TraitReference::operator= (TraitReference const &other)
133 hir_trait_ref = other.hir_trait_ref;
134 item_refs = other.item_refs;
135 super_traits = other.super_traits;
137 trait_substs.clear ();
138 trait_substs.reserve (other.trait_substs.size ());
139 for (const auto &p : other.trait_substs)
140 trait_substs.push_back (p.clone ());
142 return *this;
145 bool
146 TraitReference::is_error () const
148 return hir_trait_ref == nullptr;
151 Location
152 TraitReference::get_locus () const
154 return hir_trait_ref->get_locus ();
157 std::string
158 TraitReference::get_name () const
160 rust_assert (!is_error ());
161 return hir_trait_ref->get_name ();
164 std::string
165 TraitReference::as_string () const
167 if (is_error ())
168 return "<trait-ref-error-node>";
170 std::string item_buf;
171 for (auto &item : item_refs)
173 item_buf += item.as_string () + ", ";
175 return "HIR Trait: " + get_name () + "->"
176 + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
179 const HIR::Trait *
180 TraitReference::get_hir_trait_ref () const
182 return hir_trait_ref;
185 const Analysis::NodeMapping &
186 TraitReference::get_mappings () const
188 return hir_trait_ref->get_mappings ();
191 DefId
192 TraitReference::get_defid () const
194 return get_mappings ().get_defid ();
197 bool
198 TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
199 TraitItemReference **ref)
201 return lookup_trait_item (item.trait_identifier (), ref);
204 bool
205 TraitReference::lookup_trait_item (const std::string &ident,
206 TraitItemReference **ref)
208 for (auto &item : item_refs)
210 if (ident.compare (item.get_identifier ()) == 0)
212 *ref = &item;
213 return true;
216 return false;
219 bool
220 TraitReference::lookup_trait_item_by_type (
221 const std::string &ident, TraitItemReference::TraitItemType type,
222 TraitItemReference **ref)
224 for (auto &item : item_refs)
226 if (item.get_trait_item_type () != type)
227 continue;
229 if (ident.compare (item.get_identifier ()) == 0)
231 *ref = &item;
232 return true;
235 return false;
238 bool
239 TraitReference::lookup_trait_item_by_type (
240 const std::string &ident, TraitItemReference::TraitItemType type,
241 const TraitItemReference **ref) const
243 for (auto &item : item_refs)
245 if (item.get_trait_item_type () != type)
246 continue;
248 if (ident.compare (item.get_identifier ()) == 0)
250 *ref = &item;
251 return true;
254 return false;
257 bool
258 TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
259 const TraitItemReference **ref) const
261 return lookup_trait_item (item.trait_identifier (), ref);
264 bool
265 TraitReference::lookup_trait_item (const std::string &ident,
266 const TraitItemReference **ref) const
268 for (auto &item : item_refs)
270 if (ident.compare (item.get_identifier ()) == 0)
272 *ref = &item;
273 return true;
277 // lookup super traits
278 for (const auto &super_trait : super_traits)
280 bool found = super_trait->lookup_trait_item (ident, ref);
281 if (found)
282 return true;
285 return false;
288 const TraitItemReference *
289 TraitReference::lookup_trait_item (const std::string &ident,
290 TraitItemReference::TraitItemType type) const
292 for (auto &item : item_refs)
294 if (item.get_trait_item_type () != type)
295 continue;
297 if (ident.compare (item.get_identifier ()) == 0)
298 return &item;
301 // lookup super traits
302 for (const auto &super_trait : super_traits)
304 const TraitItemReference *res
305 = super_trait->lookup_trait_item (ident, type);
306 if (!res->is_error ())
307 return res;
310 return &TraitItemReference::error_node ();
313 size_t
314 TraitReference::size () const
316 return item_refs.size ();
319 const std::vector<TraitItemReference> &
320 TraitReference::get_trait_items () const
322 return item_refs;
325 void
326 TraitReference::get_trait_items_and_supers (
327 std::vector<const TraitItemReference *> &result) const
329 for (const auto &item : item_refs)
330 result.push_back (&item);
332 for (const auto &super_trait : super_traits)
333 super_trait->get_trait_items_and_supers (result);
336 void
337 TraitReference::on_resolved ()
339 for (auto &item : item_refs)
341 item.on_resolved ();
345 void
346 TraitReference::clear_associated_types () const
348 for (const auto &item : item_refs)
350 bool is_assoc_type = item.get_trait_item_type ()
351 == TraitItemReference::TraitItemType::TYPE;
352 if (is_assoc_type)
353 item.associated_type_reset (false);
357 void
358 TraitReference::clear_associated_type_projections () const
360 for (const auto &item : item_refs)
362 bool is_assoc_type = item.get_trait_item_type ()
363 == TraitItemReference::TraitItemType::TYPE;
364 if (is_assoc_type)
365 item.associated_type_reset (true);
369 bool
370 TraitReference::is_equal (const TraitReference &other) const
372 DefId this_id = get_mappings ().get_defid ();
373 DefId other_id = other.get_mappings ().get_defid ();
374 return this_id == other_id;
377 const std::vector<const TraitReference *>
378 TraitReference::get_super_traits () const
380 return super_traits;
383 bool
384 TraitReference::is_object_safe (bool emit_error, Location locus) const
386 // https: // doc.rust-lang.org/reference/items/traits.html#object-safety
387 std::vector<const TraitReference *> non_object_super_traits;
388 for (auto &item : super_traits)
390 if (!item->is_object_safe (false, Location ()))
391 non_object_super_traits.push_back (item);
394 std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
395 for (auto &item : get_trait_items ())
397 if (!item.is_object_safe ())
398 non_object_safe_items.push_back (&item);
401 bool is_safe
402 = non_object_super_traits.empty () && non_object_safe_items.empty ();
403 if (emit_error && !is_safe)
405 RichLocation r (locus);
406 for (auto &item : non_object_super_traits)
407 r.add_range (item->get_locus ());
408 for (auto &item : non_object_safe_items)
409 r.add_range (item->get_locus ());
411 rust_error_at (r, "trait bound is not object safe");
414 return is_safe;
417 bool
418 TraitReference::trait_has_generics () const
420 return !trait_substs.empty ();
423 std::vector<TyTy::SubstitutionParamMapping>
424 TraitReference::get_trait_substs () const
426 return trait_substs;
429 bool
430 TraitReference::satisfies_bound (const TraitReference &reference) const
432 if (is_equal (reference))
433 return true;
435 for (const auto &super_trait : super_traits)
437 if (super_trait->satisfies_bound (reference))
438 return true;
441 return false;
444 AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
445 HIR::ImplBlock *impl,
446 TyTy::BaseType *self,
447 Resolver::TypeCheckContext *context)
448 : trait (trait), impl (impl), self (self), context (context)
451 TraitReference *
452 AssociatedImplTrait::get_trait ()
454 return trait;
457 HIR::ImplBlock *
458 AssociatedImplTrait::get_impl_block ()
460 return impl;
463 TyTy::BaseType *
464 AssociatedImplTrait::get_self ()
466 return self;
468 const TyTy::BaseType *
469 AssociatedImplTrait::get_self () const
471 return self;
474 } // namespace Resolver
475 } // namespace Rust