libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / ast / rust-type.h
blob23572a29a450a9809a8851c653f76e826aea947d
1 // Copyright (C) 2020-2024 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 #ifndef RUST_AST_TYPE_H
20 #define RUST_AST_TYPE_H
22 #include "rust-ast.h"
23 #include "rust-path.h"
25 namespace Rust {
26 namespace AST {
27 // definitions moved to rust-ast.h
28 class TypeParamBound;
29 class Lifetime;
31 // A trait bound
32 class TraitBound : public TypeParamBound
34 bool in_parens;
35 bool opening_question_mark;
37 // bool has_for_lifetimes;
38 // LifetimeParams for_lifetimes;
39 std::vector<LifetimeParam> for_lifetimes; // inlined LifetimeParams
41 TypePath type_path;
43 location_t locus;
45 public:
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 TraitBound (TypePath type_path, location_t locus, bool in_parens = false,
52 bool opening_question_mark = false,
53 std::vector<LifetimeParam> for_lifetimes
54 = std::vector<LifetimeParam> ())
55 : TypeParamBound (Analysis::Mappings::get ()->get_next_node_id ()),
56 in_parens (in_parens), opening_question_mark (opening_question_mark),
57 for_lifetimes (std::move (for_lifetimes)),
58 type_path (std::move (type_path)), locus (locus)
61 TraitBound (NodeId id, TypePath type_path, location_t locus,
62 bool in_parens = false, bool opening_question_mark = false,
63 std::vector<LifetimeParam> for_lifetimes
64 = std::vector<LifetimeParam> ())
65 : TypeParamBound (id), in_parens (in_parens),
66 opening_question_mark (opening_question_mark),
67 for_lifetimes (std::move (for_lifetimes)),
68 type_path (std::move (type_path)), locus (locus)
71 std::string as_string () const override;
73 location_t get_locus () const override final { return locus; }
75 void accept_vis (ASTVisitor &vis) override;
77 // TODO: this mutable getter seems kinda dodgy
78 TypePath &get_type_path () { return type_path; }
79 const TypePath &get_type_path () const { return type_path; }
81 bool is_in_parens () const { return in_parens; }
82 bool has_opening_question_mark () const { return opening_question_mark; }
84 protected:
85 /* Use covariance to implement clone function as returning this object rather
86 * than base */
87 TraitBound *clone_type_param_bound_impl () const override
89 return new TraitBound (node_id, type_path, locus, in_parens,
90 opening_question_mark, for_lifetimes);
94 // definition moved to rust-ast.h
95 class TypeNoBounds;
97 // An impl trait? Poor reference material here.
98 class ImplTraitType : public Type
100 // TypeParamBounds type_param_bounds;
101 // inlined form
102 std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds;
104 location_t locus;
106 protected:
107 /* Use covariance to implement clone function as returning this object rather
108 * than base */
109 ImplTraitType *clone_type_impl () const override
111 return new ImplTraitType (*this);
114 public:
115 ImplTraitType (
116 std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
117 location_t locus)
118 : type_param_bounds (std::move (type_param_bounds)), locus (locus)
121 // copy constructor with vector clone
122 ImplTraitType (ImplTraitType const &other) : locus (other.locus)
124 type_param_bounds.reserve (other.type_param_bounds.size ());
125 for (const auto &e : other.type_param_bounds)
126 type_param_bounds.push_back (e->clone_type_param_bound ());
129 // overloaded assignment operator to clone
130 ImplTraitType &operator= (ImplTraitType const &other)
132 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 ());
138 return *this;
141 // move constructors
142 ImplTraitType (ImplTraitType &&other) = default;
143 ImplTraitType &operator= (ImplTraitType &&other) = default;
145 std::string as_string () const override;
147 location_t get_locus () const override final { return locus; }
149 void accept_vis (ASTVisitor &vis) override;
151 // TODO: mutable getter seems kinda dodgy
152 std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
154 return type_param_bounds;
156 const std::vector<std::unique_ptr<TypeParamBound> > &
157 get_type_param_bounds () const
159 return type_param_bounds;
163 // An opaque value of another type that implements a set of traits
164 class TraitObjectType : public Type
166 bool has_dyn;
167 std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds;
168 location_t locus;
170 protected:
171 /* Use covariance to implement clone function as returning this object rather
172 * than base */
173 TraitObjectType *clone_type_impl () const override
175 return new TraitObjectType (*this);
178 public:
179 TraitObjectType (
180 std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
181 location_t locus, bool is_dyn_dispatch)
182 : has_dyn (is_dyn_dispatch),
183 type_param_bounds (std::move (type_param_bounds)), locus (locus)
186 // copy constructor with vector clone
187 TraitObjectType (TraitObjectType const &other)
188 : has_dyn (other.has_dyn), locus (other.locus)
190 type_param_bounds.reserve (other.type_param_bounds.size ());
191 for (const auto &e : other.type_param_bounds)
192 type_param_bounds.push_back (e->clone_type_param_bound ());
195 // overloaded assignment operator to clone
196 TraitObjectType &operator= (TraitObjectType const &other)
198 has_dyn = other.has_dyn;
199 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 ());
204 return *this;
207 // move constructors
208 TraitObjectType (TraitObjectType &&other) = default;
209 TraitObjectType &operator= (TraitObjectType &&other) = default;
211 std::string as_string () const override;
213 location_t get_locus () const override final { return locus; }
215 void accept_vis (ASTVisitor &vis) override;
217 bool is_dyn () const { return has_dyn; }
219 // TODO: mutable getter seems kinda dodgy
220 std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds ()
222 return type_param_bounds;
224 const std::vector<std::unique_ptr<TypeParamBound> > &
225 get_type_param_bounds () const
227 return type_param_bounds;
231 // A type with parentheses around it, used to avoid ambiguity.
232 class ParenthesisedType : public TypeNoBounds
234 std::unique_ptr<Type> type_in_parens;
235 location_t locus;
237 protected:
238 /* Use covariance to implement clone function as returning this object rather
239 * than base */
240 ParenthesisedType *clone_type_no_bounds_impl () const override
242 return new ParenthesisedType (*this);
245 public:
246 // Constructor uses Type pointer for polymorphism
247 ParenthesisedType (std::unique_ptr<Type> type_inside_parens, location_t locus)
248 : type_in_parens (std::move (type_inside_parens)), locus (locus)
251 /* Copy constructor uses custom deep copy method for type to preserve
252 * polymorphism */
253 ParenthesisedType (ParenthesisedType const &other)
254 : type_in_parens (other.type_in_parens->clone_type ()), locus (other.locus)
257 // overload assignment operator to use custom clone method
258 ParenthesisedType &operator= (ParenthesisedType const &other)
260 type_in_parens = other.type_in_parens->clone_type ();
261 locus = other.locus;
262 return *this;
265 // default move semantics
266 ParenthesisedType (ParenthesisedType &&other) = default;
267 ParenthesisedType &operator= (ParenthesisedType &&other) = default;
269 std::string as_string () const override
271 return "(" + type_in_parens->as_string () + ")";
274 // Creates a trait bound (clone of this one's trait bound) - HACK
275 TraitBound *to_trait_bound (bool) const override
277 /* NOTE: obviously it is unknown whether the internal type is a trait bound
278 * due to polymorphism, so just let the internal type handle it. As
279 * parenthesised type, it must be in parentheses. */
280 return type_in_parens->to_trait_bound (true);
283 location_t get_locus () const override final { return locus; }
285 void accept_vis (ASTVisitor &vis) override;
287 // TODO: would a "vis_type" be better?
288 std::unique_ptr<Type> &get_type_in_parens ()
290 rust_assert (type_in_parens != nullptr);
291 return type_in_parens;
295 // Impl trait with a single bound? Poor reference material here.
296 class ImplTraitTypeOneBound : public TypeNoBounds
298 TraitBound trait_bound;
299 location_t locus;
301 protected:
302 /* Use covariance to implement clone function as returning this object rather
303 * than base */
304 ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override
306 return new ImplTraitTypeOneBound (*this);
309 public:
310 ImplTraitTypeOneBound (TraitBound trait_bound, location_t locus)
311 : trait_bound (std::move (trait_bound)), locus (locus)
314 std::string as_string () const override;
316 location_t get_locus () const override final { return locus; }
318 void accept_vis (ASTVisitor &vis) override;
320 // TODO: would a "vis_type" be better?
321 TraitBound &get_trait_bound ()
323 // TODO: check to ensure invariants are met?
324 return trait_bound;
328 /* A trait object with a single trait bound. The "trait bound" is really just
329 * the trait. Basically like using an interface as a type in an OOP language. */
330 class TraitObjectTypeOneBound : public TypeNoBounds
332 bool has_dyn;
333 TraitBound trait_bound;
334 location_t locus;
336 protected:
337 /* Use covariance to implement clone function as returning this object rather
338 * than base */
339 TraitObjectTypeOneBound *clone_type_no_bounds_impl () const override
341 return new TraitObjectTypeOneBound (*this);
344 public:
345 TraitObjectTypeOneBound (TraitBound trait_bound, location_t locus,
346 bool is_dyn_dispatch = false)
347 : has_dyn (is_dyn_dispatch), trait_bound (std::move (trait_bound)),
348 locus (locus)
351 std::string as_string () const override;
353 // Creates a trait bound (clone of this one's trait bound) - HACK
354 TraitBound *to_trait_bound (bool) const override
356 /* NOTE: this assumes there is no dynamic dispatch specified- if there was,
357 * this cloning would not be required as parsing is unambiguous. */
358 return new TraitBound (trait_bound);
361 location_t get_locus () const override final { return locus; }
363 void accept_vis (ASTVisitor &vis) override;
365 // TODO: would a "vis_type" be better?
366 TraitBound &get_trait_bound ()
368 // TODO: check to ensure invariants are met?
369 return trait_bound;
372 bool is_dyn () const { return has_dyn; }
375 class TypePath; // definition moved to "rust-path.h"
377 /* A type consisting of the "product" of others (the tuple's elements) in a
378 * specific order */
379 class TupleType : public TypeNoBounds
381 std::vector<std::unique_ptr<Type> > elems;
382 location_t locus;
384 public:
385 // Returns whether the tuple type is the unit type, i.e. has no elements.
386 bool is_unit_type () const { return elems.empty (); }
388 TupleType (std::vector<std::unique_ptr<Type> > elems, location_t locus)
389 : elems (std::move (elems)), locus (locus)
392 // copy constructor with vector clone
393 TupleType (TupleType const &other) : locus (other.locus)
395 elems.reserve (other.elems.size ());
396 for (const auto &e : other.elems)
397 elems.push_back (e->clone_type ());
400 // overloaded assignment operator to clone
401 TupleType &operator= (TupleType const &other)
403 locus = other.locus;
405 elems.reserve (other.elems.size ());
406 for (const auto &e : other.elems)
407 elems.push_back (e->clone_type ());
409 return *this;
412 // move constructors
413 TupleType (TupleType &&other) = default;
414 TupleType &operator= (TupleType &&other) = default;
416 std::string as_string () const override;
418 location_t get_locus () const override final { return locus; }
420 void accept_vis (ASTVisitor &vis) override;
422 // TODO: mutable getter seems kinda dodgy
423 std::vector<std::unique_ptr<Type> > &get_elems () { return elems; }
424 const std::vector<std::unique_ptr<Type> > &get_elems () const
426 return elems;
429 protected:
430 /* Use covariance to implement clone function as returning this object rather
431 * than base */
432 TupleType *clone_type_no_bounds_impl () const override
434 return new TupleType (*this);
438 /* A type with no values, representing the result of computations that never
439 * complete. Expressions of NeverType can be coerced into any other types.
440 * Represented as "!". */
441 class NeverType : public TypeNoBounds
443 location_t locus;
445 protected:
446 /* Use covariance to implement clone function as returning this object rather
447 * than base */
448 NeverType *clone_type_no_bounds_impl () const override
450 return new NeverType (*this);
453 public:
454 NeverType (location_t locus) : locus (locus) {}
456 std::string as_string () const override { return "! (never type)"; }
458 location_t get_locus () const override final { return locus; }
460 void accept_vis (ASTVisitor &vis) override;
463 // A type consisting of a pointer without safety or liveness guarantees
464 class RawPointerType : public TypeNoBounds
466 public:
467 enum PointerType
469 MUT,
470 CONST
473 private:
474 PointerType pointer_type;
475 std::unique_ptr<TypeNoBounds> type;
476 location_t locus;
478 public:
479 // Returns whether the pointer is mutable or constant.
480 PointerType get_pointer_type () const { return pointer_type; }
482 // Constructor requires pointer for polymorphism reasons
483 RawPointerType (PointerType pointer_type,
484 std::unique_ptr<TypeNoBounds> type_no_bounds,
485 location_t locus)
486 : pointer_type (pointer_type), type (std::move (type_no_bounds)),
487 locus (locus)
490 // Copy constructor calls custom polymorphic clone function
491 RawPointerType (RawPointerType const &other)
492 : pointer_type (other.pointer_type),
493 type (other.type->clone_type_no_bounds ()), locus (other.locus)
496 // overload assignment operator to use custom clone method
497 RawPointerType &operator= (RawPointerType const &other)
499 pointer_type = other.pointer_type;
500 type = other.type->clone_type_no_bounds ();
501 locus = other.locus;
502 return *this;
505 // default move semantics
506 RawPointerType (RawPointerType &&other) = default;
507 RawPointerType &operator= (RawPointerType &&other) = default;
509 std::string as_string () const override;
511 location_t get_locus () const override final { return locus; }
513 void accept_vis (ASTVisitor &vis) override;
515 // TODO: would a "vis_type" be better?
516 TypeNoBounds &get_type_pointed_to ()
518 rust_assert (type != nullptr);
519 return *type;
522 protected:
523 /* Use covariance to implement clone function as returning this object rather
524 * than base */
525 RawPointerType *clone_type_no_bounds_impl () const override
527 return new RawPointerType (*this);
531 // A type pointing to memory owned by another value
532 class ReferenceType : public TypeNoBounds
534 // bool has_lifetime; // TODO: handle in lifetime or something?
535 Lifetime lifetime;
537 bool has_mut;
538 std::unique_ptr<TypeNoBounds> type;
539 location_t locus;
541 public:
542 // Returns whether the reference is mutable or immutable.
543 bool is_mut () const { return has_mut; }
545 // Returns whether the reference has a lifetime.
546 bool has_lifetime () const { return !lifetime.is_error (); }
548 // Constructor
549 ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds,
550 location_t locus, Lifetime lifetime = Lifetime::elided ())
551 : lifetime (std::move (lifetime)), has_mut (is_mut),
552 type (std::move (type_no_bounds)), locus (locus)
555 // Copy constructor with custom clone method
556 ReferenceType (ReferenceType const &other)
557 : lifetime (other.lifetime), has_mut (other.has_mut),
558 type (other.type->clone_type_no_bounds ()), locus (other.locus)
561 // Operator overload assignment operator to custom clone the unique pointer
562 ReferenceType &operator= (ReferenceType const &other)
564 lifetime = other.lifetime;
565 has_mut = other.has_mut;
566 type = other.type->clone_type_no_bounds ();
567 locus = other.locus;
569 return *this;
572 // move constructors
573 ReferenceType (ReferenceType &&other) = default;
574 ReferenceType &operator= (ReferenceType &&other) = default;
576 std::string as_string () const override;
578 location_t get_locus () const override final { return locus; }
580 void accept_vis (ASTVisitor &vis) override;
582 // TODO: would a "vis_type" be better?
583 TypeNoBounds &get_type_referenced ()
585 rust_assert (type != nullptr);
586 return *type;
589 bool get_has_mut () const { return has_mut; }
591 Lifetime &get_lifetime () { return lifetime; }
593 TypeNoBounds &get_base_type () { return *type; }
595 protected:
596 /* Use covariance to implement clone function as returning this object rather
597 * than base */
598 ReferenceType *clone_type_no_bounds_impl () const override
600 return new ReferenceType (*this);
604 // A fixed-size sequence of elements of a specified type
605 class ArrayType : public TypeNoBounds
607 std::unique_ptr<Type> elem_type;
608 std::unique_ptr<Expr> size;
609 location_t locus;
611 public:
612 // Constructor requires pointers for polymorphism
613 ArrayType (std::unique_ptr<Type> type, std::unique_ptr<Expr> array_size,
614 location_t locus)
615 : elem_type (std::move (type)), size (std::move (array_size)), locus (locus)
618 // Copy constructor requires deep copies of both unique pointers
619 ArrayType (ArrayType const &other)
620 : elem_type (other.elem_type->clone_type ()),
621 size (other.size->clone_expr ()), locus (other.locus)
624 // Overload assignment operator to deep copy pointers
625 ArrayType &operator= (ArrayType const &other)
627 elem_type = other.elem_type->clone_type ();
628 size = other.size->clone_expr ();
629 locus = other.locus;
630 return *this;
633 // move constructors
634 ArrayType (ArrayType &&other) = default;
635 ArrayType &operator= (ArrayType &&other) = default;
637 std::string as_string () const override;
639 location_t get_locus () const override final { return locus; }
641 void accept_vis (ASTVisitor &vis) override;
643 // TODO: would a "vis_type" be better?
644 Type &get_elem_type ()
646 rust_assert (elem_type != nullptr);
647 return *elem_type;
650 // TODO: would a "vis_expr" be better?
651 Expr &get_size_expr ()
653 rust_assert (size != nullptr);
654 return *size;
657 protected:
658 /* Use covariance to implement clone function as returning this object rather
659 * than base */
660 ArrayType *clone_type_no_bounds_impl () const override
662 return new ArrayType (*this);
666 /* A dynamically-sized type representing a "view" into a sequence of elements of
667 * a type */
668 class SliceType : public TypeNoBounds
670 std::unique_ptr<Type> elem_type;
671 location_t locus;
673 public:
674 // Constructor requires pointer for polymorphism
675 SliceType (std::unique_ptr<Type> type, location_t locus)
676 : elem_type (std::move (type)), locus (locus)
679 // Copy constructor requires deep copy of Type smart pointer
680 SliceType (SliceType const &other)
681 : elem_type (other.elem_type->clone_type ()), locus (other.locus)
684 // Overload assignment operator to deep copy
685 SliceType &operator= (SliceType const &other)
687 elem_type = other.elem_type->clone_type ();
688 locus = other.locus;
690 return *this;
693 // move constructors
694 SliceType (SliceType &&other) = default;
695 SliceType &operator= (SliceType &&other) = default;
697 std::string as_string () const override;
699 location_t get_locus () const override final { return locus; }
701 void accept_vis (ASTVisitor &vis) override;
703 // TODO: would a "vis_type" be better?
704 Type &get_elem_type ()
706 rust_assert (elem_type != nullptr);
707 return *elem_type;
710 protected:
711 /* Use covariance to implement clone function as returning this object rather
712 * than base */
713 SliceType *clone_type_no_bounds_impl () const override
715 return new SliceType (*this);
719 /* Type used in generic arguments to explicitly request type inference (wildcard
720 * pattern) */
721 class InferredType : public TypeNoBounds
723 location_t locus;
725 // e.g. Vec<_> = whatever
726 protected:
727 /* Use covariance to implement clone function as returning this object rather
728 * than base */
729 InferredType *clone_type_no_bounds_impl () const override
731 return new InferredType (*this);
734 public:
735 InferredType (location_t locus) : locus (locus) {}
737 std::string as_string () const override;
739 location_t get_locus () const override final { return locus; }
741 void accept_vis (ASTVisitor &vis) override;
744 class QualifiedPathInType; // definition moved to "rust-path.h"
746 // A possibly named param used in a BaseFunctionType
747 struct MaybeNamedParam
749 public:
750 enum ParamKind
752 UNNAMED,
753 IDENTIFIER,
754 WILDCARD
757 private:
758 std::vector<Attribute> outer_attrs;
760 std::unique_ptr<Type> param_type;
762 ParamKind param_kind;
763 Identifier name; // technically, can be an identifier or '_'
765 location_t locus;
767 public:
768 MaybeNamedParam (Identifier name, ParamKind param_kind,
769 std::unique_ptr<Type> param_type,
770 std::vector<Attribute> outer_attrs, location_t locus)
771 : outer_attrs (std::move (outer_attrs)),
772 param_type (std::move (param_type)), param_kind (param_kind),
773 name (std::move (name)), locus (locus)
776 // Copy constructor with clone
777 MaybeNamedParam (MaybeNamedParam const &other)
778 : outer_attrs (other.outer_attrs), param_kind (other.param_kind),
779 name (other.name), locus (other.locus)
781 // guard to prevent null dereference
782 if (other.param_type != nullptr)
783 param_type = other.param_type->clone_type ();
786 ~MaybeNamedParam () = default;
788 // Overloaded assignment operator with clone
789 MaybeNamedParam &operator= (MaybeNamedParam const &other)
791 outer_attrs = other.outer_attrs;
792 name = other.name;
793 param_kind = other.param_kind;
794 locus = other.locus;
796 // guard to prevent null dereference
797 if (other.param_type != nullptr)
798 param_type = other.param_type->clone_type ();
799 else
800 param_type = nullptr;
802 return *this;
805 // move constructors
806 MaybeNamedParam (MaybeNamedParam &&other) = default;
807 MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
809 std::string as_string () const;
811 // Returns whether the param is in an error state.
812 bool is_error () const { return param_type == nullptr; }
814 // Creates an error state param.
815 static MaybeNamedParam create_error ()
817 return MaybeNamedParam ({""}, UNNAMED, nullptr, {}, UNDEF_LOCATION);
820 location_t get_locus () const { return locus; }
822 // TODO: this mutable getter seems really dodgy. Think up better way.
823 std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
824 const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
826 // TODO: would a "vis_type" be better?
827 Type &get_type ()
829 rust_assert (param_type != nullptr);
830 return *param_type;
833 std::unique_ptr<Type> &get_type_ptr ()
835 rust_assert (param_type != nullptr);
836 return param_type;
839 ParamKind get_param_kind () const { return param_kind; }
841 Identifier get_name () const { return name; }
844 /* A function pointer type - can be created via coercion from function items and
845 * non-capturing closures. */
846 class BareFunctionType : public TypeNoBounds
848 // bool has_for_lifetimes;
849 // ForLifetimes for_lifetimes;
850 std::vector<LifetimeParam> for_lifetimes; // inlined version
852 FunctionQualifiers function_qualifiers;
853 std::vector<MaybeNamedParam> params;
854 bool _is_variadic;
855 std::vector<Attribute> variadic_attrs;
857 // bool has_return_type;
858 // BareFunctionReturnType return_type;
859 std::unique_ptr<TypeNoBounds> return_type; // inlined version
861 location_t locus;
863 public:
864 // Whether a return type is defined with the function.
865 bool has_return_type () const { return return_type != nullptr; }
867 // Whether the function has ForLifetimes.
868 bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
870 std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
872 bool is_variadic () const { return _is_variadic; }
874 std::vector<Attribute> &get_variadic_attr () { return variadic_attrs; };
875 const std::vector<Attribute> &get_variadic_attr () const
877 return variadic_attrs;
880 BareFunctionType (std::vector<LifetimeParam> lifetime_params,
881 FunctionQualifiers qualifiers,
882 std::vector<MaybeNamedParam> named_params, bool is_variadic,
883 std::vector<Attribute> variadic_attrs,
884 std::unique_ptr<TypeNoBounds> type, location_t locus)
885 : for_lifetimes (std::move (lifetime_params)),
886 function_qualifiers (std::move (qualifiers)),
887 params (std::move (named_params)), _is_variadic (is_variadic),
888 variadic_attrs (std::move (variadic_attrs)),
889 return_type (std::move (type)), locus (locus)
891 if (!variadic_attrs.empty ())
892 is_variadic = true;
895 // Copy constructor with clone
896 BareFunctionType (BareFunctionType const &other)
897 : for_lifetimes (other.for_lifetimes),
898 function_qualifiers (other.function_qualifiers), params (other.params),
899 _is_variadic (other._is_variadic), variadic_attrs (other.variadic_attrs),
900 locus (other.locus)
902 // guard to prevent null dereference
903 if (other.return_type != nullptr)
904 return_type = other.return_type->clone_type_no_bounds ();
907 // Overload assignment operator to deep copy
908 BareFunctionType &operator= (BareFunctionType const &other)
910 for_lifetimes = other.for_lifetimes;
911 function_qualifiers = other.function_qualifiers;
912 params = other.params;
913 _is_variadic = other._is_variadic;
914 variadic_attrs = other.variadic_attrs;
915 locus = other.locus;
917 // guard to prevent null dereference
918 if (other.return_type != nullptr)
919 return_type = other.return_type->clone_type_no_bounds ();
920 else
921 return_type = nullptr;
923 return *this;
926 // move constructors
927 BareFunctionType (BareFunctionType &&other) = default;
928 BareFunctionType &operator= (BareFunctionType &&other) = default;
930 std::string as_string () const override;
932 location_t get_locus () const override final { return locus; }
934 void accept_vis (ASTVisitor &vis) override;
936 // TODO: this mutable getter seems kinda dodgy
937 std::vector<MaybeNamedParam> &get_function_params () { return params; }
938 const std::vector<MaybeNamedParam> &get_function_params () const
940 return params;
943 // TODO: would a "vis_type" be better?
944 TypeNoBounds &get_return_type ()
946 rust_assert (has_return_type ());
947 return *return_type;
950 FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
952 protected:
953 /* Use covariance to implement clone function as returning this object rather
954 * than base */
955 BareFunctionType *clone_type_no_bounds_impl () const override
957 return new BareFunctionType (*this);
961 // Forward decl - defined in rust-macro.h
962 class MacroInvocation;
964 /* TODO: possible types
965 * struct type?
966 * "enum" (tagged union) type?
967 * C-like union type?
968 * function item type?
969 * closure expression types?
970 * primitive types (bool, int, float, char, str (the slice))
971 * Although supposedly TypePaths are used to reference these types (including
972 * primitives) */
974 /* FIXME: Incomplete spec references:
975 * anonymous type parameters, aka "impl Trait in argument position" - impl then
976 * trait bounds abstract return types, aka "impl Trait in return position" -
977 * impl then trait bounds */
978 } // namespace AST
979 } // namespace Rust
981 #endif