Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
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.
9 : :
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.
14 : :
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/>.
18 : :
19 : : #ifndef RUST_HIR_TYPE_H
20 : : #define RUST_HIR_TYPE_H
21 : :
22 : : #include "rust-common.h"
23 : : #include "rust-hir.h"
24 : : #include "rust-hir-path.h"
25 : :
26 : : namespace Rust {
27 : : namespace HIR {
28 : : // definitions moved to rust-ast.h
29 : : class TypeParamBound;
30 : : class Lifetime;
31 : :
32 : : // A trait bound
33 : : class TraitBound : public TypeParamBound
34 : : {
35 : : bool in_parens;
36 : : BoundPolarity polarity;
37 : : std::vector<LifetimeParam> for_lifetimes;
38 : : TypePath type_path;
39 : : location_t locus;
40 : :
41 : : Analysis::NodeMapping mappings;
42 : :
43 : : public:
44 : : // Returns whether trait bound has "for" lifetimes
45 : 0 : bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
46 : :
47 : 585 : TraitBound (Analysis::NodeMapping mapping, TypePath type_path,
48 : : location_t locus, bool in_parens = false,
49 : : BoundPolarity polarity = BoundPolarity::RegularBound,
50 : : std::vector<LifetimeParam> for_lifetimes
51 : : = std::vector<LifetimeParam> ())
52 : 585 : : in_parens (in_parens), polarity (polarity),
53 : 585 : for_lifetimes (std::move (for_lifetimes)),
54 : 585 : type_path (std::move (type_path)), locus (locus), mappings (mapping)
55 : 585 : {}
56 : :
57 : : std::string as_string () const override;
58 : :
59 : 585 : location_t get_locus () const override final { return locus; }
60 : :
61 : : void accept_vis (HIRFullVisitor &vis) override;
62 : :
63 : 585 : Analysis::NodeMapping get_mappings () const override final
64 : : {
65 : 585 : return mappings;
66 : : }
67 : :
68 : 110 : std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
69 : 0 : bool get_in_parens () { return in_parens; }
70 : 339 : BoundPolarity get_polarity () { return polarity; }
71 : :
72 : 1032 : BoundType get_bound_type () const final override { return TRAITBOUND; }
73 : :
74 : 1032 : TypePath &get_path () { return type_path; }
75 : :
76 : : const TypePath &get_path () const { return type_path; }
77 : :
78 : : protected:
79 : : /* Use covariance to implement clone function as returning this object rather
80 : : * than base */
81 : 80 : TraitBound *clone_type_param_bound_impl () const override
82 : : {
83 : 80 : return new TraitBound (*this);
84 : : }
85 : : };
86 : :
87 : : // definition moved to rust-ast.h
88 : : class TypeNoBounds;
89 : :
90 : : // An impl trait? Poor reference material here.
91 : : class ImplTraitType : public Type
92 : : {
93 : : // TypeParamBounds type_param_bounds;
94 : : // inlined form
95 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
96 : :
97 : : protected:
98 : : /* Use covariance to implement clone function as returning this object rather
99 : : * than base */
100 : 0 : ImplTraitType *clone_type_impl () const override
101 : : {
102 : 0 : return new ImplTraitType (*this);
103 : : }
104 : :
105 : : public:
106 : : ImplTraitType (Analysis::NodeMapping mappings,
107 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
108 : : location_t locus)
109 : : : Type (mappings, locus), type_param_bounds (std::move (type_param_bounds))
110 : : {}
111 : :
112 : : // copy constructor with vector clone
113 : 0 : ImplTraitType (ImplTraitType const &other)
114 : 0 : : Type (other.mappings, other.locus)
115 : : {
116 : 0 : type_param_bounds.reserve (other.type_param_bounds.size ());
117 : 0 : for (const auto &e : other.type_param_bounds)
118 : 0 : type_param_bounds.push_back (e->clone_type_param_bound ());
119 : 0 : }
120 : :
121 : : // overloaded assignment operator to clone
122 : : ImplTraitType &operator= (ImplTraitType const &other)
123 : : {
124 : : locus = other.locus;
125 : : mappings = other.mappings;
126 : :
127 : : type_param_bounds.reserve (other.type_param_bounds.size ());
128 : : for (const auto &e : other.type_param_bounds)
129 : : type_param_bounds.push_back (e->clone_type_param_bound ());
130 : :
131 : : return *this;
132 : : }
133 : :
134 : : // move constructors
135 : : ImplTraitType (ImplTraitType &&other) = default;
136 : : ImplTraitType &operator= (ImplTraitType &&other) = default;
137 : :
138 : : std::string as_string () const override;
139 : 0 : std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
140 : : {
141 : 0 : return type_param_bounds;
142 : : }
143 : : void accept_vis (HIRFullVisitor &vis) override;
144 : : void accept_vis (HIRTypeVisitor &vis) override;
145 : : };
146 : :
147 : : // An opaque value of another type that implements a set of traits
148 : : class TraitObjectType : public Type
149 : : {
150 : : bool has_dyn;
151 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
152 : :
153 : : protected:
154 : : /* Use covariance to implement clone function as returning this object rather
155 : : * than base */
156 : 14 : TraitObjectType *clone_type_impl () const override
157 : : {
158 : 14 : return new TraitObjectType (*this);
159 : : }
160 : :
161 : : public:
162 : 110 : TraitObjectType (
163 : : Analysis::NodeMapping mappings,
164 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
165 : : location_t locus, bool is_dyn_dispatch)
166 : 110 : : Type (mappings, locus), has_dyn (is_dyn_dispatch),
167 : 110 : type_param_bounds (std::move (type_param_bounds))
168 : : {}
169 : :
170 : : // copy constructor with vector clone
171 : 14 : TraitObjectType (TraitObjectType const &other)
172 : 14 : : Type (other.mappings, other.locus), has_dyn (other.has_dyn)
173 : : {
174 : 14 : type_param_bounds.reserve (other.type_param_bounds.size ());
175 : 28 : for (const auto &e : other.type_param_bounds)
176 : 14 : type_param_bounds.push_back (e->clone_type_param_bound ());
177 : 14 : }
178 : :
179 : : // overloaded assignment operator to clone
180 : : TraitObjectType &operator= (TraitObjectType const &other)
181 : : {
182 : : mappings = other.mappings;
183 : : has_dyn = other.has_dyn;
184 : : locus = other.locus;
185 : : type_param_bounds.reserve (other.type_param_bounds.size ());
186 : : for (const auto &e : other.type_param_bounds)
187 : : type_param_bounds.push_back (e->clone_type_param_bound ());
188 : :
189 : : return *this;
190 : : }
191 : :
192 : : // move constructors
193 : : TraitObjectType (TraitObjectType &&other) = default;
194 : : TraitObjectType &operator= (TraitObjectType &&other) = default;
195 : :
196 : : std::string as_string () const override;
197 : 0 : bool get_has_dyn () { return has_dyn; }
198 : : void accept_vis (HIRFullVisitor &vis) override;
199 : : void accept_vis (HIRTypeVisitor &vis) override;
200 : :
201 : 0 : std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
202 : : {
203 : 110 : return type_param_bounds;
204 : : }
205 : :
206 : : const std::vector<std::unique_ptr<TypeParamBound>> &
207 : : get_type_param_bounds () const
208 : : {
209 : : return type_param_bounds;
210 : : }
211 : : };
212 : :
213 : : // A type with parentheses around it, used to avoid ambiguity.
214 : : class ParenthesisedType : public TypeNoBounds
215 : : {
216 : : std::unique_ptr<Type> type_in_parens;
217 : :
218 : : protected:
219 : : /* Use covariance to implement clone function as returning this object rather
220 : : * than base */
221 : 0 : ParenthesisedType *clone_type_impl () const override
222 : : {
223 : 0 : return new ParenthesisedType (*this);
224 : : }
225 : :
226 : : /* Use covariance to implement clone function as returning this object rather
227 : : * than base */
228 : 0 : ParenthesisedType *clone_type_no_bounds_impl () const override
229 : : {
230 : 0 : return new ParenthesisedType (*this);
231 : : }
232 : :
233 : : public:
234 : : // Constructor uses Type pointer for polymorphism
235 : : ParenthesisedType (Analysis::NodeMapping mappings,
236 : : std::unique_ptr<Type> type_inside_parens, location_t locus)
237 : : : TypeNoBounds (mappings, locus),
238 : : type_in_parens (std::move (type_inside_parens))
239 : : {}
240 : :
241 : : /* Copy constructor uses custom deep copy method for type to preserve
242 : : * polymorphism */
243 : 0 : ParenthesisedType (ParenthesisedType const &other)
244 : 0 : : TypeNoBounds (other.mappings, other.locus),
245 : 0 : type_in_parens (other.type_in_parens->clone_type ())
246 : 0 : {}
247 : :
248 : : // overload assignment operator to use custom clone method
249 : : ParenthesisedType &operator= (ParenthesisedType const &other)
250 : : {
251 : : mappings = other.mappings;
252 : : type_in_parens = other.type_in_parens->clone_type ();
253 : : locus = other.locus;
254 : : return *this;
255 : : }
256 : :
257 : : // default move semantics
258 : : ParenthesisedType (ParenthesisedType &&other) = default;
259 : : ParenthesisedType &operator= (ParenthesisedType &&other) = default;
260 : :
261 : 0 : std::string as_string () const override
262 : : {
263 : 0 : return "(" + type_in_parens->as_string () + ")";
264 : : }
265 : :
266 : : // Creates a trait bound (clone of this one's trait bound) - HACK
267 : 0 : TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override
268 : : {
269 : : /* NOTE: obviously it is unknown whether the internal type is a trait bound
270 : : * due to polymorphism, so just let the internal type handle it. As
271 : : * parenthesised type, it must be in parentheses. */
272 : 0 : return type_in_parens->to_trait_bound (true);
273 : : }
274 : 0 : std::unique_ptr<Type> &get_type_in_parens () { return type_in_parens; }
275 : : void accept_vis (HIRFullVisitor &vis) override;
276 : : void accept_vis (HIRTypeVisitor &vis) override;
277 : : };
278 : :
279 : : // Impl trait with a single bound? Poor reference material here.
280 : 0 : class ImplTraitTypeOneBound : public TypeNoBounds
281 : : {
282 : : TraitBound trait_bound;
283 : :
284 : : protected:
285 : : /* Use covariance to implement clone function as returning this object rather
286 : : * than base */
287 : 0 : ImplTraitTypeOneBound *clone_type_impl () const override
288 : : {
289 : 0 : return new ImplTraitTypeOneBound (*this);
290 : : }
291 : :
292 : : /* Use covariance to implement clone function as returning this object rather
293 : : * than base */
294 : 0 : ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override
295 : : {
296 : 0 : return new ImplTraitTypeOneBound (*this);
297 : : }
298 : :
299 : : public:
300 : : ImplTraitTypeOneBound (Analysis::NodeMapping mappings, TraitBound trait_bound,
301 : : location_t locus)
302 : : : TypeNoBounds (mappings, locus), trait_bound (std::move (trait_bound))
303 : : {}
304 : :
305 : : std::string as_string () const override;
306 : : TraitBound &get_trait_bound () { return trait_bound; }
307 : : void accept_vis (HIRFullVisitor &vis) override;
308 : : void accept_vis (HIRTypeVisitor &vis) override;
309 : : };
310 : :
311 : : class TypePath; // definition moved to "rust-path.h"
312 : :
313 : : /* A type consisting of the "product" of others (the tuple's elements) in a
314 : : * specific order */
315 : : class TupleType : public TypeNoBounds
316 : : {
317 : : std::vector<std::unique_ptr<Type>> elems;
318 : :
319 : : public:
320 : : // Returns whether the tuple type is the unit type, i.e. has no elements.
321 : 245 : bool is_unit_type () const { return elems.empty (); }
322 : :
323 : 300 : TupleType (Analysis::NodeMapping mappings,
324 : : std::vector<std::unique_ptr<Type>> elems, location_t locus)
325 : 300 : : TypeNoBounds (mappings, locus), elems (std::move (elems))
326 : : {}
327 : :
328 : : // copy constructor with vector clone
329 : 24 : TupleType (TupleType const &other)
330 : 24 : : TypeNoBounds (other.mappings, other.locus)
331 : : {
332 : 24 : mappings = other.mappings;
333 : 24 : elems.reserve (other.elems.size ());
334 : 45 : for (const auto &e : other.elems)
335 : 21 : elems.push_back (e->clone_type ());
336 : 24 : }
337 : :
338 : : // overloaded assignment operator to clone
339 : : TupleType &operator= (TupleType const &other)
340 : : {
341 : : locus = other.locus;
342 : :
343 : : elems.reserve (other.elems.size ());
344 : : for (const auto &e : other.elems)
345 : : elems.push_back (e->clone_type ());
346 : :
347 : : return *this;
348 : : }
349 : :
350 : : // move constructors
351 : : TupleType (TupleType &&other) = default;
352 : : TupleType &operator= (TupleType &&other) = default;
353 : :
354 : : std::string as_string () const override;
355 : :
356 : : void accept_vis (HIRFullVisitor &vis) override;
357 : : void accept_vis (HIRTypeVisitor &vis) override;
358 : :
359 : 192 : std::vector<std::unique_ptr<Type>> &get_elems () { return elems; }
360 : : const std::vector<std::unique_ptr<Type>> &get_elems () const { return elems; }
361 : :
362 : : protected:
363 : : /* Use covariance to implement clone function as returning this object rather
364 : : * than base */
365 : 24 : TupleType *clone_type_impl () const override { return new TupleType (*this); }
366 : :
367 : : /* Use covariance to implement clone function as returning this object rather
368 : : * than base */
369 : 0 : TupleType *clone_type_no_bounds_impl () const override
370 : : {
371 : 0 : return new TupleType (*this);
372 : : }
373 : : };
374 : :
375 : : /* A type with no values, representing the result of computations that never
376 : : * complete. Expressions of NeverType can be coerced into any other types.
377 : : * Represented as "!". */
378 : 0 : class NeverType : public TypeNoBounds
379 : : {
380 : : protected:
381 : : /* Use covariance to implement clone function as returning this object rather
382 : : * than base */
383 : 0 : NeverType *clone_type_impl () const override { return new NeverType (*this); }
384 : :
385 : : /* Use covariance to implement clone function as returning this object rather
386 : : * than base */
387 : 0 : NeverType *clone_type_no_bounds_impl () const override
388 : : {
389 : 0 : return new NeverType (*this);
390 : : }
391 : :
392 : : public:
393 : 23 : NeverType (Analysis::NodeMapping mappings, location_t locus)
394 : 23 : : TypeNoBounds (mappings, locus)
395 : : {}
396 : :
397 : 0 : std::string as_string () const override { return "! (never type)"; }
398 : :
399 : : void accept_vis (HIRFullVisitor &vis) override;
400 : : void accept_vis (HIRTypeVisitor &vis) override;
401 : : };
402 : :
403 : : // A type consisting of a pointer without safety or liveness guarantees
404 : : class RawPointerType : public TypeNoBounds
405 : : {
406 : : private:
407 : : Mutability mut;
408 : : std::unique_ptr<Type> type;
409 : :
410 : : public:
411 : : // Constructor requires pointer for polymorphism reasons
412 : 4687 : RawPointerType (Analysis::NodeMapping mappings, Mutability mut,
413 : : std::unique_ptr<Type> type, location_t locus)
414 : 4687 : : TypeNoBounds (mappings, locus), mut (mut), type (std::move (type))
415 : : {}
416 : :
417 : : // Copy constructor calls custom polymorphic clone function
418 : 42 : RawPointerType (RawPointerType const &other)
419 : 42 : : TypeNoBounds (other.mappings, other.locus), mut (other.mut),
420 : 42 : type (other.type->clone_type ())
421 : 42 : {}
422 : :
423 : : // overload assignment operator to use custom clone method
424 : : RawPointerType &operator= (RawPointerType const &other)
425 : : {
426 : : mappings = other.mappings;
427 : : mut = other.mut;
428 : : type = other.type->clone_type ();
429 : : locus = other.locus;
430 : : return *this;
431 : : }
432 : :
433 : : // default move semantics
434 : : RawPointerType (RawPointerType &&other) = default;
435 : : RawPointerType &operator= (RawPointerType &&other) = default;
436 : :
437 : : std::string as_string () const override;
438 : :
439 : : void accept_vis (HIRFullVisitor &vis) override;
440 : : void accept_vis (HIRTypeVisitor &vis) override;
441 : :
442 : 0 : std::unique_ptr<Type> &get_type () { return type; }
443 : :
444 : 4686 : Mutability get_mut () const { return mut; }
445 : :
446 : 0 : bool is_mut () const { return mut == Mutability::Mut; }
447 : :
448 : : bool is_const () const { return mut == Mutability::Imm; }
449 : :
450 : 4686 : std::unique_ptr<Type> &get_base_type () { return type; }
451 : :
452 : : protected:
453 : : /* Use covariance to implement clone function as returning this object rather
454 : : * than base */
455 : 42 : RawPointerType *clone_type_impl () const override
456 : : {
457 : 42 : return new RawPointerType (*this);
458 : : }
459 : :
460 : : /* Use covariance to implement clone function as returning this object rather
461 : : * than base */
462 : 0 : RawPointerType *clone_type_no_bounds_impl () const override
463 : : {
464 : 0 : return new RawPointerType (*this);
465 : : }
466 : : };
467 : :
468 : : // A type pointing to memory owned by another value
469 : : class ReferenceType : public TypeNoBounds
470 : : {
471 : : // bool has_lifetime; // TODO: handle in lifetime or something?
472 : : Lifetime lifetime;
473 : :
474 : : Mutability mut;
475 : : std::unique_ptr<Type> type;
476 : :
477 : : public:
478 : : // Returns whether the reference is mutable or immutable.
479 : 1 : bool is_mut () const { return mut == Mutability::Mut; }
480 : :
481 : : // Returns whether the reference has a lifetime.
482 : 1995 : bool has_lifetime () const { return !lifetime.is_error (); }
483 : :
484 : : // Constructor
485 : 1808 : ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
486 : : std::unique_ptr<Type> type_no_bounds, location_t locus,
487 : : Lifetime lifetime)
488 : 1808 : : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)),
489 : 1808 : mut (mut), type (std::move (type_no_bounds))
490 : : {}
491 : :
492 : : // Copy constructor with custom clone method
493 : 777 : ReferenceType (ReferenceType const &other)
494 : 777 : : TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime),
495 : 777 : mut (other.mut), type (other.type->clone_type ())
496 : 777 : {}
497 : :
498 : : // Operator overload assignment operator to custom clone the unique pointer
499 : : ReferenceType &operator= (ReferenceType const &other)
500 : : {
501 : : mappings = other.mappings;
502 : : lifetime = other.lifetime;
503 : : mut = other.mut;
504 : : type = other.type->clone_type ();
505 : : locus = other.locus;
506 : :
507 : : return *this;
508 : : }
509 : :
510 : : // move constructors
511 : : ReferenceType (ReferenceType &&other) = default;
512 : : ReferenceType &operator= (ReferenceType &&other) = default;
513 : :
514 : : std::string as_string () const override;
515 : :
516 : : void accept_vis (HIRFullVisitor &vis) override;
517 : : void accept_vis (HIRTypeVisitor &vis) override;
518 : :
519 : 1797 : Lifetime &get_lifetime () { return lifetime; }
520 : :
521 : 1795 : Mutability get_mut () const { return mut; }
522 : :
523 : 1797 : std::unique_ptr<Type> &get_base_type () { return type; }
524 : :
525 : : protected:
526 : : /* Use covariance to implement clone function as returning this object rather
527 : : * than base */
528 : 777 : ReferenceType *clone_type_impl () const override
529 : : {
530 : 777 : return new ReferenceType (*this);
531 : : }
532 : :
533 : : /* Use covariance to implement clone function as returning this object rather
534 : : * than base */
535 : 0 : ReferenceType *clone_type_no_bounds_impl () const override
536 : : {
537 : 0 : return new ReferenceType (*this);
538 : : }
539 : : };
540 : :
541 : : // A fixed-size sequence of elements of a specified type
542 : : class ArrayType : public TypeNoBounds
543 : : {
544 : : std::unique_ptr<Type> elem_type;
545 : : std::unique_ptr<Expr> size;
546 : :
547 : : public:
548 : : // Constructor requires pointers for polymorphism
549 : 392 : ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
550 : : std::unique_ptr<Expr> array_size, location_t locus)
551 : 392 : : TypeNoBounds (mappings, locus), elem_type (std::move (type)),
552 : 392 : size (std::move (array_size))
553 : : {}
554 : :
555 : : // Copy constructor requires deep copies of both unique pointers
556 : 0 : ArrayType (ArrayType const &other)
557 : 0 : : TypeNoBounds (other.mappings, other.locus),
558 : 0 : elem_type (other.elem_type->clone_type ()),
559 : 0 : size (other.size->clone_expr ())
560 : 0 : {}
561 : :
562 : : // Overload assignment operator to deep copy pointers
563 : : ArrayType &operator= (ArrayType const &other)
564 : : {
565 : : mappings = other.mappings;
566 : : elem_type = other.elem_type->clone_type ();
567 : : size = other.size->clone_expr ();
568 : : locus = other.locus;
569 : : return *this;
570 : : }
571 : :
572 : : // move constructors
573 : : ArrayType (ArrayType &&other) = default;
574 : : ArrayType &operator= (ArrayType &&other) = default;
575 : :
576 : : std::string as_string () const override;
577 : :
578 : : void accept_vis (HIRFullVisitor &vis) override;
579 : : void accept_vis (HIRTypeVisitor &vis) override;
580 : :
581 : 393 : std::unique_ptr<Type> &get_element_type () { return elem_type; }
582 : :
583 : 1749 : std::unique_ptr<Expr> &get_size_expr () { return size; }
584 : :
585 : : protected:
586 : : /* Use covariance to implement clone function as returning this object rather
587 : : * than base */
588 : 0 : ArrayType *clone_type_impl () const override { return new ArrayType (*this); }
589 : :
590 : : /* Use covariance to implement clone function as returning this object rather
591 : : * than base */
592 : 0 : ArrayType *clone_type_no_bounds_impl () const override
593 : : {
594 : 0 : return new ArrayType (*this);
595 : : }
596 : : };
597 : :
598 : : /* A dynamically-sized type representing a "view" into a sequence of elements of
599 : : * a type */
600 : : class SliceType : public TypeNoBounds
601 : : {
602 : : std::unique_ptr<Type> elem_type;
603 : :
604 : : public:
605 : : // Constructor requires pointer for polymorphism
606 : 746 : SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
607 : : location_t locus)
608 : 746 : : TypeNoBounds (mappings, locus), elem_type (std::move (type))
609 : : {}
610 : :
611 : : // Copy constructor requires deep copy of Type smart pointer
612 : 479 : SliceType (SliceType const &other)
613 : 479 : : TypeNoBounds (other.mappings, other.locus),
614 : 479 : elem_type (other.elem_type->clone_type ())
615 : 479 : {}
616 : :
617 : : // Overload assignment operator to deep copy
618 : : SliceType &operator= (SliceType const &other)
619 : : {
620 : : mappings = other.mappings;
621 : : elem_type = other.elem_type->clone_type ();
622 : : locus = other.locus;
623 : :
624 : : return *this;
625 : : }
626 : :
627 : : // move constructors
628 : : SliceType (SliceType &&other) = default;
629 : : SliceType &operator= (SliceType &&other) = default;
630 : :
631 : : std::string as_string () const override;
632 : :
633 : : void accept_vis (HIRFullVisitor &vis) override;
634 : : void accept_vis (HIRTypeVisitor &vis) override;
635 : :
636 : 746 : std::unique_ptr<Type> &get_element_type () { return elem_type; }
637 : :
638 : : protected:
639 : : /* Use covariance to implement clone function as returning this object rather
640 : : * than base */
641 : 479 : SliceType *clone_type_impl () const override { return new SliceType (*this); }
642 : :
643 : : /* Use covariance to implement clone function as returning this object rather
644 : : * than base */
645 : 0 : SliceType *clone_type_no_bounds_impl () const override
646 : : {
647 : 0 : return new SliceType (*this);
648 : : }
649 : : };
650 : :
651 : : /* Type used in generic arguments to explicitly request type inference (wildcard
652 : : * pattern) */
653 : 67 : class InferredType : public TypeNoBounds
654 : : {
655 : : // e.g. Vec<_> = whatever
656 : : protected:
657 : : /* Use covariance to implement clone function as returning this object rather
658 : : * than base */
659 : 67 : InferredType *clone_type_impl () const override
660 : : {
661 : 67 : return new InferredType (*this);
662 : : }
663 : :
664 : : /* Use covariance to implement clone function as returning this object rather
665 : : * than base */
666 : 0 : InferredType *clone_type_no_bounds_impl () const override
667 : : {
668 : 0 : return new InferredType (*this);
669 : : }
670 : :
671 : : public:
672 : 131 : InferredType (Analysis::NodeMapping mappings, location_t locus)
673 : 131 : : TypeNoBounds (mappings, locus)
674 : : {}
675 : :
676 : : std::string as_string () const override;
677 : :
678 : : void accept_vis (HIRFullVisitor &vis) override;
679 : : void accept_vis (HIRTypeVisitor &vis) override;
680 : : };
681 : :
682 : : class QualifiedPathInType; // definition moved to "rust-path.h"
683 : :
684 : : // A possibly named param used in a BaseFunctionType
685 : : struct MaybeNamedParam
686 : : {
687 : : public:
688 : : enum ParamKind
689 : : {
690 : : UNNAMED,
691 : : IDENTIFIER,
692 : : WILDCARD
693 : : };
694 : :
695 : : private:
696 : : std::unique_ptr<Type> param_type;
697 : :
698 : : ParamKind param_kind;
699 : : Identifier name; // technically, can be an identifier or '_'
700 : :
701 : : location_t locus;
702 : :
703 : : public:
704 : 33 : MaybeNamedParam (Identifier name, ParamKind param_kind,
705 : : std::unique_ptr<Type> param_type, location_t locus)
706 : 33 : : param_type (std::move (param_type)), param_kind (param_kind),
707 : 33 : name (std::move (name)), locus (locus)
708 : : {}
709 : :
710 : : // Copy constructor with clone
711 : 0 : MaybeNamedParam (MaybeNamedParam const &other)
712 : 0 : : param_type (other.param_type->clone_type ()),
713 : 0 : param_kind (other.param_kind), name (other.name), locus (other.locus)
714 : 0 : {}
715 : :
716 : 33 : ~MaybeNamedParam () = default;
717 : :
718 : : // Overloaded assignment operator with clone
719 : : MaybeNamedParam &operator= (MaybeNamedParam const &other)
720 : : {
721 : : name = other.name;
722 : : param_kind = other.param_kind;
723 : : param_type = other.param_type->clone_type ();
724 : : locus = other.locus;
725 : :
726 : : return *this;
727 : : }
728 : :
729 : : // move constructors
730 : 33 : MaybeNamedParam (MaybeNamedParam &&other) = default;
731 : : MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
732 : :
733 : : std::string as_string () const;
734 : :
735 : : // Returns whether the param is in an error state.
736 : : bool is_error () const { return param_type == nullptr; }
737 : :
738 : : // Creates an error state param.
739 : : static MaybeNamedParam create_error ()
740 : : {
741 : : return MaybeNamedParam ({""}, UNNAMED, nullptr, UNDEF_LOCATION);
742 : : }
743 : :
744 : : location_t get_locus () const { return locus; }
745 : :
746 : 31 : std::unique_ptr<Type> &get_type () { return param_type; }
747 : :
748 : 0 : ParamKind get_param_kind () const { return param_kind; }
749 : :
750 : 0 : Identifier get_name () const { return name; }
751 : : };
752 : :
753 : : std::string enum_to_str (MaybeNamedParam::ParamKind);
754 : :
755 : : /* A function pointer type - can be created via coercion from function items and
756 : : * non- capturing closures. */
757 : : class BareFunctionType : public TypeNoBounds
758 : : {
759 : : // bool has_for_lifetimes;
760 : : // ForLifetimes for_lifetimes;
761 : : std::vector<LifetimeParam> for_lifetimes; // inlined version
762 : :
763 : : FunctionQualifiers function_qualifiers;
764 : : std::vector<MaybeNamedParam> params;
765 : : bool is_variadic;
766 : :
767 : : std::unique_ptr<Type> return_type; // inlined version
768 : :
769 : : public:
770 : : // Whether a return type is defined with the function.
771 : 34 : bool has_return_type () const { return return_type != nullptr; }
772 : :
773 : : // Whether the function has ForLifetimes.
774 : 0 : bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
775 : :
776 : 36 : BareFunctionType (Analysis::NodeMapping mappings,
777 : : std::vector<LifetimeParam> lifetime_params,
778 : : FunctionQualifiers qualifiers,
779 : : std::vector<MaybeNamedParam> named_params, bool is_variadic,
780 : : std::unique_ptr<Type> type, location_t locus)
781 : 36 : : TypeNoBounds (mappings, locus),
782 : 36 : for_lifetimes (std::move (lifetime_params)),
783 : 36 : function_qualifiers (std::move (qualifiers)),
784 : 36 : params (std::move (named_params)), is_variadic (is_variadic),
785 : 36 : return_type (std::move (type))
786 : 36 : {}
787 : :
788 : : // Copy constructor with clone
789 : 0 : BareFunctionType (BareFunctionType const &other)
790 : 0 : : TypeNoBounds (other.mappings, other.locus),
791 : 0 : for_lifetimes (other.for_lifetimes),
792 : 0 : function_qualifiers (other.function_qualifiers), params (other.params),
793 : 0 : is_variadic (other.is_variadic),
794 : 0 : return_type (other.return_type->clone_type ())
795 : 0 : {}
796 : :
797 : : // Overload assignment operator to deep copy
798 : : BareFunctionType &operator= (BareFunctionType const &other)
799 : : {
800 : : mappings = other.mappings;
801 : : for_lifetimes = other.for_lifetimes;
802 : : function_qualifiers = other.function_qualifiers;
803 : : params = other.params;
804 : : is_variadic = other.is_variadic;
805 : : return_type = other.return_type->clone_type ();
806 : : locus = other.locus;
807 : :
808 : : return *this;
809 : : }
810 : :
811 : : // move constructors
812 : : BareFunctionType (BareFunctionType &&other) = default;
813 : : BareFunctionType &operator= (BareFunctionType &&other) = default;
814 : :
815 : : std::string as_string () const override;
816 : :
817 : : void accept_vis (HIRFullVisitor &vis) override;
818 : : void accept_vis (HIRTypeVisitor &vis) override;
819 : :
820 : 34 : std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
821 : 0 : bool get_is_variadic () { return is_variadic; }
822 : 0 : FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
823 : :
824 : 34 : std::vector<MaybeNamedParam> &get_function_params () { return params; }
825 : : const std::vector<MaybeNamedParam> &get_function_params () const
826 : : {
827 : : return params;
828 : : }
829 : :
830 : : // TODO: would a "vis_type" be better?
831 : 30 : std::unique_ptr<Type> &get_return_type () { return return_type; }
832 : :
833 : : protected:
834 : : /* Use covariance to implement clone function as returning this object rather
835 : : * than base */
836 : 0 : BareFunctionType *clone_type_impl () const override
837 : : {
838 : 0 : return new BareFunctionType (*this);
839 : : }
840 : :
841 : : /* Use covariance to implement clone function as returning this object rather
842 : : * than base */
843 : 0 : BareFunctionType *clone_type_no_bounds_impl () const override
844 : : {
845 : 0 : return new BareFunctionType (*this);
846 : : }
847 : : };
848 : :
849 : : /* TODO: possible types
850 : : * struct type?
851 : : * "enum" (tagged union) type?
852 : : * C-like union type?
853 : : * function item type?
854 : : * closure expression types?
855 : : * primitive types (bool, int, float, char, str (the slice))
856 : : * Although supposedly TypePaths are used to reference these types (including
857 : : * primitives) */
858 : :
859 : : /* FIXME: Incomplete spec references:
860 : : * anonymous type parameters, aka "impl Trait in argument position" - impl then
861 : : * trait bounds abstract return types, aka "impl Trait in return position" -
862 : : * impl then trait bounds */
863 : : } // namespace HIR
864 : : } // namespace Rust
865 : :
866 : : #endif
|