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
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
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"
25 TraitItemReference::as_string () const
27 return "(" + trait_item_type_as_string (type
) + " " + identifier
+ " " + ")";
31 TraitItemReference::is_error () const
37 TraitItemReference::is_optional () const
43 TraitItemReference::get_identifier () const
48 TraitItemReference::TraitItemType
49 TraitItemReference::get_trait_item_type () const
55 TraitItemReference::get_hir_trait_item () const
57 return hir_trait_item
;
61 TraitItemReference::get_locus () const
66 const Analysis::NodeMapping
67 TraitItemReference::get_mappings () const
69 return hir_trait_item
->get_mappings ();
73 TraitItemReference::get_tyty () const
75 rust_assert (hir_trait_item
!= nullptr);
80 return get_type_from_constant (
81 static_cast</*const*/ HIR::TraitItemConst
&> (*hir_trait_item
));
85 return get_type_from_typealias (
86 static_cast</*const*/ HIR::TraitItemType
&> (*hir_trait_item
));
89 return get_type_from_fn (
90 static_cast</*const*/ HIR::TraitItemFunc
&> (*hir_trait_item
));
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 ());
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 ());
146 TraitReference::is_error () const
148 return hir_trait_ref
== nullptr;
152 TraitReference::get_locus () const
154 return hir_trait_ref
->get_locus ();
158 TraitReference::get_name () const
160 rust_assert (!is_error ());
161 return hir_trait_ref
->get_name ();
165 TraitReference::as_string () const
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
+ "]";
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 ();
192 TraitReference::get_defid () const
194 return get_mappings ().get_defid ();
198 TraitReference::lookup_hir_trait_item (const HIR::TraitItem
&item
,
199 TraitItemReference
**ref
)
201 return lookup_trait_item (item
.trait_identifier (), ref
);
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)
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
)
229 if (ident
.compare (item
.get_identifier ()) == 0)
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
)
248 if (ident
.compare (item
.get_identifier ()) == 0)
258 TraitReference::lookup_hir_trait_item (const HIR::TraitItem
&item
,
259 const TraitItemReference
**ref
) const
261 return lookup_trait_item (item
.trait_identifier (), ref
);
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)
277 // lookup super traits
278 for (const auto &super_trait
: super_traits
)
280 bool found
= super_trait
->lookup_trait_item (ident
, ref
);
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
)
297 if (ident
.compare (item
.get_identifier ()) == 0)
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 ())
310 return &TraitItemReference::error_node ();
314 TraitReference::size () const
316 return item_refs
.size ();
319 const std::vector
<TraitItemReference
> &
320 TraitReference::get_trait_items () const
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
);
337 TraitReference::on_resolved ()
339 for (auto &item
: item_refs
)
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
;
353 item
.associated_type_reset (false);
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
;
365 item
.associated_type_reset (true);
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
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
);
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");
418 TraitReference::trait_has_generics () const
420 return !trait_substs
.empty ();
423 std::vector
<TyTy::SubstitutionParamMapping
>
424 TraitReference::get_trait_substs () const
430 TraitReference::satisfies_bound (const TraitReference
&reference
) const
432 if (is_equal (reference
))
435 for (const auto &super_trait
: super_traits
)
437 if (super_trait
->satisfies_bound (reference
))
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
)
452 AssociatedImplTrait::get_trait ()
458 AssociatedImplTrait::get_impl_block ()
464 AssociatedImplTrait::get_self ()
468 const TyTy::BaseType
*
469 AssociatedImplTrait::get_self () const
474 } // namespace Resolver