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