Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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-hir-type-abstract.h"
23 : : #include "rust-common.h"
24 : : #include "rust-hir-trait-bound.h"
25 : : #include "rust-hir-item.h"
26 : :
27 : : namespace Rust {
28 : : namespace HIR {
29 : :
30 : : // An impl trait? Poor reference material here.
31 : : class ImplTraitType : public Type
32 : : {
33 : : // TypeParamBounds type_param_bounds;
34 : : // inlined form
35 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
36 : :
37 : : protected:
38 : : /* Use covariance to implement clone function as returning this object rather
39 : : * than base */
40 : 0 : ImplTraitType *clone_type_impl () const override
41 : : {
42 : 0 : return new ImplTraitType (*this);
43 : : }
44 : :
45 : : public:
46 : : ImplTraitType (Analysis::NodeMapping mappings,
47 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
48 : : location_t locus);
49 : :
50 : : // copy constructor with vector clone
51 : : ImplTraitType (ImplTraitType const &other);
52 : :
53 : : // overloaded assignment operator to clone
54 : : ImplTraitType &operator= (ImplTraitType const &other);
55 : :
56 : : // move constructors
57 : : ImplTraitType (ImplTraitType &&other) = default;
58 : : ImplTraitType &operator= (ImplTraitType &&other) = default;
59 : :
60 : : std::string as_string () const override;
61 : 0 : std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
62 : : {
63 : 0 : return type_param_bounds;
64 : : }
65 : : void accept_vis (HIRFullVisitor &vis) override;
66 : : void accept_vis (HIRTypeVisitor &vis) override;
67 : : };
68 : :
69 : : // An opaque value of another type that implements a set of traits
70 : : class TraitObjectType : public Type
71 : : {
72 : : bool has_dyn;
73 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
74 : :
75 : : protected:
76 : : /* Use covariance to implement clone function as returning this object rather
77 : : * than base */
78 : 14 : TraitObjectType *clone_type_impl () const override
79 : : {
80 : 14 : return new TraitObjectType (*this);
81 : : }
82 : :
83 : : public:
84 : : TraitObjectType (
85 : : Analysis::NodeMapping mappings,
86 : : std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
87 : : location_t locus, bool is_dyn_dispatch);
88 : :
89 : : // copy constructor with vector clone
90 : : TraitObjectType (TraitObjectType const &other);
91 : :
92 : : // overloaded assignment operator to clone
93 : : TraitObjectType &operator= (TraitObjectType const &other);
94 : :
95 : : // move constructors
96 : : TraitObjectType (TraitObjectType &&other) = default;
97 : : TraitObjectType &operator= (TraitObjectType &&other) = default;
98 : :
99 : : std::string as_string () const override;
100 : 0 : bool get_has_dyn () { return has_dyn; }
101 : : void accept_vis (HIRFullVisitor &vis) override;
102 : : void accept_vis (HIRTypeVisitor &vis) override;
103 : :
104 : 0 : std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
105 : : {
106 : 178 : return type_param_bounds;
107 : : }
108 : :
109 : : const std::vector<std::unique_ptr<TypeParamBound>> &
110 : : get_type_param_bounds () const
111 : : {
112 : : return type_param_bounds;
113 : : }
114 : : };
115 : :
116 : : // A type with parentheses around it, used to avoid ambiguity.
117 : : class ParenthesisedType : public TypeNoBounds
118 : : {
119 : : std::unique_ptr<Type> type_in_parens;
120 : :
121 : : protected:
122 : : /* Use covariance to implement clone function as returning this object rather
123 : : * than base */
124 : 0 : ParenthesisedType *clone_type_impl () const override
125 : : {
126 : 0 : return new ParenthesisedType (*this);
127 : : }
128 : :
129 : : /* Use covariance to implement clone function as returning this object rather
130 : : * than base */
131 : 0 : ParenthesisedType *clone_type_no_bounds_impl () const override
132 : : {
133 : 0 : return new ParenthesisedType (*this);
134 : : }
135 : :
136 : : public:
137 : : // Constructor uses Type pointer for polymorphism
138 : : ParenthesisedType (Analysis::NodeMapping mappings,
139 : : std::unique_ptr<Type> type_inside_parens,
140 : : location_t locus);
141 : :
142 : : /* Copy constructor uses custom deep copy method for type to preserve
143 : : * polymorphism */
144 : : ParenthesisedType (ParenthesisedType const &other);
145 : :
146 : : // overload assignment operator to use custom clone method
147 : : ParenthesisedType &operator= (ParenthesisedType const &other);
148 : :
149 : : // default move semantics
150 : : ParenthesisedType (ParenthesisedType &&other) = default;
151 : : ParenthesisedType &operator= (ParenthesisedType &&other) = default;
152 : :
153 : 0 : std::string as_string () const override
154 : : {
155 : 0 : return "(" + type_in_parens->as_string () + ")";
156 : : }
157 : :
158 : : // Creates a trait bound (clone of this one's trait bound) - HACK
159 : : std::unique_ptr<TraitBound>
160 : : to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override;
161 : :
162 : 2 : Type &get_type_in_parens () { return *type_in_parens; }
163 : : void accept_vis (HIRFullVisitor &vis) override;
164 : : void accept_vis (HIRTypeVisitor &vis) override;
165 : : };
166 : :
167 : : /* A type consisting of the "product" of others (the tuple's elements) in a
168 : : * specific order */
169 : : class TupleType : public TypeNoBounds
170 : : {
171 : : std::vector<std::unique_ptr<Type>> elems;
172 : :
173 : : public:
174 : : // Returns whether the tuple type is the unit type, i.e. has no elements.
175 : 449 : bool is_unit_type () const { return elems.empty (); }
176 : :
177 : : TupleType (Analysis::NodeMapping mappings,
178 : : std::vector<std::unique_ptr<Type>> elems, location_t locus);
179 : :
180 : : // copy constructor with vector clone
181 : : TupleType (TupleType const &other);
182 : :
183 : : // overloaded assignment operator to clone
184 : : TupleType &operator= (TupleType const &other);
185 : :
186 : : // move constructors
187 : : TupleType (TupleType &&other) = default;
188 : : TupleType &operator= (TupleType &&other) = default;
189 : :
190 : : std::string as_string () const override;
191 : :
192 : : void accept_vis (HIRFullVisitor &vis) override;
193 : : void accept_vis (HIRTypeVisitor &vis) override;
194 : :
195 : 346 : std::vector<std::unique_ptr<Type>> &get_elems () { return elems; }
196 : : const std::vector<std::unique_ptr<Type>> &get_elems () const { return elems; }
197 : :
198 : : protected:
199 : : /* Use covariance to implement clone function as returning this object rather
200 : : * than base */
201 : 48 : TupleType *clone_type_impl () const override { return new TupleType (*this); }
202 : :
203 : : /* Use covariance to implement clone function as returning this object rather
204 : : * than base */
205 : 0 : TupleType *clone_type_no_bounds_impl () const override
206 : : {
207 : 0 : return new TupleType (*this);
208 : : }
209 : : };
210 : :
211 : : /* A type with no values, representing the result of computations that never
212 : : * complete. Expressions of NeverType can be coerced into any other types.
213 : : * Represented as "!". */
214 : 6 : class NeverType : public TypeNoBounds
215 : : {
216 : : protected:
217 : : /* Use covariance to implement clone function as returning this object rather
218 : : * than base */
219 : 6 : NeverType *clone_type_impl () const override { return new NeverType (*this); }
220 : :
221 : : /* Use covariance to implement clone function as returning this object rather
222 : : * than base */
223 : 0 : NeverType *clone_type_no_bounds_impl () const override
224 : : {
225 : 0 : return new NeverType (*this);
226 : : }
227 : :
228 : : public:
229 : : NeverType (Analysis::NodeMapping mappings, location_t locus);
230 : :
231 : 2 : std::string as_string () const override { return "! (never type)"; }
232 : :
233 : : void accept_vis (HIRFullVisitor &vis) override;
234 : : void accept_vis (HIRTypeVisitor &vis) override;
235 : : };
236 : :
237 : : // A type consisting of a pointer without safety or liveness guarantees
238 : : class RawPointerType : public TypeNoBounds
239 : : {
240 : : private:
241 : : Mutability mut;
242 : : std::unique_ptr<Type> type;
243 : :
244 : : public:
245 : : // Constructor requires pointer for polymorphism reasons
246 : : RawPointerType (Analysis::NodeMapping mappings, Mutability mut,
247 : : std::unique_ptr<Type> type, location_t locus);
248 : :
249 : : // Copy constructor calls custom polymorphic clone function
250 : : RawPointerType (RawPointerType const &other);
251 : :
252 : : // overload assignment operator to use custom clone method
253 : : RawPointerType &operator= (RawPointerType const &other);
254 : :
255 : : // default move semantics
256 : : RawPointerType (RawPointerType &&other) = default;
257 : : RawPointerType &operator= (RawPointerType &&other) = default;
258 : :
259 : : std::string as_string () const override;
260 : :
261 : : void accept_vis (HIRFullVisitor &vis) override;
262 : : void accept_vis (HIRTypeVisitor &vis) override;
263 : :
264 : 0 : Type &get_type () { return *type; }
265 : :
266 : 5925 : Mutability get_mut () const { return mut; }
267 : :
268 : 0 : bool is_mut () const { return mut == Mutability::Mut; }
269 : :
270 : : bool is_const () const { return mut == Mutability::Imm; }
271 : :
272 : 5925 : Type &get_base_type () { return *type; }
273 : :
274 : : protected:
275 : : /* Use covariance to implement clone function as returning this object rather
276 : : * than base */
277 : 42 : RawPointerType *clone_type_impl () const override
278 : : {
279 : 42 : return new RawPointerType (*this);
280 : : }
281 : :
282 : : /* Use covariance to implement clone function as returning this object rather
283 : : * than base */
284 : 0 : RawPointerType *clone_type_no_bounds_impl () const override
285 : : {
286 : 0 : return new RawPointerType (*this);
287 : : }
288 : : };
289 : :
290 : : // A type pointing to memory owned by another value
291 : : class ReferenceType : public TypeNoBounds
292 : : {
293 : : // bool has_lifetime; // TODO: handle in lifetime or something?
294 : : tl::optional<Lifetime> lifetime;
295 : :
296 : : Mutability mut;
297 : : std::unique_ptr<Type> type;
298 : :
299 : : public:
300 : : // Returns whether the reference is mutable or immutable.
301 : 115 : bool is_mut () const { return mut == Mutability::Mut; }
302 : :
303 : : // Returns whether the reference has a lifetime.
304 : 2677 : bool has_lifetime () const { return lifetime.has_value (); }
305 : :
306 : : // Constructor
307 : : ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
308 : : std::unique_ptr<Type> type_no_bounds, location_t locus,
309 : : tl::optional<Lifetime> lifetime);
310 : :
311 : : // Copy constructor with custom clone method
312 : : ReferenceType (ReferenceType const &other);
313 : :
314 : : // Operator overload assignment operator to custom clone the unique pointer
315 : : ReferenceType &operator= (ReferenceType const &other);
316 : :
317 : : // move constructors
318 : : ReferenceType (ReferenceType &&other) = default;
319 : : ReferenceType &operator= (ReferenceType &&other) = default;
320 : :
321 : : std::string as_string () const override;
322 : :
323 : : void accept_vis (HIRFullVisitor &vis) override;
324 : : void accept_vis (HIRTypeVisitor &vis) override;
325 : :
326 : 2564 : Lifetime &get_lifetime () { return lifetime.value (); }
327 : 113 : const Lifetime &get_lifetime () const { return lifetime.value (); }
328 : :
329 : 2562 : Mutability get_mut () const { return mut; }
330 : :
331 : 2564 : Type &get_base_type () { return *type; }
332 : :
333 : : protected:
334 : : /* Use covariance to implement clone function as returning this object rather
335 : : * than base */
336 : 1076 : ReferenceType *clone_type_impl () const override
337 : : {
338 : 1076 : return new ReferenceType (*this);
339 : : }
340 : :
341 : : /* Use covariance to implement clone function as returning this object rather
342 : : * than base */
343 : 0 : ReferenceType *clone_type_no_bounds_impl () const override
344 : : {
345 : 0 : return new ReferenceType (*this);
346 : : }
347 : : };
348 : :
349 : : // A fixed-size sequence of elements of a specified type
350 : : class ArrayType : public TypeNoBounds
351 : : {
352 : : std::unique_ptr<Type> elem_type;
353 : : std::unique_ptr<Expr> size;
354 : :
355 : : public:
356 : : // Constructor requires pointers for polymorphism
357 : : ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
358 : : std::unique_ptr<Expr> array_size, location_t locus);
359 : :
360 : : // Copy constructor requires deep copies of both unique pointers
361 : : ArrayType (ArrayType const &other);
362 : :
363 : : // Overload assignment operator to deep copy pointers
364 : : ArrayType &operator= (ArrayType const &other);
365 : :
366 : : // move constructors
367 : : ArrayType (ArrayType &&other) = default;
368 : : ArrayType &operator= (ArrayType &&other) = default;
369 : :
370 : : std::string as_string () const override;
371 : :
372 : : void accept_vis (HIRFullVisitor &vis) override;
373 : : void accept_vis (HIRTypeVisitor &vis) override;
374 : :
375 : 674 : Type &get_element_type () { return *elem_type; }
376 : :
377 : 3082 : Expr &get_size_expr () { return *size; }
378 : :
379 : : protected:
380 : : /* Use covariance to implement clone function as returning this object rather
381 : : * than base */
382 : 0 : ArrayType *clone_type_impl () const override { return new ArrayType (*this); }
383 : :
384 : : /* Use covariance to implement clone function as returning this object rather
385 : : * than base */
386 : 0 : ArrayType *clone_type_no_bounds_impl () const override
387 : : {
388 : 0 : return new ArrayType (*this);
389 : : }
390 : : };
391 : :
392 : : /* A dynamically-sized type representing a "view" into a sequence of elements of
393 : : * a type */
394 : : class SliceType : public TypeNoBounds
395 : : {
396 : : std::unique_ptr<Type> elem_type;
397 : :
398 : : public:
399 : : // Constructor requires pointer for polymorphism
400 : : SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
401 : : location_t locus);
402 : :
403 : : // Copy constructor requires deep copy of Type smart pointer
404 : : SliceType (SliceType const &other);
405 : :
406 : : // Overload assignment operator to deep copy
407 : : SliceType &operator= (SliceType const &other);
408 : :
409 : : // move constructors
410 : : SliceType (SliceType &&other) = default;
411 : : SliceType &operator= (SliceType &&other) = default;
412 : :
413 : : std::string as_string () const override;
414 : :
415 : : void accept_vis (HIRFullVisitor &vis) override;
416 : : void accept_vis (HIRTypeVisitor &vis) override;
417 : :
418 : 802 : Type &get_element_type () { return *elem_type; }
419 : :
420 : : protected:
421 : : /* Use covariance to implement clone function as returning this object rather
422 : : * than base */
423 : 493 : SliceType *clone_type_impl () const override { return new SliceType (*this); }
424 : :
425 : : /* Use covariance to implement clone function as returning this object rather
426 : : * than base */
427 : 0 : SliceType *clone_type_no_bounds_impl () const override
428 : : {
429 : 0 : return new SliceType (*this);
430 : : }
431 : : };
432 : :
433 : : /* Type used in generic arguments to explicitly request type inference (wildcard
434 : : * pattern) */
435 : 82 : class InferredType : public TypeNoBounds
436 : : {
437 : : // e.g. Vec<_> = whatever
438 : : protected:
439 : : /* Use covariance to implement clone function as returning this object rather
440 : : * than base */
441 : 82 : InferredType *clone_type_impl () const override
442 : : {
443 : 82 : return new InferredType (*this);
444 : : }
445 : :
446 : : /* Use covariance to implement clone function as returning this object rather
447 : : * than base */
448 : 0 : InferredType *clone_type_no_bounds_impl () const override
449 : : {
450 : 0 : return new InferredType (*this);
451 : : }
452 : :
453 : : public:
454 : : InferredType (Analysis::NodeMapping mappings, location_t locus);
455 : :
456 : : std::string as_string () const override;
457 : :
458 : : void accept_vis (HIRFullVisitor &vis) override;
459 : : void accept_vis (HIRTypeVisitor &vis) override;
460 : : };
461 : :
462 : : // A possibly named param used in a BaseFunctionType
463 : : struct MaybeNamedParam
464 : : {
465 : : public:
466 : : enum ParamKind
467 : : {
468 : : UNNAMED,
469 : : IDENTIFIER,
470 : : WILDCARD
471 : : };
472 : :
473 : : private:
474 : : std::unique_ptr<Type> param_type;
475 : :
476 : : ParamKind param_kind;
477 : : Identifier name; // technically, can be an identifier or '_'
478 : :
479 : : location_t locus;
480 : :
481 : : public:
482 : : MaybeNamedParam (Identifier name, ParamKind param_kind,
483 : : std::unique_ptr<Type> param_type, location_t locus);
484 : :
485 : : // Copy constructor with clone
486 : : MaybeNamedParam (MaybeNamedParam const &other);
487 : :
488 : 72 : ~MaybeNamedParam () = default;
489 : :
490 : : // Overloaded assignment operator with clone
491 : : MaybeNamedParam &operator= (MaybeNamedParam const &other);
492 : :
493 : : // move constructors
494 : 72 : MaybeNamedParam (MaybeNamedParam &&other) = default;
495 : : MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
496 : :
497 : : std::string as_string () const;
498 : :
499 : : // Returns whether the param is in an error state.
500 : : bool is_error () const { return param_type == nullptr; }
501 : :
502 : : // Creates an error state param.
503 : : static MaybeNamedParam create_error ()
504 : : {
505 : : return MaybeNamedParam ({""}, UNNAMED, nullptr, UNDEF_LOCATION);
506 : : }
507 : :
508 : : location_t get_locus () const { return locus; }
509 : :
510 : 60 : Type &get_type () { return *param_type; }
511 : :
512 : 0 : ParamKind get_param_kind () const { return param_kind; }
513 : :
514 : 0 : Identifier get_name () const { return name; }
515 : : };
516 : :
517 : : std::string enum_to_str (MaybeNamedParam::ParamKind);
518 : :
519 : : /* A function pointer type - can be created via coercion from function items and
520 : : * non- capturing closures. */
521 : : class BareFunctionType : public TypeNoBounds
522 : : {
523 : : // bool has_for_lifetimes;
524 : : // ForLifetimes for_lifetimes;
525 : : std::vector<LifetimeParam> for_lifetimes; // inlined version
526 : :
527 : : FunctionQualifiers function_qualifiers;
528 : : std::vector<MaybeNamedParam> params;
529 : : bool is_variadic;
530 : :
531 : : std::unique_ptr<Type> return_type; // inlined version
532 : :
533 : : public:
534 : : // Whether a return type is defined with the function.
535 : 66 : bool has_return_type () const { return return_type != nullptr; }
536 : :
537 : : // Whether the function has ForLifetimes.
538 : 0 : bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
539 : :
540 : : BareFunctionType (Analysis::NodeMapping mappings,
541 : : std::vector<LifetimeParam> lifetime_params,
542 : : FunctionQualifiers qualifiers,
543 : : std::vector<MaybeNamedParam> named_params, bool is_variadic,
544 : : std::unique_ptr<Type> type, location_t locus);
545 : :
546 : : // Copy constructor with clone
547 : : BareFunctionType (BareFunctionType const &other);
548 : :
549 : : // Overload assignment operator to deep copy
550 : : BareFunctionType &operator= (BareFunctionType const &other);
551 : :
552 : : // move constructors
553 : : BareFunctionType (BareFunctionType &&other) = default;
554 : : BareFunctionType &operator= (BareFunctionType &&other) = default;
555 : :
556 : : std::string as_string () const override;
557 : :
558 : : void accept_vis (HIRFullVisitor &vis) override;
559 : : void accept_vis (HIRTypeVisitor &vis) override;
560 : :
561 : 64 : std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
562 : 0 : bool get_is_variadic () { return is_variadic; }
563 : 0 : FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; }
564 : :
565 : 64 : std::vector<MaybeNamedParam> &get_function_params () { return params; }
566 : : const std::vector<MaybeNamedParam> &get_function_params () const
567 : : {
568 : : return params;
569 : : }
570 : :
571 : : // TODO: would a "vis_type" be better?
572 : 42 : Type &get_return_type () { return *return_type; }
573 : :
574 : : protected:
575 : : /* Use covariance to implement clone function as returning this object rather
576 : : * than base */
577 : 2 : BareFunctionType *clone_type_impl () const override
578 : : {
579 : 2 : return new BareFunctionType (*this);
580 : : }
581 : :
582 : : /* Use covariance to implement clone function as returning this object rather
583 : : * than base */
584 : 0 : BareFunctionType *clone_type_no_bounds_impl () const override
585 : : {
586 : 0 : return new BareFunctionType (*this);
587 : : }
588 : : };
589 : :
590 : : /* TODO: possible types
591 : : * struct type?
592 : : * "enum" (tagged union) type?
593 : : * C-like union type?
594 : : * function item type?
595 : : * closure expression types?
596 : : * primitive types (bool, int, float, char, str (the slice))
597 : : * Although supposedly TypePaths are used to reference these types (including
598 : : * primitives) */
599 : :
600 : : /* FIXME: Incomplete spec references:
601 : : * anonymous type parameters, aka "impl Trait in argument position" - impl then
602 : : * trait bounds abstract return types, aka "impl Trait in return position" -
603 : : * impl then trait bounds */
604 : : } // namespace HIR
605 : : } // namespace Rust
606 : :
607 : : #endif
|