1 // Copyright (C) 2020-2025 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 #ifndef RUST_AST_TYPE_H
20 #define RUST_AST_TYPE_H
23 #include "rust-path.h"
27 // definitions moved to rust-ast.h
32 class TraitBound
: public TypeParamBound
35 bool opening_question_mark
;
37 // bool has_for_lifetimes;
38 // LifetimeParams for_lifetimes;
39 std::vector
<LifetimeParam
> for_lifetimes
; // inlined LifetimeParams
46 // Returns whether trait bound has "for" lifetimes
47 bool has_for_lifetimes () const { return !for_lifetimes
.empty (); }
49 std::vector
<LifetimeParam
> &get_for_lifetimes () { return for_lifetimes
; }
51 const std::vector
<LifetimeParam
> &get_for_lifetimes () const
56 TraitBound (TypePath type_path
, location_t locus
, bool in_parens
= false,
57 bool opening_question_mark
= false,
58 std::vector
<LifetimeParam
> for_lifetimes
59 = std::vector
<LifetimeParam
> ())
60 : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
61 in_parens (in_parens
), opening_question_mark (opening_question_mark
),
62 for_lifetimes (std::move (for_lifetimes
)),
63 type_path (std::move (type_path
)), locus (locus
)
66 TraitBound (NodeId id
, TypePath type_path
, location_t locus
,
67 bool in_parens
= false, bool opening_question_mark
= false,
68 std::vector
<LifetimeParam
> for_lifetimes
69 = std::vector
<LifetimeParam
> ())
70 : TypeParamBound (id
), in_parens (in_parens
),
71 opening_question_mark (opening_question_mark
),
72 for_lifetimes (std::move (for_lifetimes
)),
73 type_path (std::move (type_path
)), locus (locus
)
76 std::string
as_string () const override
;
78 location_t
get_locus () const override final
{ return locus
; }
80 void accept_vis (ASTVisitor
&vis
) override
;
82 // TODO: this mutable getter seems kinda dodgy
83 TypePath
&get_type_path () { return type_path
; }
84 const TypePath
&get_type_path () const { return type_path
; }
86 bool is_in_parens () const { return in_parens
; }
87 bool has_opening_question_mark () const { return opening_question_mark
; }
89 TypeParamBoundType
get_bound_type () const override
91 return TypeParamBound::TypeParamBoundType::TRAIT
;
95 /* Use covariance to implement clone function as returning this object rather
97 TraitBound
*clone_type_param_bound_impl () const override
99 return new TraitBound (node_id
, type_path
, locus
, in_parens
,
100 opening_question_mark
, for_lifetimes
);
104 // definition moved to rust-ast.h
107 // An impl trait? Poor reference material here.
108 class ImplTraitType
: public Type
110 // TypeParamBounds type_param_bounds;
112 std::vector
<std::unique_ptr
<TypeParamBound
> > type_param_bounds
;
117 /* Use covariance to implement clone function as returning this object rather
119 ImplTraitType
*clone_type_impl () const override
121 return new ImplTraitType (*this);
126 std::vector
<std::unique_ptr
<TypeParamBound
> > type_param_bounds
,
128 : type_param_bounds (std::move (type_param_bounds
)), locus (locus
)
131 // copy constructor with vector clone
132 ImplTraitType (ImplTraitType
const &other
) : locus (other
.locus
)
134 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
135 for (const auto &e
: other
.type_param_bounds
)
136 type_param_bounds
.push_back (e
->clone_type_param_bound ());
139 // overloaded assignment operator to clone
140 ImplTraitType
&operator= (ImplTraitType
const &other
)
144 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
145 for (const auto &e
: other
.type_param_bounds
)
146 type_param_bounds
.push_back (e
->clone_type_param_bound ());
152 ImplTraitType (ImplTraitType
&&other
) = default;
153 ImplTraitType
&operator= (ImplTraitType
&&other
) = default;
155 std::string
as_string () const override
;
157 location_t
get_locus () const override final
{ return locus
; }
159 void accept_vis (ASTVisitor
&vis
) override
;
161 // TODO: mutable getter seems kinda dodgy
162 std::vector
<std::unique_ptr
<TypeParamBound
> > &get_type_param_bounds ()
164 return type_param_bounds
;
166 const std::vector
<std::unique_ptr
<TypeParamBound
> > &
167 get_type_param_bounds () const
169 return type_param_bounds
;
173 // An opaque value of another type that implements a set of traits
174 class TraitObjectType
: public Type
177 std::vector
<std::unique_ptr
<TypeParamBound
> > type_param_bounds
;
181 /* Use covariance to implement clone function as returning this object rather
183 TraitObjectType
*clone_type_impl () const override
185 return new TraitObjectType (*this);
190 std::vector
<std::unique_ptr
<TypeParamBound
> > type_param_bounds
,
191 location_t locus
, bool is_dyn_dispatch
)
192 : has_dyn (is_dyn_dispatch
),
193 type_param_bounds (std::move (type_param_bounds
)), locus (locus
)
196 // copy constructor with vector clone
197 TraitObjectType (TraitObjectType
const &other
)
198 : has_dyn (other
.has_dyn
), locus (other
.locus
)
200 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
201 for (const auto &e
: other
.type_param_bounds
)
202 type_param_bounds
.push_back (e
->clone_type_param_bound ());
205 // overloaded assignment operator to clone
206 TraitObjectType
&operator= (TraitObjectType
const &other
)
208 has_dyn
= other
.has_dyn
;
210 type_param_bounds
.reserve (other
.type_param_bounds
.size ());
211 for (const auto &e
: other
.type_param_bounds
)
212 type_param_bounds
.push_back (e
->clone_type_param_bound ());
218 TraitObjectType (TraitObjectType
&&other
) = default;
219 TraitObjectType
&operator= (TraitObjectType
&&other
) = default;
221 std::string
as_string () const override
;
223 location_t
get_locus () const override final
{ return locus
; }
225 void accept_vis (ASTVisitor
&vis
) override
;
227 bool is_dyn () const { return has_dyn
; }
229 // TODO: mutable getter seems kinda dodgy
230 std::vector
<std::unique_ptr
<TypeParamBound
> > &get_type_param_bounds ()
232 return type_param_bounds
;
234 const std::vector
<std::unique_ptr
<TypeParamBound
> > &
235 get_type_param_bounds () const
237 return type_param_bounds
;
241 // A type with parentheses around it, used to avoid ambiguity.
242 class ParenthesisedType
: public TypeNoBounds
244 std::unique_ptr
<Type
> type_in_parens
;
248 /* Use covariance to implement clone function as returning this object rather
250 ParenthesisedType
*clone_type_no_bounds_impl () const override
252 return new ParenthesisedType (*this);
256 // Constructor uses Type pointer for polymorphism
257 ParenthesisedType (std::unique_ptr
<Type
> type_inside_parens
, location_t locus
)
258 : type_in_parens (std::move (type_inside_parens
)), locus (locus
)
261 /* Copy constructor uses custom deep copy method for type to preserve
263 ParenthesisedType (ParenthesisedType
const &other
)
264 : type_in_parens (other
.type_in_parens
->clone_type ()), locus (other
.locus
)
267 // overload assignment operator to use custom clone method
268 ParenthesisedType
&operator= (ParenthesisedType
const &other
)
270 type_in_parens
= other
.type_in_parens
->clone_type ();
275 // default move semantics
276 ParenthesisedType (ParenthesisedType
&&other
) = default;
277 ParenthesisedType
&operator= (ParenthesisedType
&&other
) = default;
279 std::string
as_string () const override
281 return "(" + type_in_parens
->as_string () + ")";
284 // Creates a trait bound (clone of this one's trait bound) - HACK
285 TraitBound
*to_trait_bound (bool) const override
287 /* NOTE: obviously it is unknown whether the internal type is a trait bound
288 * due to polymorphism, so just let the internal type handle it. As
289 * parenthesised type, it must be in parentheses. */
290 return type_in_parens
->to_trait_bound (true);
293 location_t
get_locus () const override final
{ return locus
; }
295 void accept_vis (ASTVisitor
&vis
) override
;
297 // TODO: would a "vis_type" be better?
298 std::unique_ptr
<Type
> &get_type_in_parens ()
300 rust_assert (type_in_parens
!= nullptr);
301 return type_in_parens
;
305 // Impl trait with a single bound? Poor reference material here.
306 class ImplTraitTypeOneBound
: public TypeNoBounds
308 TraitBound trait_bound
;
312 /* Use covariance to implement clone function as returning this object rather
314 ImplTraitTypeOneBound
*clone_type_no_bounds_impl () const override
316 return new ImplTraitTypeOneBound (*this);
320 ImplTraitTypeOneBound (TraitBound trait_bound
, location_t locus
)
321 : trait_bound (std::move (trait_bound
)), locus (locus
)
324 std::string
as_string () const override
;
326 location_t
get_locus () const override final
{ return locus
; }
328 void accept_vis (ASTVisitor
&vis
) override
;
330 // TODO: would a "vis_type" be better?
331 TraitBound
&get_trait_bound ()
333 // TODO: check to ensure invariants are met?
338 /* A trait object with a single trait bound. The "trait bound" is really just
339 * the trait. Basically like using an interface as a type in an OOP language. */
340 class TraitObjectTypeOneBound
: public TypeNoBounds
343 TraitBound trait_bound
;
347 /* Use covariance to implement clone function as returning this object rather
349 TraitObjectTypeOneBound
*clone_type_no_bounds_impl () const override
351 return new TraitObjectTypeOneBound (*this);
355 TraitObjectTypeOneBound (TraitBound trait_bound
, location_t locus
,
356 bool is_dyn_dispatch
= false)
357 : has_dyn (is_dyn_dispatch
), trait_bound (std::move (trait_bound
)),
361 std::string
as_string () const override
;
363 // Creates a trait bound (clone of this one's trait bound) - HACK
364 TraitBound
*to_trait_bound (bool) const override
366 /* NOTE: this assumes there is no dynamic dispatch specified- if there was,
367 * this cloning would not be required as parsing is unambiguous. */
368 return new TraitBound (trait_bound
);
371 location_t
get_locus () const override final
{ return locus
; }
373 void accept_vis (ASTVisitor
&vis
) override
;
375 // TODO: would a "vis_type" be better?
376 TraitBound
&get_trait_bound ()
378 // TODO: check to ensure invariants are met?
382 bool is_dyn () const { return has_dyn
; }
385 class TypePath
; // definition moved to "rust-path.h"
387 /* A type consisting of the "product" of others (the tuple's elements) in a
389 class TupleType
: public TypeNoBounds
391 std::vector
<std::unique_ptr
<Type
> > elems
;
395 // Returns whether the tuple type is the unit type, i.e. has no elements.
396 bool is_unit_type () const { return elems
.empty (); }
398 TupleType (std::vector
<std::unique_ptr
<Type
> > elems
, location_t locus
)
399 : elems (std::move (elems
)), locus (locus
)
402 // copy constructor with vector clone
403 TupleType (TupleType
const &other
) : locus (other
.locus
)
405 elems
.reserve (other
.elems
.size ());
406 for (const auto &e
: other
.elems
)
407 elems
.push_back (e
->clone_type ());
410 // overloaded assignment operator to clone
411 TupleType
&operator= (TupleType
const &other
)
415 elems
.reserve (other
.elems
.size ());
416 for (const auto &e
: other
.elems
)
417 elems
.push_back (e
->clone_type ());
423 TupleType (TupleType
&&other
) = default;
424 TupleType
&operator= (TupleType
&&other
) = default;
426 std::string
as_string () const override
;
428 location_t
get_locus () const override final
{ return locus
; }
430 void accept_vis (ASTVisitor
&vis
) override
;
432 // TODO: mutable getter seems kinda dodgy
433 std::vector
<std::unique_ptr
<Type
> > &get_elems () { return elems
; }
434 const std::vector
<std::unique_ptr
<Type
> > &get_elems () const
440 /* Use covariance to implement clone function as returning this object rather
442 TupleType
*clone_type_no_bounds_impl () const override
444 return new TupleType (*this);
448 /* A type with no values, representing the result of computations that never
449 * complete. Expressions of NeverType can be coerced into any other types.
450 * Represented as "!". */
451 class NeverType
: public TypeNoBounds
456 /* Use covariance to implement clone function as returning this object rather
458 NeverType
*clone_type_no_bounds_impl () const override
460 return new NeverType (*this);
464 NeverType (location_t locus
) : locus (locus
) {}
466 std::string
as_string () const override
{ return "! (never type)"; }
468 location_t
get_locus () const override final
{ return locus
; }
470 void accept_vis (ASTVisitor
&vis
) override
;
473 // A type consisting of a pointer without safety or liveness guarantees
474 class RawPointerType
: public TypeNoBounds
484 PointerType pointer_type
;
485 std::unique_ptr
<TypeNoBounds
> type
;
489 // Returns whether the pointer is mutable or constant.
490 PointerType
get_pointer_type () const { return pointer_type
; }
492 // Constructor requires pointer for polymorphism reasons
493 RawPointerType (PointerType pointer_type
,
494 std::unique_ptr
<TypeNoBounds
> type_no_bounds
,
496 : pointer_type (pointer_type
), type (std::move (type_no_bounds
)),
500 // Copy constructor calls custom polymorphic clone function
501 RawPointerType (RawPointerType
const &other
)
502 : pointer_type (other
.pointer_type
),
503 type (other
.type
->clone_type_no_bounds ()), locus (other
.locus
)
506 // overload assignment operator to use custom clone method
507 RawPointerType
&operator= (RawPointerType
const &other
)
509 pointer_type
= other
.pointer_type
;
510 type
= other
.type
->clone_type_no_bounds ();
515 // default move semantics
516 RawPointerType (RawPointerType
&&other
) = default;
517 RawPointerType
&operator= (RawPointerType
&&other
) = default;
519 std::string
as_string () const override
;
521 location_t
get_locus () const override final
{ return locus
; }
523 void accept_vis (ASTVisitor
&vis
) override
;
525 // TODO: would a "vis_type" be better?
526 TypeNoBounds
&get_type_pointed_to ()
528 rust_assert (type
!= nullptr);
533 /* Use covariance to implement clone function as returning this object rather
535 RawPointerType
*clone_type_no_bounds_impl () const override
537 return new RawPointerType (*this);
541 // A type pointing to memory owned by another value
542 class ReferenceType
: public TypeNoBounds
544 // bool has_lifetime; // TODO: handle in lifetime or something?
545 tl::optional
<Lifetime
> lifetime
;
548 std::unique_ptr
<TypeNoBounds
> type
;
552 // Returns whether the reference is mutable or immutable.
553 bool is_mut () const { return has_mut
; }
555 // Returns whether the reference has a lifetime.
556 bool has_lifetime () const { return lifetime
.has_value (); }
559 ReferenceType (bool is_mut
, std::unique_ptr
<TypeNoBounds
> type_no_bounds
,
561 tl::optional
<Lifetime
> lifetime
= Lifetime::elided ())
562 : lifetime (std::move (lifetime
)), has_mut (is_mut
),
563 type (std::move (type_no_bounds
)), locus (locus
)
566 // Copy constructor with custom clone method
567 ReferenceType (ReferenceType
const &other
)
568 : lifetime (other
.lifetime
), has_mut (other
.has_mut
),
569 type (other
.type
->clone_type_no_bounds ()), locus (other
.locus
)
572 // Operator overload assignment operator to custom clone the unique pointer
573 ReferenceType
&operator= (ReferenceType
const &other
)
575 lifetime
= other
.lifetime
;
576 has_mut
= other
.has_mut
;
577 type
= other
.type
->clone_type_no_bounds ();
584 ReferenceType (ReferenceType
&&other
) = default;
585 ReferenceType
&operator= (ReferenceType
&&other
) = default;
587 std::string
as_string () const override
;
589 location_t
get_locus () const override final
{ return locus
; }
591 void accept_vis (ASTVisitor
&vis
) override
;
593 // TODO: would a "vis_type" be better?
594 TypeNoBounds
&get_type_referenced ()
596 rust_assert (type
!= nullptr);
600 bool get_has_mut () const { return has_mut
; }
602 Lifetime
&get_lifetime () { return lifetime
.value (); }
603 const Lifetime
&get_lifetime () const { return lifetime
.value (); }
605 TypeNoBounds
&get_base_type () { return *type
; }
608 /* Use covariance to implement clone function as returning this object rather
610 ReferenceType
*clone_type_no_bounds_impl () const override
612 return new ReferenceType (*this);
616 // A fixed-size sequence of elements of a specified type
617 class ArrayType
: public TypeNoBounds
619 std::unique_ptr
<Type
> elem_type
;
620 std::unique_ptr
<Expr
> size
;
624 // Constructor requires pointers for polymorphism
625 ArrayType (std::unique_ptr
<Type
> type
, std::unique_ptr
<Expr
> array_size
,
627 : elem_type (std::move (type
)), size (std::move (array_size
)), locus (locus
)
630 // Copy constructor requires deep copies of both unique pointers
631 ArrayType (ArrayType
const &other
)
632 : elem_type (other
.elem_type
->clone_type ()),
633 size (other
.size
->clone_expr ()), locus (other
.locus
)
636 // Overload assignment operator to deep copy pointers
637 ArrayType
&operator= (ArrayType
const &other
)
639 elem_type
= other
.elem_type
->clone_type ();
640 size
= other
.size
->clone_expr ();
646 ArrayType (ArrayType
&&other
) = default;
647 ArrayType
&operator= (ArrayType
&&other
) = default;
649 std::string
as_string () const override
;
651 location_t
get_locus () const override final
{ return locus
; }
653 void accept_vis (ASTVisitor
&vis
) override
;
655 // TODO: would a "vis_type" be better?
656 Type
&get_elem_type ()
658 rust_assert (elem_type
!= nullptr);
662 // TODO: would a "vis_expr" be better?
663 Expr
&get_size_expr ()
665 rust_assert (size
!= nullptr);
670 /* Use covariance to implement clone function as returning this object rather
672 ArrayType
*clone_type_no_bounds_impl () const override
674 return new ArrayType (*this);
678 /* A dynamically-sized type representing a "view" into a sequence of elements of
680 class SliceType
: public TypeNoBounds
682 std::unique_ptr
<Type
> elem_type
;
686 // Constructor requires pointer for polymorphism
687 SliceType (std::unique_ptr
<Type
> type
, location_t locus
)
688 : elem_type (std::move (type
)), locus (locus
)
691 // Copy constructor requires deep copy of Type smart pointer
692 SliceType (SliceType
const &other
)
693 : elem_type (other
.elem_type
->clone_type ()), locus (other
.locus
)
696 // Overload assignment operator to deep copy
697 SliceType
&operator= (SliceType
const &other
)
699 elem_type
= other
.elem_type
->clone_type ();
706 SliceType (SliceType
&&other
) = default;
707 SliceType
&operator= (SliceType
&&other
) = default;
709 std::string
as_string () const override
;
711 location_t
get_locus () const override final
{ return locus
; }
713 void accept_vis (ASTVisitor
&vis
) override
;
715 // TODO: would a "vis_type" be better?
716 Type
&get_elem_type ()
718 rust_assert (elem_type
!= nullptr);
723 /* Use covariance to implement clone function as returning this object rather
725 SliceType
*clone_type_no_bounds_impl () const override
727 return new SliceType (*this);
731 /* Type used in generic arguments to explicitly request type inference (wildcard
733 class InferredType
: public TypeNoBounds
737 // e.g. Vec<_> = whatever
739 /* Use covariance to implement clone function as returning this object rather
741 InferredType
*clone_type_no_bounds_impl () const override
743 return new InferredType (*this);
747 InferredType (location_t locus
) : locus (locus
) {}
749 std::string
as_string () const override
;
751 location_t
get_locus () const override final
{ return locus
; }
753 void accept_vis (ASTVisitor
&vis
) override
;
756 class QualifiedPathInType
; // definition moved to "rust-path.h"
758 // A possibly named param used in a BaseFunctionType
759 struct MaybeNamedParam
770 std::vector
<Attribute
> outer_attrs
;
772 std::unique_ptr
<Type
> param_type
;
774 ParamKind param_kind
;
775 Identifier name
; // technically, can be an identifier or '_'
780 MaybeNamedParam (Identifier name
, ParamKind param_kind
,
781 std::unique_ptr
<Type
> param_type
,
782 std::vector
<Attribute
> outer_attrs
, location_t locus
)
783 : outer_attrs (std::move (outer_attrs
)),
784 param_type (std::move (param_type
)), param_kind (param_kind
),
785 name (std::move (name
)), locus (locus
)
788 // Copy constructor with clone
789 MaybeNamedParam (MaybeNamedParam
const &other
)
790 : outer_attrs (other
.outer_attrs
), param_kind (other
.param_kind
),
791 name (other
.name
), locus (other
.locus
)
793 // guard to prevent null dereference
794 if (other
.param_type
!= nullptr)
795 param_type
= other
.param_type
->clone_type ();
798 ~MaybeNamedParam () = default;
800 // Overloaded assignment operator with clone
801 MaybeNamedParam
&operator= (MaybeNamedParam
const &other
)
803 outer_attrs
= other
.outer_attrs
;
805 param_kind
= other
.param_kind
;
808 // guard to prevent null dereference
809 if (other
.param_type
!= nullptr)
810 param_type
= other
.param_type
->clone_type ();
812 param_type
= nullptr;
818 MaybeNamedParam (MaybeNamedParam
&&other
) = default;
819 MaybeNamedParam
&operator= (MaybeNamedParam
&&other
) = default;
821 std::string
as_string () const;
823 // Returns whether the param is in an error state.
824 bool is_error () const { return param_type
== nullptr; }
826 // Creates an error state param.
827 static MaybeNamedParam
create_error ()
829 return MaybeNamedParam ({""}, UNNAMED
, nullptr, {}, UNDEF_LOCATION
);
832 location_t
get_locus () const { return locus
; }
834 // TODO: this mutable getter seems really dodgy. Think up better way.
835 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
836 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
838 // TODO: would a "vis_type" be better?
841 rust_assert (param_type
!= nullptr);
845 std::unique_ptr
<Type
> &get_type_ptr ()
847 rust_assert (param_type
!= nullptr);
851 ParamKind
get_param_kind () const { return param_kind
; }
853 Identifier
get_name () const { return name
; }
856 /* A function pointer type - can be created via coercion from function items and
857 * non-capturing closures. */
858 class BareFunctionType
: public TypeNoBounds
860 // bool has_for_lifetimes;
861 // ForLifetimes for_lifetimes;
862 std::vector
<LifetimeParam
> for_lifetimes
; // inlined version
864 FunctionQualifiers function_qualifiers
;
865 std::vector
<MaybeNamedParam
> params
;
867 std::vector
<Attribute
> variadic_attrs
;
869 // bool has_return_type;
870 // BareFunctionReturnType return_type;
871 std::unique_ptr
<TypeNoBounds
> return_type
; // inlined version
876 // Whether a return type is defined with the function.
877 bool has_return_type () const { return return_type
!= nullptr; }
879 // Whether the function has ForLifetimes.
880 bool has_for_lifetimes () const { return !for_lifetimes
.empty (); }
882 std::vector
<LifetimeParam
> &get_for_lifetimes () { return for_lifetimes
; }
884 bool is_variadic () const { return _is_variadic
; }
886 std::vector
<Attribute
> &get_variadic_attr () { return variadic_attrs
; };
887 const std::vector
<Attribute
> &get_variadic_attr () const
889 return variadic_attrs
;
892 BareFunctionType (std::vector
<LifetimeParam
> lifetime_params
,
893 FunctionQualifiers qualifiers
,
894 std::vector
<MaybeNamedParam
> named_params
, bool is_variadic
,
895 std::vector
<Attribute
> variadic_attrs
,
896 std::unique_ptr
<TypeNoBounds
> type
, location_t locus
)
897 : for_lifetimes (std::move (lifetime_params
)),
898 function_qualifiers (std::move (qualifiers
)),
899 params (std::move (named_params
)), _is_variadic (is_variadic
),
900 variadic_attrs (std::move (variadic_attrs
)),
901 return_type (std::move (type
)), locus (locus
)
903 if (!variadic_attrs
.empty ())
907 // Copy constructor with clone
908 BareFunctionType (BareFunctionType
const &other
)
909 : for_lifetimes (other
.for_lifetimes
),
910 function_qualifiers (other
.function_qualifiers
), params (other
.params
),
911 _is_variadic (other
._is_variadic
), variadic_attrs (other
.variadic_attrs
),
914 // guard to prevent null dereference
915 if (other
.return_type
!= nullptr)
916 return_type
= other
.return_type
->clone_type_no_bounds ();
919 // Overload assignment operator to deep copy
920 BareFunctionType
&operator= (BareFunctionType
const &other
)
922 for_lifetimes
= other
.for_lifetimes
;
923 function_qualifiers
= other
.function_qualifiers
;
924 params
= other
.params
;
925 _is_variadic
= other
._is_variadic
;
926 variadic_attrs
= other
.variadic_attrs
;
929 // guard to prevent null dereference
930 if (other
.return_type
!= nullptr)
931 return_type
= other
.return_type
->clone_type_no_bounds ();
933 return_type
= nullptr;
939 BareFunctionType (BareFunctionType
&&other
) = default;
940 BareFunctionType
&operator= (BareFunctionType
&&other
) = default;
942 std::string
as_string () const override
;
944 location_t
get_locus () const override final
{ return locus
; }
946 void accept_vis (ASTVisitor
&vis
) override
;
948 // TODO: this mutable getter seems kinda dodgy
949 std::vector
<MaybeNamedParam
> &get_function_params () { return params
; }
950 const std::vector
<MaybeNamedParam
> &get_function_params () const
955 // TODO: would a "vis_type" be better?
956 TypeNoBounds
&get_return_type ()
958 rust_assert (has_return_type ());
962 FunctionQualifiers
&get_function_qualifiers () { return function_qualifiers
; }
965 /* Use covariance to implement clone function as returning this object rather
967 BareFunctionType
*clone_type_no_bounds_impl () const override
969 return new BareFunctionType (*this);
973 // Forward decl - defined in rust-macro.h
974 class MacroInvocation
;
976 /* TODO: possible types
978 * "enum" (tagged union) type?
980 * function item type?
981 * closure expression types?
982 * primitive types (bool, int, float, char, str (the slice))
983 * Although supposedly TypePaths are used to reference these types (including
986 /* FIXME: Incomplete spec references:
987 * anonymous type parameters, aka "impl Trait in argument position" - impl then
988 * trait bounds abstract return types, aka "impl Trait in return position" -
989 * impl then trait bounds */