1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
22 #include "rust-hir-map.h"
23 #include "rust-common.h"
24 #include "rust-identifier.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"
37 class TraitItemReference
;
39 class AssociatedImplTrait
;
40 } // namespace Resolver
46 class CallableTypeInterface
;
48 // https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
49 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
75 // there are more to add...
80 is_primitive_type_kind (TypeKind kind
);
85 static std::string
to_string (TypeKind kind
);
90 class BaseType
: public TypeBoundsMappings
95 HirId
get_ref () const;
96 void set_ref (HirId id
);
98 HirId
get_ty_ref () const;
99 void set_ty_ref (HirId id
);
101 HirId
get_orig_ref () const;
103 virtual void accept_vis (TyVisitor
&vis
) = 0;
104 virtual void accept_vis (TyConstVisitor
&vis
) const = 0;
106 virtual std::string
as_string () const = 0;
107 virtual std::string
get_name () const = 0;
109 // similar to unify but does not actually perform type unification but
110 // determines whether they are compatible. Consider the following
112 // fn foo<T>() -> T { ... }
113 // fn foo() -> i32 { ... }
115 // when the function has been substituted they can be considered equal.
117 // It can also be used to optional emit errors for trait item compatibility
119 virtual bool can_eq (const BaseType
*other
, bool emit_errors
) const = 0;
121 // Check value equality between two ty. Type inference rules are ignored. Two
122 // ty are considered equal if they're of the same kind, and
123 // 1. (For ADTs, arrays, tuples, refs) have the same underlying ty
124 // 2. (For functions) have the same signature
125 virtual bool is_equal (const BaseType
&other
) const;
127 bool satisfies_bound (const TypeBoundPredicate
&predicate
,
128 bool emit_error
) const;
130 bool bounds_compatible (const BaseType
&other
, location_t locus
,
131 bool emit_error
) const;
133 void inherit_bounds (const BaseType
&other
);
135 void inherit_bounds (
136 const std::vector
<TyTy::TypeBoundPredicate
> &specified_bounds
);
138 // is_unit returns whether this is just a unit-struct
139 bool is_unit () const;
141 // is_concrete returns true if the type is fully resolved to concrete
143 bool is_concrete () const;
145 // return the type-kind
146 TypeKind
get_kind () const;
148 // monomorphized clone is a clone which destructures the types to get rid of
150 BaseType
*monomorphized_clone () const;
152 // get_combined_refs returns the chain of node refs involved in unification
153 std::set
<HirId
> get_combined_refs () const;
155 void append_reference (HirId id
);
157 std::string
mappings_str () const;
159 std::string
debug_str () const;
163 // FIXME this will eventually go away
164 const BaseType
*get_root () const;
166 // This will get the monomorphized type from Params, Placeholders or
167 // Projections if available or error
168 BaseType
*destructure ();
169 const BaseType
*destructure () const;
171 const RustIdent
&get_ident () const;
172 location_t
get_locus () const;
174 bool has_substitutions_defined () const;
175 bool needs_generic_substitutions () const;
177 std::string
mangle_string () const
179 return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
180 + mappings_str () + ":" + bounds_as_string ();
183 /* Returns a pointer to a clone of this. The caller is responsible for
184 * releasing the memory of the returned ty. */
185 virtual BaseType
*clone () const = 0;
187 // Check if TyTy::BaseType is of a specific type.
188 template <typename T
> WARN_UNUSED_RESULT
bool is () const
190 static_assert (std::is_base_of
<BaseType
, T
>::value
,
191 "Can only safely cast to TyTy types.");
192 return this->get_kind () == T::KIND
;
195 template <typename T
> T
*as () const
197 static_assert (std::is_base_of
<BaseType
, T
>::value
,
198 "Can only safely cast to TyTy types.");
199 rust_assert (this->is
<T
> ());
200 return static_cast<T
*> (this);
203 template <typename T
> T
*as ()
205 static_assert (std::is_base_of
<BaseType
, T
>::value
,
206 "Can only safely cast to TyTy types.");
207 rust_assert (this->is
<T
> ());
208 return static_cast<T
*> (this);
211 // Check if TyTy::BaseType is of a specific type and convert it to that type
213 // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler
215 template <typename T
> T
*try_as () const
217 static_assert (std::is_base_of
<BaseType
, T
>::value
,
218 "Can only safely cast to TyTy types.");
222 return static_cast<T
*> (this);
226 template <typename T
> T
*try_as ()
228 static_assert (std::is_base_of
<BaseType
, T
>::value
,
229 "Can only safely cast to TyTy types.");
233 return static_cast<T
*> (this);
237 BaseType (HirId ref
, HirId ty_ref
, TypeKind kind
, RustIdent ident
,
238 std::set
<HirId
> refs
= std::set
<HirId
> ());
240 BaseType (HirId ref
, HirId ty_ref
, TypeKind kind
, RustIdent ident
,
241 std::vector
<TypeBoundPredicate
> specified_bounds
,
242 std::set
<HirId
> refs
= std::set
<HirId
> ());
247 const HirId orig_ref
;
248 std::set
<HirId
> combined
;
251 Analysis::Mappings
*mappings
;
254 /** Unified interface for all function-like types. */
255 class CallableTypeInterface
: public BaseType
258 explicit CallableTypeInterface (HirId ref
, HirId ty_ref
, TypeKind kind
,
260 std::set
<HirId
> refs
= std::set
<HirId
> ())
261 : BaseType (ref
, ty_ref
, kind
, ident
, refs
)
264 WARN_UNUSED_RESULT
virtual size_t get_num_params () const = 0;
265 WARN_UNUSED_RESULT
virtual BaseType
*
266 get_param_type_at (size_t index
) const = 0;
267 WARN_UNUSED_RESULT
virtual BaseType
*get_return_type () const = 0;
270 class InferType
: public BaseType
273 static constexpr auto KIND
= TypeKind::INFER
;
305 static TypeHint
Default ()
307 return TypeHint
{TypeKind::ERROR
, UNKNOWN
, SUNKNOWN
};
311 InferType (HirId ref
, InferTypeKind infer_kind
, TypeHint hint
,
312 location_t locus
, std::set
<HirId
> refs
= std::set
<HirId
> ());
314 InferType (HirId ref
, HirId ty_ref
, InferTypeKind infer_kind
, TypeHint hint
,
315 location_t locus
, std::set
<HirId
> refs
= std::set
<HirId
> ());
317 void accept_vis (TyVisitor
&vis
) override
;
319 void accept_vis (TyConstVisitor
&vis
) const override
;
321 std::string
as_string () const override
;
323 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
325 BaseType
*clone () const final override
;
327 InferTypeKind
get_infer_kind () const;
329 std::string
get_name () const override final
;
331 bool default_type (BaseType
**type
) const;
333 void apply_primitive_type_hint (const TyTy::BaseType
&hint
);
336 InferTypeKind infer_kind
;
337 TypeHint default_hint
;
340 class ErrorType
: public BaseType
343 static constexpr auto KIND
= TypeKind::ERROR
;
345 ErrorType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
347 ErrorType (HirId ref
, HirId ty_ref
,
348 std::set
<HirId
> refs
= std::set
<HirId
> ());
350 void accept_vis (TyVisitor
&vis
) override
;
351 void accept_vis (TyConstVisitor
&vis
) const override
;
353 std::string
as_string () const override
;
355 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
357 BaseType
*clone () const final override
;
359 std::string
get_name () const override final
;
362 class ParamType
: public BaseType
365 static constexpr auto KIND
= TypeKind::PARAM
;
367 ParamType (std::string symbol
, location_t locus
, HirId ref
,
368 HIR::GenericParam
¶m
,
369 std::vector
<TypeBoundPredicate
> specified_bounds
,
370 std::set
<HirId
> refs
= std::set
<HirId
> ());
372 ParamType (bool is_trait_self
, std::string symbol
, location_t locus
,
373 HirId ref
, HirId ty_ref
, HIR::GenericParam
¶m
,
374 std::vector
<TypeBoundPredicate
> specified_bounds
,
375 std::set
<HirId
> refs
= std::set
<HirId
> ());
377 void accept_vis (TyVisitor
&vis
) override
;
378 void accept_vis (TyConstVisitor
&vis
) const override
;
380 std::string
as_string () const override
;
382 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
384 BaseType
*clone () const final override
;
386 std::string
get_symbol () const;
388 HIR::GenericParam
&get_generic_param ();
390 bool can_resolve () const;
392 BaseType
*resolve () const;
394 std::string
get_name () const override final
;
396 bool is_equal (const BaseType
&other
) const override
;
398 ParamType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
400 void set_implicit_self_trait ();
401 bool is_implicit_self_trait () const;
406 HIR::GenericParam
¶m
;
409 class StructFieldType
412 StructFieldType (HirId ref
, std::string name
, BaseType
*ty
, location_t locus
);
414 HirId
get_ref () const;
416 bool is_equal (const StructFieldType
&other
) const;
418 std::string
get_name () const;
420 BaseType
*get_field_type () const;
421 void set_field_type (BaseType
*fty
);
423 StructFieldType
*clone () const;
424 StructFieldType
*monomorphized_clone () const;
427 location_t
get_locus () const;
428 std::string
as_string () const;
437 class TupleType
: public BaseType
440 static constexpr auto KIND
= TypeKind::TUPLE
;
442 TupleType (HirId ref
, location_t locus
,
443 std::vector
<TyVar
> fields
= std::vector
<TyVar
> (),
444 std::set
<HirId
> refs
= std::set
<HirId
> ());
446 TupleType (HirId ref
, HirId ty_ref
, location_t locus
,
447 std::vector
<TyVar
> fields
= std::vector
<TyVar
> (),
448 std::set
<HirId
> refs
= std::set
<HirId
> ());
450 static TupleType
*get_unit_type (HirId ref
);
452 void accept_vis (TyVisitor
&vis
) override
;
453 void accept_vis (TyConstVisitor
&vis
) const override
;
455 std::string
as_string () const override
;
457 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
459 bool is_equal (const BaseType
&other
) const override
;
461 size_t num_fields () const;
463 BaseType
*get_field (size_t index
) const;
465 BaseType
*clone () const final override
;
467 const std::vector
<TyVar
> &get_fields () const;
469 std::string
get_name () const override final
;
471 TupleType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
474 std::vector
<TyVar
> fields
;
477 class TypeBoundPredicate
: public SubstitutionRef
480 TypeBoundPredicate (const Resolver::TraitReference
&trait_reference
,
481 BoundPolarity polarity
, location_t locus
);
483 TypeBoundPredicate (DefId reference
,
484 std::vector
<SubstitutionParamMapping
> substitutions
,
485 BoundPolarity polarity
, location_t locus
);
487 TypeBoundPredicate (const TypeBoundPredicate
&other
);
489 virtual ~TypeBoundPredicate (){};
491 TypeBoundPredicate
&operator= (const TypeBoundPredicate
&other
);
493 static TypeBoundPredicate
error ();
495 std::string
as_string () const;
497 std::string
as_name () const;
499 const Resolver::TraitReference
*get () const;
501 location_t
get_locus () const { return locus
; }
503 std::string
get_name () const;
505 // check that this predicate is object-safe see:
506 // https://doc.rust-lang.org/reference/items/traits.html#object-safety
507 bool is_object_safe (bool emit_error
, location_t locus
) const;
509 void apply_generic_arguments (HIR::GenericArgs
*generic_args
,
510 bool has_associated_self
);
512 bool contains_item (const std::string
&search
) const;
514 TypeBoundPredicateItem
515 lookup_associated_item (const std::string
&search
) const;
517 TypeBoundPredicateItem
518 lookup_associated_item (const Resolver::TraitItemReference
*ref
) const;
520 // WARNING THIS WILL ALWAYS RETURN NULLPTR
522 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
524 bool is_error () const;
526 bool requires_generic_args () const;
528 bool contains_associated_types () const;
530 DefId
get_id () const { return reference
; }
532 BoundPolarity
get_polarity () const { return polarity
; }
534 std::vector
<TypeBoundPredicateItem
> get_associated_type_items ();
536 size_t get_num_associated_bindings () const override final
;
538 TypeBoundPredicateItem
539 lookup_associated_type (const std::string
&search
) override final
;
541 bool is_equal (const TypeBoundPredicate
&other
) const;
548 TypeBoundPredicate (mark_is_error
);
553 BoundPolarity polarity
;
556 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
567 static std::string
variant_type_string (VariantType type
);
569 VariantDef (HirId id
, DefId defid
, std::string identifier
, RustIdent ident
,
570 HIR::Expr
*discriminant
);
572 VariantDef (HirId id
, DefId defid
, std::string identifier
, RustIdent ident
,
573 VariantType type
, HIR::Expr
*discriminant
,
574 std::vector
<StructFieldType
*> fields
);
576 VariantDef (const VariantDef
&other
);
578 VariantDef
&operator= (const VariantDef
&other
);
580 static VariantDef
&get_error_node ();
581 bool is_error () const;
583 HirId
get_id () const;
584 DefId
get_defid () const;
586 VariantType
get_variant_type () const;
587 bool is_data_variant () const;
588 bool is_dataless_variant () const;
590 std::string
get_identifier () const;
592 size_t num_fields () const;
593 StructFieldType
*get_field_at_index (size_t index
);
595 std::vector
<StructFieldType
*> &get_fields ();
597 bool lookup_field (const std::string
&lookup
, StructFieldType
**field_lookup
,
598 size_t *index
) const;
600 HIR::Expr
*get_discriminant () const;
602 std::string
as_string () const;
604 bool is_equal (const VariantDef
&other
) const;
606 VariantDef
*clone () const;
608 VariantDef
*monomorphized_clone () const;
610 const RustIdent
&get_ident () const;
615 std::string identifier
;
618 // can either be a structure or a discriminant value
619 HIR::Expr
*discriminant
;
620 std::vector
<StructFieldType
*> fields
;
623 class ADTType
: public BaseType
, public SubstitutionRef
626 static constexpr auto KIND
= TypeKind::ADT
;
636 // Representation options, specified via attributes e.g. #[repr(packed)]
640 // bool is_transparent;
643 // For align and pack: 0 = unspecified. Nonzero = byte alignment.
644 // It is an error for both to be nonzero, this should be caught when
645 // parsing the #[repr] attribute.
646 unsigned char align
= 0;
647 unsigned char pack
= 0;
650 ADTType (HirId ref
, std::string identifier
, RustIdent ident
, ADTKind adt_kind
,
651 std::vector
<VariantDef
*> variants
,
652 std::vector
<SubstitutionParamMapping
> subst_refs
,
653 SubstitutionArgumentMappings generic_arguments
654 = SubstitutionArgumentMappings::error (),
655 RegionConstraints region_constraints
= {},
656 std::set
<HirId
> refs
= std::set
<HirId
> ())
657 : BaseType (ref
, ref
, TypeKind::ADT
, ident
, refs
),
658 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
),
660 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
663 ADTType (HirId ref
, HirId ty_ref
, std::string identifier
, RustIdent ident
,
664 ADTKind adt_kind
, std::vector
<VariantDef
*> variants
,
665 std::vector
<SubstitutionParamMapping
> subst_refs
,
666 SubstitutionArgumentMappings generic_arguments
667 = SubstitutionArgumentMappings::error (),
668 RegionConstraints region_constraints
= {},
669 std::set
<HirId
> refs
= std::set
<HirId
> ())
670 : BaseType (ref
, ty_ref
, TypeKind::ADT
, ident
, refs
),
671 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
),
673 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
676 ADTType (HirId ref
, HirId ty_ref
, std::string identifier
, RustIdent ident
,
677 ADTKind adt_kind
, std::vector
<VariantDef
*> variants
,
678 std::vector
<SubstitutionParamMapping
> subst_refs
, ReprOptions repr
,
679 SubstitutionArgumentMappings generic_arguments
680 = SubstitutionArgumentMappings::error (),
681 RegionConstraints region_constraints
= {},
682 std::set
<HirId
> refs
= std::set
<HirId
> ())
683 : BaseType (ref
, ty_ref
, TypeKind::ADT
, ident
, refs
),
684 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
),
686 identifier (identifier
), variants (variants
), adt_kind (adt_kind
),
690 ADTKind
get_adt_kind () const { return adt_kind
; }
692 ReprOptions
get_repr_options () const { return repr
; }
694 bool is_struct_struct () const { return adt_kind
== STRUCT_STRUCT
; }
696 bool is_tuple_struct () const { return adt_kind
== TUPLE_STRUCT
; }
698 bool is_union () const { return adt_kind
== UNION
; }
700 bool is_enum () const { return adt_kind
== ENUM
; }
702 void accept_vis (TyVisitor
&vis
) override
;
704 void accept_vis (TyConstVisitor
&vis
) const override
;
706 std::string
as_string () const override
;
708 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
710 bool is_equal (const BaseType
&other
) const override
;
712 std::string
get_identifier () const { return identifier
; }
714 std::string
get_name () const override final
716 return identifier
+ subst_as_string ();
719 BaseType
*clone () const final override
;
721 size_t number_of_variants () const { return variants
.size (); }
723 std::vector
<VariantDef
*> &get_variants () { return variants
; }
725 const std::vector
<VariantDef
*> &get_variants () const { return variants
; }
727 bool lookup_variant (const std::string
&lookup
,
728 VariantDef
**found_variant
) const
730 for (auto &variant
: variants
)
732 if (variant
->get_identifier ().compare (lookup
) == 0)
734 *found_variant
= variant
;
741 bool lookup_variant_by_id (HirId id
, VariantDef
**found_variant
,
742 int *index
= nullptr) const
745 for (auto &variant
: variants
)
747 if (variant
->get_id () == id
)
749 if (index
!= nullptr)
752 *found_variant
= variant
;
761 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
764 std::string identifier
;
765 std::vector
<VariantDef
*> variants
;
766 ADTType::ADTKind adt_kind
;
770 class FnType
: public CallableTypeInterface
, public SubstitutionRef
773 static constexpr auto KIND
= TypeKind::FNDEF
;
775 static const uint8_t FNTYPE_DEFAULT_FLAGS
= 0x00;
776 static const uint8_t FNTYPE_IS_METHOD_FLAG
= 0x01;
777 static const uint8_t FNTYPE_IS_EXTERN_FLAG
= 0x02;
778 static const uint8_t FNTYPE_IS_VARADIC_FLAG
= 0X04;
780 FnType (HirId ref
, DefId id
, std::string identifier
, RustIdent ident
,
781 uint8_t flags
, ABI abi
,
782 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
,
783 BaseType
*type
, std::vector
<SubstitutionParamMapping
> subst_refs
,
784 SubstitutionArgumentMappings substitution_argument_mappings
,
785 RegionConstraints region_constraints
,
786 std::set
<HirId
> refs
= std::set
<HirId
> ())
787 : CallableTypeInterface (ref
, ref
, TypeKind::FNDEF
, ident
, refs
),
788 SubstitutionRef (std::move (subst_refs
), substitution_argument_mappings
,
790 params (std::move (params
)), type (type
), flags (flags
),
791 identifier (identifier
), id (id
), abi (abi
)
793 LocalDefId local_def_id
= id
.localDefId
;
794 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
797 FnType (HirId ref
, HirId ty_ref
, DefId id
, std::string identifier
,
798 RustIdent ident
, uint8_t flags
, ABI abi
,
799 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
,
800 BaseType
*type
, std::vector
<SubstitutionParamMapping
> subst_refs
,
801 SubstitutionArgumentMappings substitution_argument_mappings
,
802 RegionConstraints region_constraints
,
803 std::set
<HirId
> refs
= std::set
<HirId
> ())
804 : CallableTypeInterface (ref
, ty_ref
, TypeKind::FNDEF
, ident
, refs
),
805 SubstitutionRef (std::move (subst_refs
), substitution_argument_mappings
,
807 params (params
), type (type
), flags (flags
), identifier (identifier
),
810 LocalDefId local_def_id
= id
.localDefId
;
811 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
814 void accept_vis (TyVisitor
&vis
) override
;
815 void accept_vis (TyConstVisitor
&vis
) const override
;
817 std::string
as_string () const override
;
819 std::string
get_name () const override final
{ return as_string (); }
821 std::string
get_identifier () const { return identifier
; }
823 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
825 bool is_equal (const BaseType
&other
) const override
;
827 size_t num_params () const { return params
.size (); }
829 bool is_method () const
831 if (num_params () == 0)
834 return (flags
& FNTYPE_IS_METHOD_FLAG
) != 0;
837 bool is_extern () const { return (flags
& FNTYPE_IS_EXTERN_FLAG
) != 0; }
839 bool is_variadic () const { return (flags
& FNTYPE_IS_VARADIC_FLAG
) != 0; }
841 DefId
get_id () const { return id
; }
843 // get the Self type for the method
844 BaseType
*get_self_type () const
846 rust_assert (is_method ());
847 return param_at (0).second
;
850 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params ()
855 const std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params () const
860 std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
)
862 return params
.at (idx
);
865 const std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
) const
867 return params
.at (idx
);
870 BaseType
*clone () const final override
;
873 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
875 ABI
get_abi () const { return abi
; }
876 uint8_t get_flags () const { return flags
; }
878 WARN_UNUSED_RESULT
size_t get_num_params () const override
880 return params
.size ();
883 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
885 return param_at (index
).second
;
888 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
894 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
;
897 std::string identifier
;
902 class FnPtr
: public CallableTypeInterface
905 static constexpr auto KIND
= TypeKind::FNPTR
;
907 FnPtr (HirId ref
, location_t locus
, std::vector
<TyVar
> params
,
908 TyVar result_type
, std::set
<HirId
> refs
= std::set
<HirId
> ())
909 : CallableTypeInterface (ref
, ref
, TypeKind::FNPTR
,
910 {Resolver::CanonicalPath::create_empty (), locus
},
912 params (std::move (params
)), result_type (result_type
)
915 FnPtr (HirId ref
, HirId ty_ref
, location_t locus
, std::vector
<TyVar
> params
,
916 TyVar result_type
, std::set
<HirId
> refs
= std::set
<HirId
> ())
917 : CallableTypeInterface (ref
, ty_ref
, TypeKind::FNPTR
,
918 {Resolver::CanonicalPath::create_empty (), locus
},
920 params (params
), result_type (result_type
)
923 std::string
get_name () const override final
{ return as_string (); }
925 WARN_UNUSED_RESULT
size_t get_num_params () const override
927 return params
.size ();
930 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
932 return params
.at (index
).get_tyty ();
935 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
937 return result_type
.get_tyty ();
940 const TyVar
&get_var_return_type () const { return result_type
; }
942 size_t num_params () const { return params
.size (); }
944 void accept_vis (TyVisitor
&vis
) override
;
945 void accept_vis (TyConstVisitor
&vis
) const override
;
947 std::string
as_string () const override
;
949 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
951 bool is_equal (const BaseType
&other
) const override
;
953 BaseType
*clone () const final override
;
955 std::vector
<TyVar
> &get_params () { return params
; }
956 const std::vector
<TyVar
> &get_params () const { return params
; }
959 std::vector
<TyVar
> params
;
963 class ClosureType
: public CallableTypeInterface
, public SubstitutionRef
966 static constexpr auto KIND
= TypeKind::CLOSURE
;
968 ClosureType (HirId ref
, DefId id
, RustIdent ident
, TupleType
*parameters
,
970 std::vector
<SubstitutionParamMapping
> subst_refs
,
971 std::set
<NodeId
> captures
,
972 std::set
<HirId
> refs
= std::set
<HirId
> (),
973 std::vector
<TypeBoundPredicate
> specified_bounds
974 = std::vector
<TypeBoundPredicate
> ())
975 : CallableTypeInterface (ref
, ref
, TypeKind::CLOSURE
, ident
, refs
),
976 SubstitutionRef (std::move (subst_refs
),
977 SubstitutionArgumentMappings::error (),
978 {}), // TODO: check region constraints
979 parameters (parameters
), result_type (std::move (result_type
)), id (id
),
982 LocalDefId local_def_id
= id
.localDefId
;
983 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
984 inherit_bounds (specified_bounds
);
987 ClosureType (HirId ref
, HirId ty_ref
, RustIdent ident
, DefId id
,
988 TupleType
*parameters
, TyVar result_type
,
989 std::vector
<SubstitutionParamMapping
> subst_refs
,
990 std::set
<NodeId
> captures
,
991 std::set
<HirId
> refs
= std::set
<HirId
> (),
992 std::vector
<TypeBoundPredicate
> specified_bounds
993 = std::vector
<TypeBoundPredicate
> ())
994 : CallableTypeInterface (ref
, ty_ref
, TypeKind::CLOSURE
, ident
, refs
),
995 SubstitutionRef (std::move (subst_refs
),
996 SubstitutionArgumentMappings::error (), {}), // TODO
997 parameters (parameters
), result_type (std::move (result_type
)), id (id
),
1000 LocalDefId local_def_id
= id
.localDefId
;
1001 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1002 inherit_bounds (specified_bounds
);
1005 void accept_vis (TyVisitor
&vis
) override
;
1006 void accept_vis (TyConstVisitor
&vis
) const override
;
1008 WARN_UNUSED_RESULT
size_t get_num_params () const override
1010 return parameters
->num_fields ();
1013 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
1015 return parameters
->get_field (index
);
1018 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
1020 return result_type
.get_tyty ();
1023 std::string
as_string () const override
;
1024 std::string
get_name () const override final
{ return as_string (); }
1026 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1028 bool is_equal (const BaseType
&other
) const override
;
1030 BaseType
*clone () const final override
;
1033 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
1035 TyTy::TupleType
&get_parameters () const { return *parameters
; }
1036 TyTy::BaseType
&get_result_type () const { return *result_type
.get_tyty (); }
1038 DefId
get_def_id () const { return id
; }
1040 void setup_fn_once_output () const;
1042 const std::set
<NodeId
> &get_captures () const { return captures
; }
1045 TyTy::TupleType
*parameters
;
1048 std::set
<NodeId
> captures
;
1051 class ArrayType
: public BaseType
1054 static constexpr auto KIND
= TypeKind::ARRAY
;
1056 ArrayType (HirId ref
, location_t locus
, HIR::Expr
&capacity_expr
, TyVar base
,
1057 std::set
<HirId
> refs
= std::set
<HirId
> ())
1058 : BaseType (ref
, ref
, TypeKind::ARRAY
,
1059 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1060 element_type (base
), capacity_expr (capacity_expr
)
1063 ArrayType (HirId ref
, HirId ty_ref
, location_t locus
,
1064 HIR::Expr
&capacity_expr
, TyVar base
,
1065 std::set
<HirId
> refs
= std::set
<HirId
> ())
1066 : BaseType (ref
, ty_ref
, TypeKind::ARRAY
,
1067 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1068 element_type (base
), capacity_expr (capacity_expr
)
1071 void accept_vis (TyVisitor
&vis
) override
;
1072 void accept_vis (TyConstVisitor
&vis
) const override
;
1074 std::string
as_string () const override
;
1076 std::string
get_name () const override final
{ return as_string (); }
1078 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1080 bool is_equal (const BaseType
&other
) const override
;
1082 BaseType
*get_element_type () const;
1083 const TyVar
&get_var_element_type () const;
1085 BaseType
*clone () const final override
;
1087 HIR::Expr
&get_capacity_expr () const { return capacity_expr
; }
1089 ArrayType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1093 // FIXME: I dont think this should be in tyty - tyty should already be const
1095 HIR::Expr
&capacity_expr
;
1098 class SliceType
: public BaseType
1101 static constexpr auto KIND
= TypeKind::SLICE
;
1103 SliceType (HirId ref
, location_t locus
, TyVar base
,
1104 std::set
<HirId
> refs
= std::set
<HirId
> ())
1105 : BaseType (ref
, ref
, TypeKind::SLICE
,
1106 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1110 SliceType (HirId ref
, HirId ty_ref
, location_t locus
, TyVar base
,
1111 std::set
<HirId
> refs
= std::set
<HirId
> ())
1112 : BaseType (ref
, ty_ref
, TypeKind::SLICE
,
1113 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1117 void accept_vis (TyVisitor
&vis
) override
;
1118 void accept_vis (TyConstVisitor
&vis
) const override
;
1120 std::string
as_string () const override
;
1122 std::string
get_name () const override final
{ return as_string (); }
1124 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1126 bool is_equal (const BaseType
&other
) const override
;
1128 BaseType
*get_element_type () const;
1129 const TyVar
&get_var_element_type () const;
1131 BaseType
*clone () const final override
;
1133 SliceType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1139 class BoolType
: public BaseType
1142 static constexpr auto KIND
= TypeKind::BOOL
;
1144 BoolType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1145 BoolType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1147 void accept_vis (TyVisitor
&vis
) override
;
1148 void accept_vis (TyConstVisitor
&vis
) const override
;
1150 std::string
as_string () const override
;
1152 std::string
get_name () const override final
;
1154 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1156 BaseType
*clone () const final override
;
1159 class IntType
: public BaseType
1171 static constexpr auto KIND
= TypeKind::INT
;
1173 IntType (HirId ref
, IntKind kind
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1174 IntType (HirId ref
, HirId ty_ref
, IntKind kind
,
1175 std::set
<HirId
> refs
= std::set
<HirId
> ());
1177 void accept_vis (TyVisitor
&vis
) override
;
1178 void accept_vis (TyConstVisitor
&vis
) const override
;
1180 std::string
as_string () const override
;
1182 std::string
get_name () const override final
;
1184 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1186 IntKind
get_int_kind () const;
1188 BaseType
*clone () const final override
;
1190 bool is_equal (const BaseType
&other
) const override
;
1196 class UintType
: public BaseType
1199 static constexpr auto KIND
= TypeKind::UINT
;
1210 UintType (HirId ref
, UintKind kind
,
1211 std::set
<HirId
> refs
= std::set
<HirId
> ());
1212 UintType (HirId ref
, HirId ty_ref
, UintKind kind
,
1213 std::set
<HirId
> refs
= std::set
<HirId
> ());
1215 void accept_vis (TyVisitor
&vis
) override
;
1216 void accept_vis (TyConstVisitor
&vis
) const override
;
1218 std::string
as_string () const override
;
1220 std::string
get_name () const override final
;
1222 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1224 UintKind
get_uint_kind () const;
1226 BaseType
*clone () const final override
;
1228 bool is_equal (const BaseType
&other
) const override
;
1234 class FloatType
: public BaseType
1237 static constexpr auto KIND
= TypeKind::FLOAT
;
1245 FloatType (HirId ref
, FloatKind kind
,
1246 std::set
<HirId
> refs
= std::set
<HirId
> ());
1247 FloatType (HirId ref
, HirId ty_ref
, FloatKind kind
,
1248 std::set
<HirId
> refs
= std::set
<HirId
> ());
1250 void accept_vis (TyVisitor
&vis
) override
;
1251 void accept_vis (TyConstVisitor
&vis
) const override
;
1253 std::string
as_string () const override
;
1254 std::string
get_name () const override final
;
1256 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1258 FloatKind
get_float_kind () const;
1260 BaseType
*clone () const final override
;
1262 bool is_equal (const BaseType
&other
) const override
;
1265 FloatKind float_kind
;
1268 class USizeType
: public BaseType
1271 static constexpr auto KIND
= TypeKind::USIZE
;
1273 USizeType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1274 USizeType (HirId ref
, HirId ty_ref
,
1275 std::set
<HirId
> refs
= std::set
<HirId
> ());
1277 void accept_vis (TyVisitor
&vis
) override
;
1278 void accept_vis (TyConstVisitor
&vis
) const override
;
1280 std::string
as_string () const override
;
1281 std::string
get_name () const override final
;
1283 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1285 BaseType
*clone () const final override
;
1288 class ISizeType
: public BaseType
1291 static constexpr auto KIND
= TypeKind::ISIZE
;
1293 ISizeType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1294 ISizeType (HirId ref
, HirId ty_ref
,
1295 std::set
<HirId
> refs
= std::set
<HirId
> ());
1297 void accept_vis (TyVisitor
&vis
) override
;
1298 void accept_vis (TyConstVisitor
&vis
) const override
;
1300 std::string
as_string () const override
;
1301 std::string
get_name () const override final
;
1303 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1305 BaseType
*clone () const final override
;
1308 class CharType
: public BaseType
1311 static constexpr auto KIND
= TypeKind::CHAR
;
1313 CharType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1314 CharType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1316 void accept_vis (TyVisitor
&vis
) override
;
1317 void accept_vis (TyConstVisitor
&vis
) const override
;
1319 std::string
as_string () const override
;
1320 std::string
get_name () const override final
;
1322 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1324 BaseType
*clone () const final override
;
1327 class StrType
: public BaseType
1330 static constexpr auto KIND
= TypeKind::STR
;
1332 StrType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1333 StrType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1335 std::string
get_name () const override final
;
1337 void accept_vis (TyVisitor
&vis
) override
;
1338 void accept_vis (TyConstVisitor
&vis
) const override
;
1340 std::string
as_string () const override
;
1342 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1344 bool is_equal (const BaseType
&other
) const override
;
1346 BaseType
*clone () const final override
;
1349 class DynamicObjectType
: public BaseType
1352 static constexpr auto KIND
= TypeKind::DYNAMIC
;
1354 DynamicObjectType (HirId ref
, RustIdent ident
,
1355 std::vector
<TypeBoundPredicate
> specified_bounds
,
1356 std::set
<HirId
> refs
= std::set
<HirId
> ());
1358 DynamicObjectType (HirId ref
, HirId ty_ref
, RustIdent ident
,
1359 std::vector
<TypeBoundPredicate
> specified_bounds
,
1360 std::set
<HirId
> refs
= std::set
<HirId
> ());
1362 void accept_vis (TyVisitor
&vis
) override
;
1363 void accept_vis (TyConstVisitor
&vis
) const override
;
1365 std::string
as_string () const override
;
1367 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1369 bool is_equal (const BaseType
&other
) const override
;
1371 BaseType
*clone () const final override
;
1373 std::string
get_name () const override final
;
1375 // this returns a flat list of items including super trait bounds
1377 std::pair
<const Resolver::TraitItemReference
*, const TypeBoundPredicate
*>>
1378 get_object_items () const;
1381 class ReferenceType
: public BaseType
1384 static constexpr auto KIND
= REF
;
1386 ReferenceType (HirId ref
, TyVar base
, Mutability mut
,
1387 Region region
= Region::make_anonymous (),
1388 std::set
<HirId
> refs
= std::set
<HirId
> ());
1389 ReferenceType (HirId ref
, HirId ty_ref
, TyVar base
, Mutability mut
,
1390 Region region
= Region::make_anonymous (),
1391 std::set
<HirId
> refs
= std::set
<HirId
> ());
1393 BaseType
*get_base () const;
1394 const TyVar
&get_var_element_type () const;
1396 void accept_vis (TyVisitor
&vis
) override
;
1397 void accept_vis (TyConstVisitor
&vis
) const override
;
1399 std::string
as_string () const override
;
1401 std::string
get_name () const override final
;
1403 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1405 bool is_equal (const BaseType
&other
) const override
;
1407 BaseType
*clone () const final override
;
1409 ReferenceType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1411 Mutability
mutability () const;
1412 bool is_mutable () const;
1414 WARN_UNUSED_RESULT Region
get_region () const;
1415 void set_region (Region region
);
1417 bool is_dyn_object () const;
1418 bool is_dyn_slice_type (const TyTy::SliceType
**slice
= nullptr) const;
1419 bool is_dyn_str_type (const TyTy::StrType
**str
= nullptr) const;
1420 bool is_dyn_obj_type (const TyTy::DynamicObjectType
**dyn
= nullptr) const;
1428 class PointerType
: public BaseType
1431 static constexpr auto KIND
= TypeKind::POINTER
;
1433 PointerType (HirId ref
, TyVar base
, Mutability mut
,
1434 std::set
<HirId
> refs
= std::set
<HirId
> ());
1435 PointerType (HirId ref
, HirId ty_ref
, TyVar base
, Mutability mut
,
1436 std::set
<HirId
> refs
= std::set
<HirId
> ());
1438 BaseType
*get_base () const;
1439 const TyVar
&get_var_element_type () const;
1441 void accept_vis (TyVisitor
&vis
) override
;
1442 void accept_vis (TyConstVisitor
&vis
) const override
;
1444 std::string
as_string () const override
;
1445 std::string
get_name () const override final
;
1447 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1449 bool is_equal (const BaseType
&other
) const override
;
1451 BaseType
*clone () const final override
;
1453 PointerType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1455 Mutability
mutability () const;
1456 bool is_mutable () const;
1457 bool is_const () const;
1458 bool is_dyn_object () const;
1459 bool is_dyn_slice_type (const TyTy::SliceType
**slice
= nullptr) const;
1460 bool is_dyn_str_type (const TyTy::StrType
**str
= nullptr) const;
1461 bool is_dyn_obj_type (const TyTy::DynamicObjectType
**dyn
= nullptr) const;
1468 // https://doc.rust-lang.org/std/primitive.never.html
1470 // Since the `!` type is really complicated and it is even still unstable
1471 // in rustc, only fairly limited support for this type is introduced here.
1472 // Unification between `!` and ANY other type (including `<T?>`) is simply
1473 // not allowed. If it is needed, it should be handled manually. For example,
1474 // unifying `!` with other types is very necessary when resolving types of
1475 // `if/else` expressions.
1477 // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
1478 class NeverType
: public BaseType
1481 static constexpr auto KIND
= TypeKind::NEVER
;
1483 NeverType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1485 NeverType (HirId ref
, HirId ty_ref
,
1486 std::set
<HirId
> refs
= std::set
<HirId
> ());
1488 void accept_vis (TyVisitor
&vis
) override
;
1490 void accept_vis (TyConstVisitor
&vis
) const override
;
1492 std::string
as_string () const override
;
1494 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1496 BaseType
*clone () const final override
;
1498 std::string
get_name () const override final
;
1501 // used at the type in associated types in traits
1502 // see: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
1503 class PlaceholderType
: public BaseType
1506 static constexpr auto KIND
= TypeKind::PLACEHOLDER
;
1508 PlaceholderType (std::string symbol
, HirId ref
,
1509 std::set
<HirId
> refs
= std::set
<HirId
> ());
1510 PlaceholderType (std::string symbol
, HirId ref
, HirId ty_ref
,
1511 std::set
<HirId
> refs
= std::set
<HirId
> ());
1513 void accept_vis (TyVisitor
&vis
) override
;
1514 void accept_vis (TyConstVisitor
&vis
) const override
;
1516 std::string
as_string () const override
;
1518 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1520 BaseType
*clone () const final override
;
1522 std::string
get_name () const override final
;
1524 std::string
get_symbol () const;
1526 void set_associated_type (HirId ref
);
1528 void clear_associated_type ();
1530 bool can_resolve () const;
1532 BaseType
*resolve () const;
1534 bool is_equal (const BaseType
&other
) const override
;
1540 class ProjectionType
: public BaseType
, public SubstitutionRef
1543 static constexpr auto KIND
= TypeKind::PROJECTION
;
1545 ProjectionType (HirId ref
, BaseType
*base
,
1546 const Resolver::TraitReference
*trait
, DefId item
,
1547 std::vector
<SubstitutionParamMapping
> subst_refs
,
1548 SubstitutionArgumentMappings generic_arguments
1549 = SubstitutionArgumentMappings::error (),
1550 RegionConstraints region_constraints
= {},
1551 std::set
<HirId
> refs
= std::set
<HirId
> ());
1553 ProjectionType (HirId ref
, HirId ty_ref
, BaseType
*base
,
1554 const Resolver::TraitReference
*trait
, DefId item
,
1555 std::vector
<SubstitutionParamMapping
> subst_refs
,
1556 SubstitutionArgumentMappings generic_arguments
1557 = SubstitutionArgumentMappings::error (),
1558 RegionConstraints region_constraints
= {},
1559 std::set
<HirId
> refs
= std::set
<HirId
> ());
1561 void accept_vis (TyVisitor
&vis
) override
;
1562 void accept_vis (TyConstVisitor
&vis
) const override
;
1564 std::string
as_string () const override
;
1566 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1568 BaseType
*clone () const final override
;
1570 std::string
get_name () const override final
;
1572 const BaseType
*get () const;
1576 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
1580 const Resolver::TraitReference
*trait
;
1585 WARN_UNUSED_RESULT
inline bool
1586 BaseType::is
<CallableTypeInterface
> () const
1588 auto kind
= this->get_kind ();
1589 return kind
== FNPTR
|| kind
== FNDEF
|| kind
== CLOSURE
;
1593 WARN_UNUSED_RESULT
inline bool
1594 BaseType::is
<const CallableTypeInterface
> () const
1596 return this->is
<CallableTypeInterface
> ();
1600 WARN_UNUSED_RESULT
inline bool
1601 BaseType::is
<SubstitutionRef
> () const
1603 auto kind
= this->get_kind ();
1604 return kind
== FNPTR
|| kind
== FNDEF
|| kind
== CLOSURE
|| kind
== ADT
1605 || kind
== PROJECTION
;
1609 WARN_UNUSED_RESULT
inline bool
1610 BaseType::is
<const SubstitutionRef
> () const
1612 return this->is
<SubstitutionRef
> ();
1616 WARN_UNUSED_RESULT
inline SubstitutionRef
*
1617 BaseType::as
<SubstitutionRef
> ()
1619 auto kind
= this->get_kind ();
1623 return static_cast<FnType
*> (this);
1625 return static_cast<ClosureType
*> (this);
1627 return static_cast<ADTType
*> (this);
1629 return static_cast<ProjectionType
*> (this);
1631 rust_unreachable ();
1636 WARN_UNUSED_RESULT
inline const SubstitutionRef
*
1637 BaseType::as
<const SubstitutionRef
> () const
1639 auto kind
= this->get_kind ();
1643 return static_cast<const FnType
*> (this);
1645 return static_cast<const ClosureType
*> (this);
1647 return static_cast<const ADTType
*> (this);
1649 return static_cast<const ProjectionType
*> (this);
1651 rust_unreachable ();
1656 WARN_UNUSED_RESULT
inline SubstitutionRef
*
1657 BaseType::try_as
<SubstitutionRef
> ()
1659 if (this->is
<SubstitutionRef
> ())
1661 return this->as
<SubstitutionRef
> ();
1667 WARN_UNUSED_RESULT
inline const SubstitutionRef
*
1668 BaseType::try_as
<const SubstitutionRef
> () const
1670 if (this->is
<const SubstitutionRef
> ())
1672 return this->as
<const SubstitutionRef
> ();