Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / rust / ast / rust-type.h
blob7fa1bc61e9b4b496100c7056273d4154c310ca17
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 locus)
311 : trait_bound (std::move (trait_bound)), locus (locus)
314 std::string as_string () const override;
316 Location 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 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 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 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 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 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 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 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 locus) : locus (locus) {}
456 std::string as_string () const override { return "! (never type)"; }
458 Location 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 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, Location locus)
485 : pointer_type (pointer_type), type (std::move (type_no_bounds)),
486 locus (locus)
489 // Copy constructor calls custom polymorphic clone function
490 RawPointerType (RawPointerType const &other)
491 : pointer_type (other.pointer_type),
492 type (other.type->clone_type_no_bounds ()), locus (other.locus)
495 // overload assignment operator to use custom clone method
496 RawPointerType &operator= (RawPointerType const &other)
498 pointer_type = other.pointer_type;
499 type = other.type->clone_type_no_bounds ();
500 locus = other.locus;
501 return *this;
504 // default move semantics
505 RawPointerType (RawPointerType &&other) = default;
506 RawPointerType &operator= (RawPointerType &&other) = default;
508 std::string as_string () const override;
510 Location get_locus () const override final { return locus; }
512 void accept_vis (ASTVisitor &vis) override;
514 // TODO: would a "vis_type" be better?
515 std::unique_ptr<TypeNoBounds> &get_type_pointed_to ()
517 rust_assert (type != nullptr);
518 return type;
521 protected:
522 /* Use covariance to implement clone function as returning this object rather
523 * than base */
524 RawPointerType *clone_type_no_bounds_impl () const override
526 return new RawPointerType (*this);
530 // A type pointing to memory owned by another value
531 class ReferenceType : public TypeNoBounds
533 // bool has_lifetime; // TODO: handle in lifetime or something?
534 Lifetime lifetime;
536 bool has_mut;
537 std::unique_ptr<TypeNoBounds> type;
538 Location locus;
540 public:
541 // Returns whether the reference is mutable or immutable.
542 bool is_mut () const { return has_mut; }
544 // Returns whether the reference has a lifetime.
545 bool has_lifetime () const { return !lifetime.is_error (); }
547 // Constructor
548 ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds,
549 Location locus, Lifetime lifetime = Lifetime::error ())
550 : lifetime (std::move (lifetime)), has_mut (is_mut),
551 type (std::move (type_no_bounds)), locus (locus)
554 // Copy constructor with custom clone method
555 ReferenceType (ReferenceType const &other)
556 : lifetime (other.lifetime), has_mut (other.has_mut),
557 type (other.type->clone_type_no_bounds ()), locus (other.locus)
560 // Operator overload assignment operator to custom clone the unique pointer
561 ReferenceType &operator= (ReferenceType const &other)
563 lifetime = other.lifetime;
564 has_mut = other.has_mut;
565 type = other.type->clone_type_no_bounds ();
566 locus = other.locus;
568 return *this;
571 // move constructors
572 ReferenceType (ReferenceType &&other) = default;
573 ReferenceType &operator= (ReferenceType &&other) = default;
575 std::string as_string () const override;
577 Location get_locus () const override final { return locus; }
579 void accept_vis (ASTVisitor &vis) override;
581 // TODO: would a "vis_type" be better?
582 std::unique_ptr<TypeNoBounds> &get_type_referenced ()
584 rust_assert (type != nullptr);
585 return type;
588 bool get_has_mut () const { return has_mut; }
590 Lifetime &get_lifetime () { return lifetime; }
592 std::unique_ptr<TypeNoBounds> &get_base_type () { return type; }
594 protected:
595 /* Use covariance to implement clone function as returning this object rather
596 * than base */
597 ReferenceType *clone_type_no_bounds_impl () const override
599 return new ReferenceType (*this);
603 // A fixed-size sequence of elements of a specified type
604 class ArrayType : public TypeNoBounds
606 std::unique_ptr<Type> elem_type;
607 std::unique_ptr<Expr> size;
608 Location locus;
610 public:
611 // Constructor requires pointers for polymorphism
612 ArrayType (std::unique_ptr<Type> type, std::unique_ptr<Expr> array_size,
613 Location locus)
614 : elem_type (std::move (type)), size (std::move (array_size)), locus (locus)
617 // Copy constructor requires deep copies of both unique pointers
618 ArrayType (ArrayType const &other)
619 : elem_type (other.elem_type->clone_type ()),
620 size (other.size->clone_expr ()), locus (other.locus)
623 // Overload assignment operator to deep copy pointers
624 ArrayType &operator= (ArrayType const &other)
626 elem_type = other.elem_type->clone_type ();
627 size = other.size->clone_expr ();
628 locus = other.locus;
629 return *this;
632 // move constructors
633 ArrayType (ArrayType &&other) = default;
634 ArrayType &operator= (ArrayType &&other) = default;
636 std::string as_string () const override;
638 Location get_locus () const override final { return locus; }
640 void accept_vis (ASTVisitor &vis) override;
642 // TODO: would a "vis_type" be better?
643 std::unique_ptr<Type> &get_elem_type ()
645 rust_assert (elem_type != nullptr);
646 return elem_type;
649 // TODO: would a "vis_expr" be better?
650 std::unique_ptr<Expr> &get_size_expr ()
652 rust_assert (size != nullptr);
653 return size;
656 protected:
657 /* Use covariance to implement clone function as returning this object rather
658 * than base */
659 ArrayType *clone_type_no_bounds_impl () const override
661 return new ArrayType (*this);
665 /* A dynamically-sized type representing a "view" into a sequence of elements of
666 * a type */
667 class SliceType : public TypeNoBounds
669 std::unique_ptr<Type> elem_type;
670 Location locus;
672 public:
673 // Constructor requires pointer for polymorphism
674 SliceType (std::unique_ptr<Type> type, Location locus)
675 : elem_type (std::move (type)), locus (locus)
678 // Copy constructor requires deep copy of Type smart pointer
679 SliceType (SliceType const &other)
680 : elem_type (other.elem_type->clone_type ()), locus (other.locus)
683 // Overload assignment operator to deep copy
684 SliceType &operator= (SliceType const &other)
686 elem_type = other.elem_type->clone_type ();
687 locus = other.locus;
689 return *this;
692 // move constructors
693 SliceType (SliceType &&other) = default;
694 SliceType &operator= (SliceType &&other) = default;
696 std::string as_string () const override;
698 Location get_locus () const override final { return locus; }
700 void accept_vis (ASTVisitor &vis) override;
702 // TODO: would a "vis_type" be better?
703 std::unique_ptr<Type> &get_elem_type ()
705 rust_assert (elem_type != nullptr);
706 return elem_type;
709 protected:
710 /* Use covariance to implement clone function as returning this object rather
711 * than base */
712 SliceType *clone_type_no_bounds_impl () const override
714 return new SliceType (*this);
718 /* Type used in generic arguments to explicitly request type inference (wildcard
719 * pattern) */
720 class InferredType : public TypeNoBounds
722 Location locus;
724 // e.g. Vec<_> = whatever
725 protected:
726 /* Use covariance to implement clone function as returning this object rather
727 * than base */
728 InferredType *clone_type_no_bounds_impl () const override
730 return new InferredType (*this);
733 public:
734 InferredType (Location locus) : locus (locus) {}
736 std::string as_string () const override;
738 Location get_locus () const override final { return locus; }
740 void accept_vis (ASTVisitor &vis) override;
743 class QualifiedPathInType; // definition moved to "rust-path.h"
745 // A possibly named param used in a BaseFunctionType
746 struct MaybeNamedParam
748 public:
749 enum ParamKind
751 UNNAMED,
752 IDENTIFIER,
753 WILDCARD
756 private:
757 std::vector<Attribute> outer_attrs;
759 std::unique_ptr<Type> param_type;
761 ParamKind param_kind;
762 Identifier name; // technically, can be an identifier or '_'
764 Location locus;
766 public:
767 MaybeNamedParam (Identifier name, ParamKind param_kind,
768 std::unique_ptr<Type> param_type,
769 std::vector<Attribute> outer_attrs, Location locus)
770 : outer_attrs (std::move (outer_attrs)),
771 param_type (std::move (param_type)), param_kind (param_kind),
772 name (std::move (name)), locus (locus)
775 // Copy constructor with clone
776 MaybeNamedParam (MaybeNamedParam const &other)
777 : outer_attrs (other.outer_attrs), param_kind (other.param_kind),
778 name (other.name), locus (other.locus)
780 // guard to prevent null dereference
781 if (other.param_type != nullptr)
782 param_type = other.param_type->clone_type ();
785 ~MaybeNamedParam () = default;
787 // Overloaded assignment operator with clone
788 MaybeNamedParam &operator= (MaybeNamedParam const &other)
790 outer_attrs = other.outer_attrs;
791 name = other.name;
792 param_kind = other.param_kind;
793 locus = other.locus;
795 // guard to prevent null dereference
796 if (other.param_type != nullptr)
797 param_type = other.param_type->clone_type ();
798 else
799 param_type = nullptr;
801 return *this;
804 // move constructors
805 MaybeNamedParam (MaybeNamedParam &&other) = default;
806 MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
808 std::string as_string () const;
810 // Returns whether the param is in an error state.
811 bool is_error () const { return param_type == nullptr; }
813 // Creates an error state param.
814 static MaybeNamedParam create_error ()
816 return MaybeNamedParam ("", UNNAMED, nullptr, {}, Location ());
819 Location get_locus () const { return locus; }
821 // TODO: this mutable getter seems really dodgy. Think up better way.
822 std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
823 const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
825 // TODO: would a "vis_type" be better?
826 std::unique_ptr<Type> &get_type ()
828 rust_assert (param_type != nullptr);
829 return param_type;
832 ParamKind get_param_kind () const { return param_kind; }
834 Identifier get_name () const { return name; }
837 /* A function pointer type - can be created via coercion from function items and
838 * non-capturing closures. */
839 class BareFunctionType : public TypeNoBounds
841 // bool has_for_lifetimes;
842 // ForLifetimes for_lifetimes;
843 std::vector<LifetimeParam> for_lifetimes; // inlined version
845 FunctionQualifiers function_qualifiers;
846 std::vector<MaybeNamedParam> params;
847 bool _is_variadic;
848 std::vector<Attribute> variadic_attrs;
850 // bool has_return_type;
851 // BareFunctionReturnType return_type;
852 std::unique_ptr<TypeNoBounds> return_type; // inlined version
854 Location locus;
856 public:
857 // Whether a return type is defined with the function.
858 bool has_return_type () const { return return_type != nullptr; }
860 // Whether the function has ForLifetimes.
861 bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
863 std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
865 bool is_variadic () const { return _is_variadic; }
867 std::vector<Attribute> &get_variadic_attr () { return variadic_attrs; };
868 const std::vector<Attribute> &get_variadic_attr () const
870 return variadic_attrs;
873 BareFunctionType (std::vector<LifetimeParam> lifetime_params,
874 FunctionQualifiers qualifiers,
875 std::vector<MaybeNamedParam> named_params, bool is_variadic,
876 std::vector<Attribute> variadic_attrs,
877 std::unique_ptr<TypeNoBounds> type, Location locus)
878 : for_lifetimes (std::move (lifetime_params)),
879 function_qualifiers (std::move (qualifiers)),
880 params (std::move (named_params)), _is_variadic (is_variadic),
881 variadic_attrs (std::move (variadic_attrs)),
882 return_type (std::move (type)), locus (locus)
884 if (!variadic_attrs.empty ())
885 is_variadic = true;
888 // Copy constructor with clone
889 BareFunctionType (BareFunctionType const &other)
890 : for_lifetimes (other.for_lifetimes),
891 function_qualifiers (other.function_qualifiers), params (other.params),
892 _is_variadic (other._is_variadic), variadic_attrs (other.variadic_attrs),
893 locus (other.locus)
895 // guard to prevent null dereference
896 if (other.return_type != nullptr)
897 return_type = other.return_type->clone_type_no_bounds ();
900 // Overload assignment operator to deep copy
901 BareFunctionType &operator= (BareFunctionType const &other)
903 for_lifetimes = other.for_lifetimes;
904 function_qualifiers = other.function_qualifiers;
905 params = other.params;
906 _is_variadic = other._is_variadic;
907 variadic_attrs = other.variadic_attrs;
908 locus = other.locus;
910 // guard to prevent null dereference
911 if (other.return_type != nullptr)
912 return_type = other.return_type->clone_type_no_bounds ();
913 else
914 return_type = nullptr;
916 return *this;
919 // move constructors
920 BareFunctionType (BareFunctionType &&other) = default;
921 BareFunctionType &operator= (BareFunctionType &&other) = default;
923 std::string as_string () const override;
925 Location get_locus () const override final { return locus; }
927 void accept_vis (ASTVisitor &vis) override;
929 // TODO: this mutable getter seems kinda dodgy
930 std::vector<MaybeNamedParam> &get_function_params () { return params; }
931 const std::vector<MaybeNamedParam> &get_function_params () const
933 return params;
936 // TODO: would a "vis_type" be better?
937 std::unique_ptr<TypeNoBounds> &get_return_type ()
939 rust_assert (has_return_type ());
940 return return_type;
943 FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
945 protected:
946 /* Use covariance to implement clone function as returning this object rather
947 * than base */
948 BareFunctionType *clone_type_no_bounds_impl () const override
950 return new BareFunctionType (*this);
954 // Forward decl - defined in rust-macro.h
955 class MacroInvocation;
957 /* TODO: possible types
958 * struct type?
959 * "enum" (tagged union) type?
960 * C-like union type?
961 * function item type?
962 * closure expression types?
963 * primitive types (bool, int, float, char, str (the slice))
964 * Although supposedly TypePaths are used to reference these types (including
965 * primitives) */
967 /* FIXME: Incomplete spec references:
968 * anonymous type parameters, aka "impl Trait in argument position" - impl then
969 * trait bounds abstract return types, aka "impl Trait in return position" -
970 * impl then trait bounds */
971 } // namespace AST
972 } // namespace Rust
974 #endif