Line data Source code
1 : // Copyright (C) 2020-2026 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 to_string () const override;
61 0 : std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
62 : {
63 57 : 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 to_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 257 : 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 to_string () const override
154 : {
155 0 : return "(" + type_in_parens->to_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 9 : 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 395 : 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 to_string () const override;
191 :
192 : void accept_vis (HIRFullVisitor &vis) override;
193 : void accept_vis (HIRTypeVisitor &vis) override;
194 :
195 622 : 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 38 : 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 3 : class NeverType : public TypeNoBounds
215 : {
216 : protected:
217 : /* Use covariance to implement clone function as returning this object rather
218 : * than base */
219 3 : 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 1 : std::string to_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 to_string () const override;
260 :
261 : void accept_vis (HIRFullVisitor &vis) override;
262 : void accept_vis (HIRTypeVisitor &vis) override;
263 :
264 3914 : Type &get_type () { return *type; }
265 :
266 6487 : 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 6487 : 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 0 : RawPointerType *clone_type_impl () const override
278 : {
279 0 : 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 110 : bool is_mut () const { return mut == Mutability::Mut; }
302 :
303 : // Returns whether the reference has a lifetime.
304 8445 : 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 to_string () const override;
322 :
323 : void accept_vis (HIRFullVisitor &vis) override;
324 : void accept_vis (HIRTypeVisitor &vis) override;
325 :
326 8336 : Lifetime &get_lifetime () { return lifetime.value (); }
327 109 : const Lifetime &get_lifetime () const { return lifetime.value (); }
328 :
329 4365 : Mutability get_mut () const { return mut; }
330 :
331 8336 : 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 672 : ReferenceType *clone_type_impl () const override
337 : {
338 672 : 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 to_string () const override;
371 :
372 : void accept_vis (HIRFullVisitor &vis) override;
373 : void accept_vis (HIRTypeVisitor &vis) override;
374 :
375 1133 : Type &get_element_type () { return *elem_type; }
376 :
377 3446 : 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 7 : 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 to_string () const override;
414 :
415 : void accept_vis (HIRFullVisitor &vis) override;
416 : void accept_vis (HIRTypeVisitor &vis) override;
417 :
418 1660 : 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 503 : 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 70 : 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 70 : InferredType *clone_type_impl () const override
442 : {
443 70 : 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 to_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 51 : ~MaybeNamedParam () = default;
489 :
490 : // Overloaded assignment operator with clone
491 : MaybeNamedParam &operator= (MaybeNamedParam const &other);
492 :
493 : // move constructors
494 51 : MaybeNamedParam (MaybeNamedParam &&other) = default;
495 : MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
496 :
497 : std::string to_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 65 : 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 108 : bool has_return_type () const { return return_type != nullptr; }
536 :
537 : // Whether the function has ForLifetimes.
538 2 : 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 to_string () const override;
557 :
558 : void accept_vis (HIRFullVisitor &vis) override;
559 : void accept_vis (HIRTypeVisitor &vis) override;
560 :
561 93 : 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 93 : 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 68 : 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 13 : BareFunctionType *clone_type_impl () const override
578 : {
579 13 : 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
|