]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/typecheck/rust-tyty.h
Ada: Remove left-overs of front-end exception mechanism
[thirdparty/gcc.git] / gcc / rust / typecheck / rust-tyty.h
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_TYTY
20 #define RUST_TYTY
21
22 #include "rust-hir-map.h"
23 #include "rust-common.h"
24 #include "rust-identifier.h"
25 #include "rust-abi.h"
26 #include "rust-tyty-bounds.h"
27 #include "rust-tyty-util.h"
28 #include "rust-tyty-subst.h"
29 #include "rust-tyty-region.h"
30 #include "rust-system.h"
31 #include "rust-hir.h"
32
33 namespace Rust {
34
35 namespace Resolver {
36 class TraitReference;
37
38 class TraitItemReference;
39
40 class AssociatedImplTrait;
41 } // namespace Resolver
42
43 namespace TyTy {
44 class ClosureType;
45 class FnPtr;
46 class FnType;
47 class CallableTypeInterface;
48
49 // https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
50 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
51 enum TypeKind
52 {
53 INFER,
54 ADT,
55 STR,
56 REF,
57 POINTER,
58 PARAM,
59 ARRAY,
60 SLICE,
61 FNDEF,
62 FNPTR,
63 TUPLE,
64 BOOL,
65 CHAR,
66 INT,
67 UINT,
68 FLOAT,
69 USIZE,
70 ISIZE,
71 NEVER,
72 PLACEHOLDER,
73 PROJECTION,
74 DYNAMIC,
75 CLOSURE,
76 OPAQUE,
77 // there are more to add...
78 ERROR
79 };
80
81 extern bool
82 is_primitive_type_kind (TypeKind kind);
83
84 class TypeKindFormat
85 {
86 public:
87 static std::string to_string (TypeKind kind);
88 };
89
90 class TyVisitor;
91 class TyConstVisitor;
92 class BaseType : public TypeBoundsMappings
93 {
94 public:
95 virtual ~BaseType ();
96
97 HirId get_ref () const;
98 void set_ref (HirId id);
99
100 HirId get_ty_ref () const;
101 void set_ty_ref (HirId id);
102
103 HirId get_orig_ref () const;
104
105 virtual void accept_vis (TyVisitor &vis) = 0;
106 virtual void accept_vis (TyConstVisitor &vis) const = 0;
107
108 virtual std::string as_string () const = 0;
109 virtual std::string get_name () const = 0;
110
111 // similar to unify but does not actually perform type unification but
112 // determines whether they are compatible. Consider the following
113 //
114 // fn foo<T>() -> T { ... }
115 // fn foo() -> i32 { ... }
116 //
117 // when the function has been substituted they can be considered equal.
118 //
119 // It can also be used to optional emit errors for trait item compatibility
120 // checks
121 virtual bool can_eq (const BaseType *other, bool emit_errors) const = 0;
122
123 // Check value equality between two ty. Type inference rules are ignored. Two
124 // ty are considered equal if they're of the same kind, and
125 // 1. (For ADTs, arrays, tuples, refs) have the same underlying ty
126 // 2. (For functions) have the same signature
127 virtual bool is_equal (const BaseType &other) const;
128
129 bool satisfies_bound (const TypeBoundPredicate &predicate,
130 bool emit_error) const;
131
132 bool bounds_compatible (const BaseType &other, location_t locus,
133 bool emit_error) const;
134
135 void inherit_bounds (const BaseType &other);
136
137 void inherit_bounds (
138 const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
139
140 // contains_infer checks if there is an inference variable inside the type
141 const TyTy::BaseType *contains_infer () const;
142
143 // is_unit returns whether this is just a unit-struct
144 bool is_unit () const;
145
146 // is_concrete returns true if the type is fully resolved to concrete
147 // primitives
148 bool is_concrete () const;
149
150 // return the type-kind
151 TypeKind get_kind () const;
152
153 // monomorphized clone is a clone which destructures the types to get rid of
154 // generics
155 BaseType *monomorphized_clone () const;
156
157 // get_combined_refs returns the chain of node refs involved in unification
158 std::set<HirId> get_combined_refs () const;
159
160 void append_reference (HirId id);
161
162 std::string mappings_str () const;
163
164 std::string debug_str () const;
165
166 void debug () const;
167
168 // FIXME this will eventually go away
169 const BaseType *get_root () const;
170
171 // This will get the monomorphized type from Params, Placeholders or
172 // Projections if available or error
173 BaseType *destructure ();
174 const BaseType *destructure () const;
175
176 const RustIdent &get_ident () const;
177 location_t get_locus () const;
178
179 bool has_substitutions_defined () const;
180 bool needs_generic_substitutions () const;
181 const SubstitutionArgumentMappings &get_subst_argument_mappings () const;
182
183 std::string mangle_string () const
184 {
185 return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
186 + mappings_str () + ":" + bounds_as_string ();
187 }
188
189 /* Returns a pointer to a clone of this. The caller is responsible for
190 * releasing the memory of the returned ty. */
191 virtual BaseType *clone () const = 0;
192
193 // Check if TyTy::BaseType is of a specific type.
194 template <typename T> WARN_UNUSED_RESULT bool is () const
195 {
196 static_assert (std::is_base_of<BaseType, T>::value,
197 "Can only safely cast to TyTy types.");
198 return this->get_kind () == T::KIND;
199 }
200
201 template <typename T> T *as () const
202 {
203 static_assert (std::is_base_of<BaseType, T>::value,
204 "Can only safely cast to TyTy types.");
205 rust_assert (this->is<T> ());
206 return static_cast<T *> (this);
207 }
208
209 template <typename T> T *as ()
210 {
211 static_assert (std::is_base_of<BaseType, T>::value,
212 "Can only safely cast to TyTy types.");
213 rust_assert (this->is<T> ());
214 return static_cast<T *> (this);
215 }
216
217 // Check if TyTy::BaseType is of a specific type and convert it to that type
218 // if so.
219 // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler
220 // RTTI.
221 template <typename T> T *try_as () const
222 {
223 static_assert (std::is_base_of<BaseType, T>::value,
224 "Can only safely cast to TyTy types.");
225 if (!this->is<T> ())
226 return nullptr;
227
228 return static_cast<T *> (this);
229 }
230
231 // See above.
232 template <typename T> T *try_as ()
233 {
234 static_assert (std::is_base_of<BaseType, T>::value,
235 "Can only safely cast to TyTy types.");
236 if (!this->is<T> ())
237 return nullptr;
238
239 return static_cast<T *> (this);
240 }
241
242 protected:
243 BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
244 std::set<HirId> refs = std::set<HirId> ());
245
246 BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
247 std::vector<TypeBoundPredicate> specified_bounds,
248 std::set<HirId> refs = std::set<HirId> ());
249
250 TypeKind kind;
251 HirId ref;
252 HirId ty_ref;
253 const HirId orig_ref;
254 std::set<HirId> combined;
255 RustIdent ident;
256
257 Analysis::Mappings &mappings;
258 };
259
260 /** Unified interface for all function-like types. */
261 class CallableTypeInterface : public BaseType
262 {
263 public:
264 explicit CallableTypeInterface (HirId ref, HirId ty_ref, TypeKind kind,
265 RustIdent ident,
266 std::set<HirId> refs = std::set<HirId> ())
267 : BaseType (ref, ty_ref, kind, ident, refs)
268 {}
269
270 WARN_UNUSED_RESULT virtual size_t get_num_params () const = 0;
271 WARN_UNUSED_RESULT virtual BaseType *
272 get_param_type_at (size_t index) const = 0;
273 WARN_UNUSED_RESULT virtual BaseType *get_return_type () const = 0;
274 };
275
276 class InferType : public BaseType
277 {
278 public:
279 static constexpr auto KIND = TypeKind::INFER;
280
281 enum InferTypeKind
282 {
283 GENERAL,
284 INTEGRAL,
285 FLOAT
286 };
287
288 struct TypeHint
289 {
290 enum SignedHint
291 {
292 SIGNED,
293 UNSIGNED,
294
295 UNKNOWN
296 };
297 enum SizeHint
298 {
299 S8,
300 S16,
301 S32,
302 S64,
303 S128,
304 SUNKNOWN
305 };
306
307 TyTy::TypeKind kind;
308 SignedHint shint;
309 SizeHint szhint;
310
311 static TypeHint Default ()
312 {
313 return TypeHint{TypeKind::ERROR, UNKNOWN, SUNKNOWN};
314 }
315 };
316
317 InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
318 location_t locus, std::set<HirId> refs = std::set<HirId> ());
319
320 InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, TypeHint hint,
321 location_t locus, std::set<HirId> refs = std::set<HirId> ());
322
323 void accept_vis (TyVisitor &vis) override;
324
325 void accept_vis (TyConstVisitor &vis) const override;
326
327 std::string as_string () const override;
328
329 bool can_eq (const BaseType *other, bool emit_errors) const override final;
330
331 BaseType *clone () const final override;
332
333 InferTypeKind get_infer_kind () const;
334
335 std::string get_name () const override final;
336
337 bool default_type (BaseType **type) const;
338
339 void apply_primitive_type_hint (const TyTy::BaseType &hint);
340
341 private:
342 InferTypeKind infer_kind;
343 TypeHint default_hint;
344 };
345
346 class ErrorType : public BaseType
347 {
348 public:
349 static constexpr auto KIND = TypeKind::ERROR;
350
351 ErrorType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
352
353 ErrorType (HirId ref, HirId ty_ref,
354 std::set<HirId> refs = std::set<HirId> ());
355
356 void accept_vis (TyVisitor &vis) override;
357 void accept_vis (TyConstVisitor &vis) const override;
358
359 std::string as_string () const override;
360
361 bool can_eq (const BaseType *other, bool emit_errors) const override final;
362
363 BaseType *clone () const final override;
364
365 std::string get_name () const override final;
366 };
367
368 class ParamType : public BaseType
369 {
370 public:
371 static constexpr auto KIND = TypeKind::PARAM;
372
373 ParamType (std::string symbol, location_t locus, HirId ref,
374 HIR::GenericParam &param,
375 std::vector<TypeBoundPredicate> specified_bounds,
376 std::set<HirId> refs = std::set<HirId> ());
377
378 ParamType (bool is_trait_self, std::string symbol, location_t locus,
379 HirId ref, HirId ty_ref, HIR::GenericParam &param,
380 std::vector<TypeBoundPredicate> specified_bounds,
381 std::set<HirId> refs = std::set<HirId> ());
382
383 void accept_vis (TyVisitor &vis) override;
384 void accept_vis (TyConstVisitor &vis) const override;
385
386 std::string as_string () const override;
387
388 bool can_eq (const BaseType *other, bool emit_errors) const override final;
389
390 BaseType *clone () const final override;
391
392 std::string get_symbol () const;
393
394 HIR::GenericParam &get_generic_param ();
395
396 bool can_resolve () const;
397
398 BaseType *resolve () const;
399
400 std::string get_name () const override final;
401
402 bool is_equal (const BaseType &other) const override;
403
404 ParamType *handle_substitions (SubstitutionArgumentMappings &mappings);
405
406 void set_implicit_self_trait ();
407 bool is_implicit_self_trait () const;
408
409 private:
410 bool is_trait_self;
411 std::string symbol;
412 HIR::GenericParam &param;
413 };
414
415 class OpaqueType : public BaseType
416 {
417 public:
418 static constexpr auto KIND = TypeKind::OPAQUE;
419
420 OpaqueType (location_t locus, HirId ref,
421 std::vector<TypeBoundPredicate> specified_bounds,
422 std::set<HirId> refs = std::set<HirId> ());
423
424 OpaqueType (location_t locus, HirId ref, HirId ty_ref,
425 std::vector<TypeBoundPredicate> specified_bounds,
426 std::set<HirId> refs = std::set<HirId> ());
427
428 void accept_vis (TyVisitor &vis) override;
429 void accept_vis (TyConstVisitor &vis) const override;
430
431 std::string as_string () const override;
432
433 bool can_eq (const BaseType *other, bool emit_errors) const override final;
434
435 BaseType *clone () const final override;
436
437 bool can_resolve () const;
438
439 BaseType *resolve () const;
440
441 std::string get_name () const override final;
442
443 bool is_equal (const BaseType &other) const override;
444
445 OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings);
446 };
447
448 class StructFieldType
449 {
450 public:
451 StructFieldType (HirId ref, std::string name, BaseType *ty, location_t locus);
452
453 HirId get_ref () const;
454
455 bool is_equal (const StructFieldType &other) const;
456
457 std::string get_name () const;
458
459 BaseType *get_field_type () const;
460 void set_field_type (BaseType *fty);
461
462 StructFieldType *clone () const;
463 StructFieldType *monomorphized_clone () const;
464
465 void debug () const;
466 location_t get_locus () const;
467 std::string as_string () const;
468
469 private:
470 HirId ref;
471 std::string name;
472 BaseType *ty;
473 location_t locus;
474 };
475
476 class TupleType : public BaseType
477 {
478 public:
479 static constexpr auto KIND = TypeKind::TUPLE;
480
481 TupleType (HirId ref, location_t locus,
482 std::vector<TyVar> fields = std::vector<TyVar> (),
483 std::set<HirId> refs = std::set<HirId> ());
484
485 TupleType (HirId ref, HirId ty_ref, location_t locus,
486 std::vector<TyVar> fields = std::vector<TyVar> (),
487 std::set<HirId> refs = std::set<HirId> ());
488
489 static TupleType *get_unit_type ();
490
491 void accept_vis (TyVisitor &vis) override;
492 void accept_vis (TyConstVisitor &vis) const override;
493
494 std::string as_string () const override;
495
496 bool can_eq (const BaseType *other, bool emit_errors) const override final;
497
498 bool is_equal (const BaseType &other) const override;
499
500 size_t num_fields () const;
501
502 BaseType *get_field (size_t index) const;
503
504 BaseType *clone () const final override;
505
506 const std::vector<TyVar> &get_fields () const;
507
508 std::string get_name () const override final;
509
510 TupleType *handle_substitions (SubstitutionArgumentMappings &mappings);
511
512 private:
513 std::vector<TyVar> fields;
514 };
515
516 class TypeBoundPredicate : public SubstitutionRef
517 {
518 public:
519 TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
520 BoundPolarity polarity, location_t locus);
521
522 TypeBoundPredicate (DefId reference,
523 std::vector<SubstitutionParamMapping> substitutions,
524 BoundPolarity polarity, location_t locus);
525
526 TypeBoundPredicate (const TypeBoundPredicate &other);
527
528 virtual ~TypeBoundPredicate (){};
529
530 TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
531
532 static TypeBoundPredicate error ();
533
534 std::string as_string () const;
535
536 std::string as_name () const;
537
538 const Resolver::TraitReference *get () const;
539
540 location_t get_locus () const { return locus; }
541
542 std::string get_name () const;
543
544 // check that this predicate is object-safe see:
545 // https://doc.rust-lang.org/reference/items/traits.html#object-safety
546 bool is_object_safe (bool emit_error, location_t locus) const;
547
548 void apply_generic_arguments (HIR::GenericArgs *generic_args,
549 bool has_associated_self);
550
551 void apply_argument_mappings (SubstitutionArgumentMappings &arguments);
552
553 bool contains_item (const std::string &search) const;
554
555 TypeBoundPredicateItem
556 lookup_associated_item (const std::string &search) const;
557
558 TypeBoundPredicateItem
559 lookup_associated_item (const Resolver::TraitItemReference *ref) const;
560
561 // WARNING THIS WILL ALWAYS RETURN NULLPTR
562 BaseType *
563 handle_substitions (SubstitutionArgumentMappings &mappings) override final;
564
565 bool is_error () const;
566
567 bool requires_generic_args () const;
568
569 bool contains_associated_types () const;
570
571 DefId get_id () const { return reference; }
572
573 BoundPolarity get_polarity () const { return polarity; }
574
575 std::vector<TypeBoundPredicateItem> get_associated_type_items ();
576
577 size_t get_num_associated_bindings () const override final;
578
579 TypeBoundPredicateItem
580 lookup_associated_type (const std::string &search) override final;
581
582 bool is_equal (const TypeBoundPredicate &other) const;
583
584 bool validate_type_implements_super_traits (TyTy::BaseType &self,
585 HIR::Type &impl_type,
586 HIR::Type &trait) const;
587
588 bool validate_type_implements_this (TyTy::BaseType &self,
589 HIR::Type &impl_type,
590 HIR::Type &trait) const;
591
592 private:
593 struct mark_is_error
594 {
595 };
596
597 TypeBoundPredicate (mark_is_error);
598
599 DefId reference;
600 location_t locus;
601 bool error_flag;
602 BoundPolarity polarity;
603 std::vector<TyTy::TypeBoundPredicate> super_traits;
604 };
605
606 class TypeBoundPredicateItem
607 {
608 public:
609 TypeBoundPredicateItem (const TypeBoundPredicate parent,
610 const Resolver::TraitItemReference *trait_item_ref);
611
612 TypeBoundPredicateItem (const TypeBoundPredicateItem &other);
613
614 TypeBoundPredicateItem &operator= (const TypeBoundPredicateItem &other);
615
616 static TypeBoundPredicateItem error ();
617
618 bool is_error () const;
619
620 BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
621
622 const Resolver::TraitItemReference *get_raw_item () const;
623
624 bool needs_implementation () const;
625
626 const TypeBoundPredicate *get_parent () const;
627
628 location_t get_locus () const;
629
630 private:
631 TypeBoundPredicate parent;
632 const Resolver::TraitItemReference *trait_item_ref;
633 };
634
635 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
636 class VariantDef
637 {
638 public:
639 enum VariantType
640 {
641 NUM,
642 TUPLE,
643 STRUCT
644 };
645
646 static std::string variant_type_string (VariantType type);
647
648 VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
649 tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant);
650
651 VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
652 VariantType type,
653 tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
654 std::vector<StructFieldType *> fields);
655
656 static VariantDef &get_error_node ();
657 bool is_error () const;
658
659 HirId get_id () const;
660 DefId get_defid () const;
661
662 VariantType get_variant_type () const;
663 bool is_data_variant () const;
664 bool is_dataless_variant () const;
665
666 std::string get_identifier () const;
667
668 size_t num_fields () const;
669 StructFieldType *get_field_at_index (size_t index);
670
671 std::vector<StructFieldType *> &get_fields ();
672
673 bool lookup_field (const std::string &lookup, StructFieldType **field_lookup,
674 size_t *index) const;
675
676 bool has_discriminant () const;
677
678 HIR::Expr &get_discriminant ();
679 const HIR::Expr &get_discriminant () const;
680
681 std::string as_string () const;
682
683 bool is_equal (const VariantDef &other) const;
684
685 VariantDef *clone () const;
686
687 VariantDef *monomorphized_clone () const;
688
689 const RustIdent &get_ident () const;
690
691 private:
692 HirId id;
693 DefId defid;
694 std::string identifier;
695 RustIdent ident;
696 VariantType type;
697
698 // can either be a structure or a discriminant value
699 tl::optional<std::unique_ptr<HIR::Expr>> discriminant;
700
701 std::vector<StructFieldType *> fields;
702 };
703
704 class ADTType : public BaseType, public SubstitutionRef
705 {
706 public:
707 static constexpr auto KIND = TypeKind::ADT;
708
709 enum ADTKind
710 {
711 STRUCT_STRUCT,
712 TUPLE_STRUCT,
713 UNION,
714 ENUM
715 };
716
717 enum ReprKind
718 {
719 RUST,
720 C,
721 INT,
722 ALIGN,
723 PACKED,
724 // TRANSPARENT,
725 // SIMD,
726 // ...
727 };
728
729 // Representation options, specified via attributes e.g. #[repr(packed)]
730 struct ReprOptions
731 {
732 ReprKind repr_kind = ReprKind::RUST;
733
734 // For align and pack: 0 = unspecified. Nonzero = byte alignment.
735 // It is an error for both to be nonzero, this should be caught when
736 // parsing the #[repr] attribute.
737 unsigned char align = 0;
738 unsigned char pack = 0;
739 BaseType *repr = nullptr;
740 };
741
742 ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
743 ADTKind adt_kind, std::vector<VariantDef *> variants,
744 std::vector<SubstitutionParamMapping> subst_refs,
745 SubstitutionArgumentMappings generic_arguments
746 = SubstitutionArgumentMappings::error (),
747 RegionConstraints region_constraints = RegionConstraints{},
748 std::set<HirId> refs = std::set<HirId> ());
749
750 ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
751 RustIdent ident, ADTKind adt_kind,
752 std::vector<VariantDef *> variants,
753 std::vector<SubstitutionParamMapping> subst_refs,
754 SubstitutionArgumentMappings generic_arguments
755 = SubstitutionArgumentMappings::error (),
756 RegionConstraints region_constraints = RegionConstraints{},
757 std::set<HirId> refs = std::set<HirId> ());
758
759 ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
760 RustIdent ident, ADTKind adt_kind,
761 std::vector<VariantDef *> variants,
762 std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
763 SubstitutionArgumentMappings generic_arguments
764 = SubstitutionArgumentMappings::error (),
765 RegionConstraints region_constraints = RegionConstraints{},
766 std::set<HirId> refs = std::set<HirId> ());
767
768 ADTKind get_adt_kind () const { return adt_kind; }
769
770 ReprOptions get_repr_options () const { return repr; }
771
772 bool is_struct_struct () const { return adt_kind == STRUCT_STRUCT; }
773
774 bool is_tuple_struct () const { return adt_kind == TUPLE_STRUCT; }
775
776 bool is_union () const { return adt_kind == UNION; }
777
778 bool is_enum () const { return adt_kind == ENUM; }
779
780 void accept_vis (TyVisitor &vis) override;
781
782 void accept_vis (TyConstVisitor &vis) const override;
783
784 std::string as_string () const override;
785
786 bool can_eq (const BaseType *other, bool emit_errors) const override final;
787
788 bool is_equal (const BaseType &other) const override;
789
790 std::string get_identifier () const { return identifier; }
791
792 std::string get_name () const override final
793 {
794 return identifier + subst_as_string ();
795 }
796
797 DefId get_id () const;
798
799 BaseType *clone () const final override;
800
801 size_t number_of_variants () const { return variants.size (); }
802
803 std::vector<VariantDef *> &get_variants () { return variants; }
804
805 const std::vector<VariantDef *> &get_variants () const { return variants; }
806
807 bool lookup_variant (const std::string &lookup,
808 VariantDef **found_variant) const
809 {
810 for (auto &variant : variants)
811 {
812 if (variant->get_identifier ().compare (lookup) == 0)
813 {
814 *found_variant = variant;
815 return true;
816 }
817 }
818 return false;
819 }
820
821 bool lookup_variant_by_id (HirId id, VariantDef **found_variant,
822 int *index = nullptr) const
823 {
824 int i = 0;
825 for (auto &variant : variants)
826 {
827 if (variant->get_id () == id)
828 {
829 if (index != nullptr)
830 *index = i;
831
832 *found_variant = variant;
833 return true;
834 }
835 i++;
836 }
837 return false;
838 }
839
840 ADTType *
841 handle_substitions (SubstitutionArgumentMappings &mappings) override final;
842
843 private:
844 DefId id;
845 std::string identifier;
846 std::vector<VariantDef *> variants;
847 ADTType::ADTKind adt_kind;
848 ReprOptions repr;
849 };
850
851 class FnParam
852 {
853 public:
854 FnParam (std::unique_ptr<HIR::Pattern> pattern, BaseType *type)
855 : pattern (std::move (pattern)), type (type)
856 {}
857
858 FnParam (const FnParam &) = delete;
859 FnParam (FnParam &&) = default;
860 FnParam &operator= (FnParam &&) = default;
861
862 HIR::Pattern &get_pattern () { return *pattern; }
863 const HIR::Pattern &get_pattern () const { return *pattern; }
864
865 bool has_pattern () { return pattern != nullptr; }
866 BaseType *get_type () const { return type; }
867 void set_type (BaseType *new_type) { type = new_type; }
868
869 FnParam clone () const
870 {
871 return FnParam (pattern->clone_pattern (), type->clone ());
872 }
873
874 FnParam monomorphized_clone () const
875 {
876 return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
877 }
878
879 private:
880 std::unique_ptr<HIR::Pattern> pattern;
881 BaseType *type;
882 };
883
884 class FnType : public CallableTypeInterface, public SubstitutionRef
885 {
886 public:
887 static constexpr auto KIND = TypeKind::FNDEF;
888
889 static const uint8_t FNTYPE_DEFAULT_FLAGS = 0x00;
890 static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01;
891 static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02;
892 static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
893
894 FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
895 uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
896 std::vector<SubstitutionParamMapping> subst_refs,
897 SubstitutionArgumentMappings substitution_argument_mappings,
898 RegionConstraints region_constraints,
899 std::set<HirId> refs = std::set<HirId> ())
900 : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
901 SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
902 region_constraints),
903 params (std::move (params)), type (type), flags (flags),
904 identifier (identifier), id (id), abi (abi)
905 {
906 LocalDefId local_def_id = id.localDefId;
907 rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
908 }
909
910 FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
911 RustIdent ident, uint8_t flags, ABI abi, std::vector<FnParam> params,
912 BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
913 SubstitutionArgumentMappings substitution_argument_mappings,
914 RegionConstraints region_constraints,
915 std::set<HirId> refs = std::set<HirId> ())
916 : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
917 SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
918 region_constraints),
919 params (std::move (params)), type (type), flags (flags),
920 identifier (identifier), id (id), abi (abi)
921 {
922 LocalDefId local_def_id = id.localDefId;
923 rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
924 }
925
926 FnType (const FnType &) = delete;
927 FnType (FnType &&) = default;
928
929 void accept_vis (TyVisitor &vis) override;
930 void accept_vis (TyConstVisitor &vis) const override;
931
932 std::string as_string () const override;
933
934 std::string get_name () const override final { return as_string (); }
935
936 std::string get_identifier () const { return identifier; }
937
938 bool can_eq (const BaseType *other, bool emit_errors) const override final;
939
940 bool is_equal (const BaseType &other) const override;
941
942 size_t num_params () const { return params.size (); }
943
944 bool is_method () const
945 {
946 if (num_params () == 0)
947 return false;
948
949 return (flags & FNTYPE_IS_METHOD_FLAG) != 0;
950 }
951
952 bool is_extern () const { return (flags & FNTYPE_IS_EXTERN_FLAG) != 0; }
953
954 bool is_variadic () const { return (flags & FNTYPE_IS_VARADIC_FLAG) != 0; }
955
956 DefId get_id () const { return id; }
957
958 // get the Self type for the method
959 BaseType *get_self_type () const
960 {
961 rust_assert (is_method ());
962 return param_at (0).get_type ();
963 }
964
965 std::vector<FnParam> &get_params () { return params; }
966
967 const std::vector<FnParam> &get_params () const { return params; }
968
969 FnParam &param_at (size_t idx) { return params.at (idx); }
970
971 const FnParam &param_at (size_t idx) const { return params.at (idx); }
972
973 BaseType *clone () const final override;
974
975 FnType *
976 handle_substitions (SubstitutionArgumentMappings &mappings) override final;
977
978 ABI get_abi () const { return abi; }
979 uint8_t get_flags () const { return flags; }
980
981 WARN_UNUSED_RESULT size_t get_num_params () const override
982 {
983 return params.size ();
984 }
985
986 WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
987 {
988 return param_at (index).get_type ();
989 }
990
991 WARN_UNUSED_RESULT BaseType *get_return_type () const override
992 {
993 return type;
994 }
995
996 private:
997 std::vector<FnParam> params;
998 BaseType *type;
999 uint8_t flags;
1000 std::string identifier;
1001 DefId id;
1002 ABI abi;
1003 };
1004
1005 class FnPtr : public CallableTypeInterface
1006 {
1007 public:
1008 static constexpr auto KIND = TypeKind::FNPTR;
1009
1010 FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
1011 TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1012 : CallableTypeInterface (ref, ref, TypeKind::FNPTR,
1013 {Resolver::CanonicalPath::create_empty (), locus},
1014 refs),
1015 params (std::move (params)), result_type (result_type)
1016 {}
1017
1018 FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
1019 TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1020 : CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
1021 {Resolver::CanonicalPath::create_empty (), locus},
1022 refs),
1023 params (params), result_type (result_type)
1024 {}
1025
1026 std::string get_name () const override final { return as_string (); }
1027
1028 WARN_UNUSED_RESULT size_t get_num_params () const override
1029 {
1030 return params.size ();
1031 }
1032
1033 WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
1034 {
1035 return params.at (index).get_tyty ();
1036 }
1037
1038 WARN_UNUSED_RESULT BaseType *get_return_type () const override
1039 {
1040 return result_type.get_tyty ();
1041 }
1042
1043 const TyVar &get_var_return_type () const { return result_type; }
1044
1045 size_t num_params () const { return params.size (); }
1046
1047 void accept_vis (TyVisitor &vis) override;
1048 void accept_vis (TyConstVisitor &vis) const override;
1049
1050 std::string as_string () const override;
1051
1052 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1053
1054 bool is_equal (const BaseType &other) const override;
1055
1056 BaseType *clone () const final override;
1057
1058 std::vector<TyVar> &get_params () { return params; }
1059 const std::vector<TyVar> &get_params () const { return params; }
1060
1061 private:
1062 std::vector<TyVar> params;
1063 TyVar result_type;
1064 };
1065
1066 class ClosureType : public CallableTypeInterface, public SubstitutionRef
1067 {
1068 public:
1069 static constexpr auto KIND = TypeKind::CLOSURE;
1070
1071 ClosureType (HirId ref, DefId id, RustIdent ident, TupleType *parameters,
1072 TyVar result_type,
1073 std::vector<SubstitutionParamMapping> subst_refs,
1074 std::set<NodeId> captures,
1075 std::set<HirId> refs = std::set<HirId> (),
1076 std::vector<TypeBoundPredicate> specified_bounds
1077 = std::vector<TypeBoundPredicate> ())
1078 : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
1079 SubstitutionRef (std::move (subst_refs),
1080 SubstitutionArgumentMappings::error (),
1081 {}), // TODO: check region constraints
1082 parameters (parameters), result_type (std::move (result_type)), id (id),
1083 captures (captures)
1084 {
1085 LocalDefId local_def_id = id.localDefId;
1086 rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
1087 inherit_bounds (specified_bounds);
1088 }
1089
1090 ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
1091 TupleType *parameters, TyVar result_type,
1092 std::vector<SubstitutionParamMapping> subst_refs,
1093 std::set<NodeId> captures,
1094 std::set<HirId> refs = std::set<HirId> (),
1095 std::vector<TypeBoundPredicate> specified_bounds
1096 = std::vector<TypeBoundPredicate> ())
1097 : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
1098 SubstitutionRef (std::move (subst_refs),
1099 SubstitutionArgumentMappings::error (), {}), // TODO
1100 parameters (parameters), result_type (std::move (result_type)), id (id),
1101 captures (captures)
1102 {
1103 LocalDefId local_def_id = id.localDefId;
1104 rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
1105 inherit_bounds (specified_bounds);
1106 }
1107
1108 void accept_vis (TyVisitor &vis) override;
1109 void accept_vis (TyConstVisitor &vis) const override;
1110
1111 WARN_UNUSED_RESULT size_t get_num_params () const override
1112 {
1113 return parameters->num_fields ();
1114 }
1115
1116 WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
1117 {
1118 return parameters->get_field (index);
1119 }
1120
1121 WARN_UNUSED_RESULT BaseType *get_return_type () const override
1122 {
1123 return result_type.get_tyty ();
1124 }
1125
1126 std::string as_string () const override;
1127 std::string get_name () const override final { return as_string (); }
1128
1129 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1130
1131 bool is_equal (const BaseType &other) const override;
1132
1133 BaseType *clone () const final override;
1134
1135 ClosureType *
1136 handle_substitions (SubstitutionArgumentMappings &mappings) override final;
1137
1138 TyTy::TupleType &get_parameters () const { return *parameters; }
1139 TyTy::BaseType &get_result_type () const { return *result_type.get_tyty (); }
1140
1141 DefId get_def_id () const { return id; }
1142
1143 void setup_fn_once_output () const;
1144
1145 const std::set<NodeId> &get_captures () const { return captures; }
1146
1147 private:
1148 TyTy::TupleType *parameters;
1149 TyVar result_type;
1150 DefId id;
1151 std::set<NodeId> captures;
1152 };
1153
1154 class ArrayType : public BaseType
1155 {
1156 public:
1157 static constexpr auto KIND = TypeKind::ARRAY;
1158
1159 ArrayType (HirId ref, location_t locus, HIR::Expr &capacity_expr, TyVar base,
1160 std::set<HirId> refs = std::set<HirId> ())
1161 : BaseType (ref, ref, TypeKind::ARRAY,
1162 {Resolver::CanonicalPath::create_empty (), locus}, refs),
1163 element_type (base), capacity_expr (capacity_expr)
1164 {}
1165
1166 ArrayType (HirId ref, HirId ty_ref, location_t locus,
1167 HIR::Expr &capacity_expr, TyVar base,
1168 std::set<HirId> refs = std::set<HirId> ())
1169 : BaseType (ref, ty_ref, TypeKind::ARRAY,
1170 {Resolver::CanonicalPath::create_empty (), locus}, refs),
1171 element_type (base), capacity_expr (capacity_expr)
1172 {}
1173
1174 void accept_vis (TyVisitor &vis) override;
1175 void accept_vis (TyConstVisitor &vis) const override;
1176
1177 std::string as_string () const override;
1178
1179 std::string get_name () const override final { return as_string (); }
1180
1181 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1182
1183 bool is_equal (const BaseType &other) const override;
1184
1185 BaseType *get_element_type () const;
1186 const TyVar &get_var_element_type () const;
1187
1188 BaseType *clone () const final override;
1189
1190 HIR::Expr &get_capacity_expr () const { return capacity_expr; }
1191
1192 ArrayType *handle_substitions (SubstitutionArgumentMappings &mappings);
1193
1194 private:
1195 TyVar element_type;
1196 // FIXME: I dont think this should be in tyty - tyty should already be const
1197 // evaluated
1198 HIR::Expr &capacity_expr;
1199 };
1200
1201 class SliceType : public BaseType
1202 {
1203 public:
1204 static constexpr auto KIND = TypeKind::SLICE;
1205
1206 SliceType (HirId ref, location_t locus, TyVar base,
1207 std::set<HirId> refs = std::set<HirId> ())
1208 : BaseType (ref, ref, TypeKind::SLICE,
1209 {Resolver::CanonicalPath::create_empty (), locus}, refs),
1210 element_type (base)
1211 {}
1212
1213 SliceType (HirId ref, HirId ty_ref, location_t locus, TyVar base,
1214 std::set<HirId> refs = std::set<HirId> ())
1215 : BaseType (ref, ty_ref, TypeKind::SLICE,
1216 {Resolver::CanonicalPath::create_empty (), locus}, refs),
1217 element_type (base)
1218 {}
1219
1220 void accept_vis (TyVisitor &vis) override;
1221 void accept_vis (TyConstVisitor &vis) const override;
1222
1223 std::string as_string () const override;
1224
1225 std::string get_name () const override final { return as_string (); }
1226
1227 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1228
1229 bool is_equal (const BaseType &other) const override;
1230
1231 BaseType *get_element_type () const;
1232 const TyVar &get_var_element_type () const;
1233
1234 BaseType *clone () const final override;
1235
1236 SliceType *handle_substitions (SubstitutionArgumentMappings &mappings);
1237
1238 private:
1239 TyVar element_type;
1240 };
1241
1242 class BoolType : public BaseType
1243 {
1244 public:
1245 static constexpr auto KIND = TypeKind::BOOL;
1246
1247 BoolType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1248 BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1249
1250 void accept_vis (TyVisitor &vis) override;
1251 void accept_vis (TyConstVisitor &vis) const override;
1252
1253 std::string as_string () const override;
1254
1255 std::string get_name () const override final;
1256
1257 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1258
1259 BaseType *clone () const final override;
1260 };
1261
1262 class IntType : public BaseType
1263 {
1264 public:
1265 enum IntKind
1266 {
1267 I8,
1268 I16,
1269 I32,
1270 I64,
1271 I128
1272 };
1273
1274 static constexpr auto KIND = TypeKind::INT;
1275
1276 IntType (HirId ref, IntKind kind, std::set<HirId> refs = std::set<HirId> ());
1277 IntType (HirId ref, HirId ty_ref, IntKind kind,
1278 std::set<HirId> refs = std::set<HirId> ());
1279
1280 void accept_vis (TyVisitor &vis) override;
1281 void accept_vis (TyConstVisitor &vis) const override;
1282
1283 std::string as_string () const override;
1284
1285 std::string get_name () const override final;
1286
1287 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1288
1289 IntKind get_int_kind () const;
1290
1291 BaseType *clone () const final override;
1292
1293 bool is_equal (const BaseType &other) const override;
1294
1295 private:
1296 IntKind int_kind;
1297 };
1298
1299 class UintType : public BaseType
1300 {
1301 public:
1302 static constexpr auto KIND = TypeKind::UINT;
1303
1304 enum UintKind
1305 {
1306 U8,
1307 U16,
1308 U32,
1309 U64,
1310 U128
1311 };
1312
1313 UintType (HirId ref, UintKind kind,
1314 std::set<HirId> refs = std::set<HirId> ());
1315 UintType (HirId ref, HirId ty_ref, UintKind kind,
1316 std::set<HirId> refs = std::set<HirId> ());
1317
1318 void accept_vis (TyVisitor &vis) override;
1319 void accept_vis (TyConstVisitor &vis) const override;
1320
1321 std::string as_string () const override;
1322
1323 std::string get_name () const override final;
1324
1325 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1326
1327 UintKind get_uint_kind () const;
1328
1329 BaseType *clone () const final override;
1330
1331 bool is_equal (const BaseType &other) const override;
1332
1333 private:
1334 UintKind uint_kind;
1335 };
1336
1337 class FloatType : public BaseType
1338 {
1339 public:
1340 static constexpr auto KIND = TypeKind::FLOAT;
1341
1342 enum FloatKind
1343 {
1344 F32,
1345 F64
1346 };
1347
1348 FloatType (HirId ref, FloatKind kind,
1349 std::set<HirId> refs = std::set<HirId> ());
1350 FloatType (HirId ref, HirId ty_ref, FloatKind kind,
1351 std::set<HirId> refs = std::set<HirId> ());
1352
1353 void accept_vis (TyVisitor &vis) override;
1354 void accept_vis (TyConstVisitor &vis) const override;
1355
1356 std::string as_string () const override;
1357 std::string get_name () const override final;
1358
1359 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1360
1361 FloatKind get_float_kind () const;
1362
1363 BaseType *clone () const final override;
1364
1365 bool is_equal (const BaseType &other) const override;
1366
1367 private:
1368 FloatKind float_kind;
1369 };
1370
1371 class USizeType : public BaseType
1372 {
1373 public:
1374 static constexpr auto KIND = TypeKind::USIZE;
1375
1376 USizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1377 USizeType (HirId ref, HirId ty_ref,
1378 std::set<HirId> refs = std::set<HirId> ());
1379
1380 void accept_vis (TyVisitor &vis) override;
1381 void accept_vis (TyConstVisitor &vis) const override;
1382
1383 std::string as_string () const override;
1384 std::string get_name () const override final;
1385
1386 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1387
1388 BaseType *clone () const final override;
1389 };
1390
1391 class ISizeType : public BaseType
1392 {
1393 public:
1394 static constexpr auto KIND = TypeKind::ISIZE;
1395
1396 ISizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1397 ISizeType (HirId ref, HirId ty_ref,
1398 std::set<HirId> refs = std::set<HirId> ());
1399
1400 void accept_vis (TyVisitor &vis) override;
1401 void accept_vis (TyConstVisitor &vis) const override;
1402
1403 std::string as_string () const override;
1404 std::string get_name () const override final;
1405
1406 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1407
1408 BaseType *clone () const final override;
1409 };
1410
1411 class CharType : public BaseType
1412 {
1413 public:
1414 static constexpr auto KIND = TypeKind::CHAR;
1415
1416 CharType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1417 CharType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1418
1419 void accept_vis (TyVisitor &vis) override;
1420 void accept_vis (TyConstVisitor &vis) const override;
1421
1422 std::string as_string () const override;
1423 std::string get_name () const override final;
1424
1425 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1426
1427 BaseType *clone () const final override;
1428 };
1429
1430 class StrType : public BaseType
1431 {
1432 public:
1433 static constexpr auto KIND = TypeKind::STR;
1434
1435 StrType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1436 StrType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1437
1438 std::string get_name () const override final;
1439
1440 void accept_vis (TyVisitor &vis) override;
1441 void accept_vis (TyConstVisitor &vis) const override;
1442
1443 std::string as_string () const override;
1444
1445 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1446
1447 bool is_equal (const BaseType &other) const override;
1448
1449 BaseType *clone () const final override;
1450 };
1451
1452 class DynamicObjectType : public BaseType
1453 {
1454 public:
1455 static constexpr auto KIND = TypeKind::DYNAMIC;
1456
1457 DynamicObjectType (HirId ref, RustIdent ident,
1458 std::vector<TypeBoundPredicate> specified_bounds,
1459 std::set<HirId> refs = std::set<HirId> ());
1460
1461 DynamicObjectType (HirId ref, HirId ty_ref, RustIdent ident,
1462 std::vector<TypeBoundPredicate> specified_bounds,
1463 std::set<HirId> refs = std::set<HirId> ());
1464
1465 void accept_vis (TyVisitor &vis) override;
1466 void accept_vis (TyConstVisitor &vis) const override;
1467
1468 std::string as_string () const override;
1469
1470 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1471
1472 bool is_equal (const BaseType &other) const override;
1473
1474 BaseType *clone () const final override;
1475
1476 std::string get_name () const override final;
1477
1478 // this returns a flat list of items including super trait bounds
1479 const std::vector<
1480 std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
1481 get_object_items () const;
1482 };
1483
1484 class ReferenceType : public BaseType
1485 {
1486 public:
1487 static constexpr auto KIND = REF;
1488
1489 ReferenceType (HirId ref, TyVar base, Mutability mut,
1490 Region region = Region::make_anonymous (),
1491 std::set<HirId> refs = std::set<HirId> ());
1492 ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
1493 Region region = Region::make_anonymous (),
1494 std::set<HirId> refs = std::set<HirId> ());
1495
1496 BaseType *get_base () const;
1497 const TyVar &get_var_element_type () const;
1498
1499 void accept_vis (TyVisitor &vis) override;
1500 void accept_vis (TyConstVisitor &vis) const override;
1501
1502 std::string as_string () const override;
1503
1504 std::string get_name () const override final;
1505
1506 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1507
1508 bool is_equal (const BaseType &other) const override;
1509
1510 BaseType *clone () const final override;
1511
1512 ReferenceType *handle_substitions (SubstitutionArgumentMappings &mappings);
1513
1514 Mutability mutability () const;
1515 bool is_mutable () const;
1516
1517 WARN_UNUSED_RESULT Region get_region () const;
1518 void set_region (Region region);
1519
1520 bool is_dyn_object () const;
1521 bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
1522 bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
1523 bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
1524
1525 private:
1526 TyVar base;
1527 Mutability mut;
1528 Region region;
1529 };
1530
1531 class PointerType : public BaseType
1532 {
1533 public:
1534 static constexpr auto KIND = TypeKind::POINTER;
1535
1536 PointerType (HirId ref, TyVar base, Mutability mut,
1537 std::set<HirId> refs = std::set<HirId> ());
1538 PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
1539 std::set<HirId> refs = std::set<HirId> ());
1540
1541 BaseType *get_base () const;
1542 const TyVar &get_var_element_type () const;
1543
1544 void accept_vis (TyVisitor &vis) override;
1545 void accept_vis (TyConstVisitor &vis) const override;
1546
1547 std::string as_string () const override;
1548 std::string get_name () const override final;
1549
1550 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1551
1552 bool is_equal (const BaseType &other) const override;
1553
1554 BaseType *clone () const final override;
1555
1556 PointerType *handle_substitions (SubstitutionArgumentMappings &mappings);
1557
1558 Mutability mutability () const;
1559 bool is_mutable () const;
1560 bool is_const () const;
1561 bool is_dyn_object () const;
1562 bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
1563 bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
1564 bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
1565
1566 private:
1567 TyVar base;
1568 Mutability mut;
1569 };
1570
1571 // https://doc.rust-lang.org/std/primitive.never.html
1572 //
1573 // Since the `!` type is really complicated and it is even still unstable
1574 // in rustc, only fairly limited support for this type is introduced here.
1575 // Unification between `!` and ANY other type (including `<T?>`) is simply
1576 // not allowed. If it is needed, it should be handled manually. For example,
1577 // unifying `!` with other types is very necessary when resolving types of
1578 // `if/else` expressions.
1579 //
1580 // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
1581 class NeverType : public BaseType
1582 {
1583 public:
1584 static constexpr auto KIND = TypeKind::NEVER;
1585
1586 NeverType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1587
1588 NeverType (HirId ref, HirId ty_ref,
1589 std::set<HirId> refs = std::set<HirId> ());
1590
1591 void accept_vis (TyVisitor &vis) override;
1592
1593 void accept_vis (TyConstVisitor &vis) const override;
1594
1595 std::string as_string () const override;
1596
1597 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1598
1599 BaseType *clone () const final override;
1600
1601 std::string get_name () const override final;
1602 };
1603
1604 // used at the type in associated types in traits
1605 // see: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
1606 class PlaceholderType : public BaseType
1607 {
1608 public:
1609 static constexpr auto KIND = TypeKind::PLACEHOLDER;
1610
1611 PlaceholderType (std::string symbol, DefId id, HirId ref,
1612 std::set<HirId> refs = std::set<HirId> ());
1613 PlaceholderType (std::string symbol, DefId id, HirId ref, HirId ty_ref,
1614 std::set<HirId> refs = std::set<HirId> ());
1615
1616 void accept_vis (TyVisitor &vis) override;
1617 void accept_vis (TyConstVisitor &vis) const override;
1618
1619 std::string as_string () const override;
1620
1621 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1622
1623 BaseType *clone () const final override;
1624
1625 std::string get_name () const override final;
1626
1627 std::string get_symbol () const;
1628
1629 void set_associated_type (HirId ref);
1630
1631 void clear_associated_type ();
1632
1633 bool can_resolve () const;
1634
1635 BaseType *resolve () const;
1636
1637 bool is_equal (const BaseType &other) const override;
1638
1639 DefId get_def_id () const;
1640
1641 private:
1642 std::string symbol;
1643 DefId defId;
1644 };
1645
1646 class ProjectionType : public BaseType, public SubstitutionRef
1647 {
1648 public:
1649 static constexpr auto KIND = TypeKind::PROJECTION;
1650
1651 ProjectionType (HirId ref, BaseType *base,
1652 const Resolver::TraitReference *trait, DefId item,
1653 std::vector<SubstitutionParamMapping> subst_refs,
1654 SubstitutionArgumentMappings generic_arguments
1655 = SubstitutionArgumentMappings::error (),
1656 RegionConstraints region_constraints = {},
1657 std::set<HirId> refs = std::set<HirId> ());
1658
1659 ProjectionType (HirId ref, HirId ty_ref, BaseType *base,
1660 const Resolver::TraitReference *trait, DefId item,
1661 std::vector<SubstitutionParamMapping> subst_refs,
1662 SubstitutionArgumentMappings generic_arguments
1663 = SubstitutionArgumentMappings::error (),
1664 RegionConstraints region_constraints = {},
1665 std::set<HirId> refs = std::set<HirId> ());
1666
1667 void accept_vis (TyVisitor &vis) override;
1668 void accept_vis (TyConstVisitor &vis) const override;
1669
1670 std::string as_string () const override;
1671
1672 bool can_eq (const BaseType *other, bool emit_errors) const override final;
1673
1674 BaseType *clone () const final override;
1675
1676 std::string get_name () const override final;
1677
1678 const BaseType *get () const;
1679 BaseType *get ();
1680
1681 ProjectionType *
1682 handle_substitions (SubstitutionArgumentMappings &mappings) override final;
1683
1684 private:
1685 BaseType *base;
1686 const Resolver::TraitReference *trait;
1687 DefId item;
1688 };
1689
1690 template <>
1691 WARN_UNUSED_RESULT inline bool
1692 BaseType::is<CallableTypeInterface> () const
1693 {
1694 auto kind = this->get_kind ();
1695 return kind == FNPTR || kind == FNDEF || kind == CLOSURE;
1696 }
1697
1698 template <>
1699 WARN_UNUSED_RESULT inline bool
1700 BaseType::is<const CallableTypeInterface> () const
1701 {
1702 return this->is<CallableTypeInterface> ();
1703 }
1704
1705 template <>
1706 WARN_UNUSED_RESULT inline bool
1707 BaseType::is<SubstitutionRef> () const
1708 {
1709 auto kind = this->get_kind ();
1710 return kind == FNPTR || kind == FNDEF || kind == CLOSURE || kind == ADT
1711 || kind == PROJECTION;
1712 }
1713
1714 template <>
1715 WARN_UNUSED_RESULT inline bool
1716 BaseType::is<const SubstitutionRef> () const
1717 {
1718 return this->is<SubstitutionRef> ();
1719 }
1720
1721 template <>
1722 WARN_UNUSED_RESULT inline SubstitutionRef *
1723 BaseType::as<SubstitutionRef> ()
1724 {
1725 auto kind = this->get_kind ();
1726 switch (kind)
1727 {
1728 case FNDEF:
1729 return static_cast<FnType *> (this);
1730 case CLOSURE:
1731 return static_cast<ClosureType *> (this);
1732 case ADT:
1733 return static_cast<ADTType *> (this);
1734 case PROJECTION:
1735 return static_cast<ProjectionType *> (this);
1736 default:
1737 rust_unreachable ();
1738 }
1739 }
1740
1741 template <>
1742 WARN_UNUSED_RESULT inline const SubstitutionRef *
1743 BaseType::as<const SubstitutionRef> () const
1744 {
1745 auto kind = this->get_kind ();
1746 switch (kind)
1747 {
1748 case FNDEF:
1749 return static_cast<const FnType *> (this);
1750 case CLOSURE:
1751 return static_cast<const ClosureType *> (this);
1752 case ADT:
1753 return static_cast<const ADTType *> (this);
1754 case PROJECTION:
1755 return static_cast<const ProjectionType *> (this);
1756 default:
1757 rust_unreachable ();
1758 }
1759 }
1760
1761 template <>
1762 WARN_UNUSED_RESULT inline SubstitutionRef *
1763 BaseType::try_as<SubstitutionRef> ()
1764 {
1765 if (this->is<SubstitutionRef> ())
1766 {
1767 return this->as<SubstitutionRef> ();
1768 }
1769 return nullptr;
1770 }
1771
1772 template <>
1773 WARN_UNUSED_RESULT inline const SubstitutionRef *
1774 BaseType::try_as<const SubstitutionRef> () const
1775 {
1776 if (this->is<const SubstitutionRef> ())
1777 {
1778 return this->as<const SubstitutionRef> ();
1779 }
1780 return nullptr;
1781 }
1782
1783 } // namespace TyTy
1784 } // namespace Rust
1785
1786 #endif // RUST_TYTY