1 // Copyright (C) 2020-2024 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"
38 class TraitItemReference
;
40 class AssociatedImplTrait
;
41 } // namespace Resolver
47 class CallableTypeInterface
;
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
76 // there are more to add...
81 is_primitive_type_kind (TypeKind kind
);
86 static std::string
to_string (TypeKind kind
);
91 class BaseType
: public TypeBoundsMappings
96 HirId
get_ref () const;
97 void set_ref (HirId id
);
99 HirId
get_ty_ref () const;
100 void set_ty_ref (HirId id
);
102 HirId
get_orig_ref () const;
104 virtual void accept_vis (TyVisitor
&vis
) = 0;
105 virtual void accept_vis (TyConstVisitor
&vis
) const = 0;
107 virtual std::string
as_string () const = 0;
108 virtual std::string
get_name () const = 0;
110 // similar to unify but does not actually perform type unification but
111 // determines whether they are compatible. Consider the following
113 // fn foo<T>() -> T { ... }
114 // fn foo() -> i32 { ... }
116 // when the function has been substituted they can be considered equal.
118 // It can also be used to optional emit errors for trait item compatibility
120 virtual bool can_eq (const BaseType
*other
, bool emit_errors
) const = 0;
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;
128 bool satisfies_bound (const TypeBoundPredicate
&predicate
,
129 bool emit_error
) const;
131 bool bounds_compatible (const BaseType
&other
, location_t locus
,
132 bool emit_error
) const;
134 void inherit_bounds (const BaseType
&other
);
136 void inherit_bounds (
137 const std::vector
<TyTy::TypeBoundPredicate
> &specified_bounds
);
139 // is_unit returns whether this is just a unit-struct
140 bool is_unit () const;
142 // is_concrete returns true if the type is fully resolved to concrete
144 bool is_concrete () const;
146 // return the type-kind
147 TypeKind
get_kind () const;
149 // monomorphized clone is a clone which destructures the types to get rid of
151 BaseType
*monomorphized_clone () const;
153 // get_combined_refs returns the chain of node refs involved in unification
154 std::set
<HirId
> get_combined_refs () const;
156 void append_reference (HirId id
);
158 std::string
mappings_str () const;
160 std::string
debug_str () const;
164 // FIXME this will eventually go away
165 const BaseType
*get_root () const;
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;
172 const RustIdent
&get_ident () const;
173 location_t
get_locus () const;
175 bool has_substitutions_defined () const;
176 bool needs_generic_substitutions () const;
178 std::string
mangle_string () const
180 return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
181 + mappings_str () + ":" + bounds_as_string ();
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;
188 // Check if TyTy::BaseType is of a specific type.
189 template <typename T
> WARN_UNUSED_RESULT
bool is () const
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
;
196 template <typename T
> T
*as () const
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);
204 template <typename T
> T
*as ()
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);
212 // Check if TyTy::BaseType is of a specific type and convert it to that type
214 // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler
216 template <typename T
> T
*try_as () const
218 static_assert (std::is_base_of
<BaseType
, T
>::value
,
219 "Can only safely cast to TyTy types.");
223 return static_cast<T
*> (this);
227 template <typename T
> T
*try_as ()
229 static_assert (std::is_base_of
<BaseType
, T
>::value
,
230 "Can only safely cast to TyTy types.");
234 return static_cast<T
*> (this);
238 BaseType (HirId ref
, HirId ty_ref
, TypeKind kind
, RustIdent ident
,
239 std::set
<HirId
> refs
= std::set
<HirId
> ());
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
> ());
248 const HirId orig_ref
;
249 std::set
<HirId
> combined
;
252 Analysis::Mappings
*mappings
;
255 /** Unified interface for all function-like types. */
256 class CallableTypeInterface
: public BaseType
259 explicit CallableTypeInterface (HirId ref
, HirId ty_ref
, TypeKind kind
,
261 std::set
<HirId
> refs
= std::set
<HirId
> ())
262 : BaseType (ref
, ty_ref
, kind
, ident
, refs
)
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;
271 class InferType
: public BaseType
274 static constexpr auto KIND
= TypeKind::INFER
;
306 static TypeHint
Default ()
308 return TypeHint
{TypeKind::ERROR
, UNKNOWN
, SUNKNOWN
};
312 InferType (HirId ref
, InferTypeKind infer_kind
, TypeHint hint
,
313 location_t locus
, std::set
<HirId
> refs
= std::set
<HirId
> ());
315 InferType (HirId ref
, HirId ty_ref
, InferTypeKind infer_kind
, TypeHint hint
,
316 location_t locus
, std::set
<HirId
> refs
= std::set
<HirId
> ());
318 void accept_vis (TyVisitor
&vis
) override
;
320 void accept_vis (TyConstVisitor
&vis
) const override
;
322 std::string
as_string () const override
;
324 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
326 BaseType
*clone () const final override
;
328 InferTypeKind
get_infer_kind () const;
330 std::string
get_name () const override final
;
332 bool default_type (BaseType
**type
) const;
334 void apply_primitive_type_hint (const TyTy::BaseType
&hint
);
337 InferTypeKind infer_kind
;
338 TypeHint default_hint
;
341 class ErrorType
: public BaseType
344 static constexpr auto KIND
= TypeKind::ERROR
;
346 ErrorType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
348 ErrorType (HirId ref
, HirId ty_ref
,
349 std::set
<HirId
> refs
= std::set
<HirId
> ());
351 void accept_vis (TyVisitor
&vis
) override
;
352 void accept_vis (TyConstVisitor
&vis
) const override
;
354 std::string
as_string () const override
;
356 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
358 BaseType
*clone () const final override
;
360 std::string
get_name () const override final
;
363 class ParamType
: public BaseType
366 static constexpr auto KIND
= TypeKind::PARAM
;
368 ParamType (std::string symbol
, location_t locus
, HirId ref
,
369 HIR::GenericParam
¶m
,
370 std::vector
<TypeBoundPredicate
> specified_bounds
,
371 std::set
<HirId
> refs
= std::set
<HirId
> ());
373 ParamType (bool is_trait_self
, std::string symbol
, location_t locus
,
374 HirId ref
, HirId ty_ref
, HIR::GenericParam
¶m
,
375 std::vector
<TypeBoundPredicate
> specified_bounds
,
376 std::set
<HirId
> refs
= std::set
<HirId
> ());
378 void accept_vis (TyVisitor
&vis
) override
;
379 void accept_vis (TyConstVisitor
&vis
) const override
;
381 std::string
as_string () const override
;
383 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
385 BaseType
*clone () const final override
;
387 std::string
get_symbol () const;
389 HIR::GenericParam
&get_generic_param ();
391 bool can_resolve () const;
393 BaseType
*resolve () const;
395 std::string
get_name () const override final
;
397 bool is_equal (const BaseType
&other
) const override
;
399 ParamType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
401 void set_implicit_self_trait ();
402 bool is_implicit_self_trait () const;
407 HIR::GenericParam
¶m
;
410 class StructFieldType
413 StructFieldType (HirId ref
, std::string name
, BaseType
*ty
, location_t locus
);
415 HirId
get_ref () const;
417 bool is_equal (const StructFieldType
&other
) const;
419 std::string
get_name () const;
421 BaseType
*get_field_type () const;
422 void set_field_type (BaseType
*fty
);
424 StructFieldType
*clone () const;
425 StructFieldType
*monomorphized_clone () const;
428 location_t
get_locus () const;
429 std::string
as_string () const;
438 class TupleType
: public BaseType
441 static constexpr auto KIND
= TypeKind::TUPLE
;
443 TupleType (HirId ref
, location_t locus
,
444 std::vector
<TyVar
> fields
= std::vector
<TyVar
> (),
445 std::set
<HirId
> refs
= std::set
<HirId
> ());
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
> ());
451 static TupleType
*get_unit_type (HirId ref
);
453 void accept_vis (TyVisitor
&vis
) override
;
454 void accept_vis (TyConstVisitor
&vis
) const override
;
456 std::string
as_string () const override
;
458 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
460 bool is_equal (const BaseType
&other
) const override
;
462 size_t num_fields () const;
464 BaseType
*get_field (size_t index
) const;
466 BaseType
*clone () const final override
;
468 const std::vector
<TyVar
> &get_fields () const;
470 std::string
get_name () const override final
;
472 TupleType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
475 std::vector
<TyVar
> fields
;
478 class TypeBoundPredicate
: public SubstitutionRef
481 TypeBoundPredicate (const Resolver::TraitReference
&trait_reference
,
482 BoundPolarity polarity
, location_t locus
);
484 TypeBoundPredicate (DefId reference
,
485 std::vector
<SubstitutionParamMapping
> substitutions
,
486 BoundPolarity polarity
, location_t locus
);
488 TypeBoundPredicate (const TypeBoundPredicate
&other
);
490 virtual ~TypeBoundPredicate (){};
492 TypeBoundPredicate
&operator= (const TypeBoundPredicate
&other
);
494 static TypeBoundPredicate
error ();
496 std::string
as_string () const;
498 std::string
as_name () const;
500 const Resolver::TraitReference
*get () const;
502 location_t
get_locus () const { return locus
; }
504 std::string
get_name () const;
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;
510 void apply_generic_arguments (HIR::GenericArgs
*generic_args
,
511 bool has_associated_self
);
513 bool contains_item (const std::string
&search
) const;
515 TypeBoundPredicateItem
516 lookup_associated_item (const std::string
&search
) const;
518 TypeBoundPredicateItem
519 lookup_associated_item (const Resolver::TraitItemReference
*ref
) const;
521 // WARNING THIS WILL ALWAYS RETURN NULLPTR
523 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
525 bool is_error () const;
527 bool requires_generic_args () const;
529 bool contains_associated_types () const;
531 DefId
get_id () const { return reference
; }
533 BoundPolarity
get_polarity () const { return polarity
; }
535 std::vector
<TypeBoundPredicateItem
> get_associated_type_items ();
537 size_t get_num_associated_bindings () const override final
;
539 TypeBoundPredicateItem
540 lookup_associated_type (const std::string
&search
) override final
;
542 bool is_equal (const TypeBoundPredicate
&other
) const;
549 TypeBoundPredicate (mark_is_error
);
554 BoundPolarity polarity
;
557 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
568 static std::string
variant_type_string (VariantType type
);
570 VariantDef (HirId id
, DefId defid
, std::string identifier
, RustIdent ident
,
571 HIR::Expr
*discriminant
);
573 VariantDef (HirId id
, DefId defid
, std::string identifier
, RustIdent ident
,
574 VariantType type
, HIR::Expr
*discriminant
,
575 std::vector
<StructFieldType
*> fields
);
577 VariantDef (const VariantDef
&other
);
579 VariantDef
&operator= (const VariantDef
&other
);
581 static VariantDef
&get_error_node ();
582 bool is_error () const;
584 HirId
get_id () const;
585 DefId
get_defid () const;
587 VariantType
get_variant_type () const;
588 bool is_data_variant () const;
589 bool is_dataless_variant () const;
591 std::string
get_identifier () const;
593 size_t num_fields () const;
594 StructFieldType
*get_field_at_index (size_t index
);
596 std::vector
<StructFieldType
*> &get_fields ();
598 bool lookup_field (const std::string
&lookup
, StructFieldType
**field_lookup
,
599 size_t *index
) const;
601 HIR::Expr
*get_discriminant () const;
603 std::string
as_string () const;
605 bool is_equal (const VariantDef
&other
) const;
607 VariantDef
*clone () const;
609 VariantDef
*monomorphized_clone () const;
611 const RustIdent
&get_ident () const;
616 std::string identifier
;
619 // can either be a structure or a discriminant value
620 HIR::Expr
*discriminant
;
621 std::vector
<StructFieldType
*> fields
;
624 class ADTType
: public BaseType
, public SubstitutionRef
627 static constexpr auto KIND
= TypeKind::ADT
;
637 // Representation options, specified via attributes e.g. #[repr(packed)]
641 // bool is_transparent;
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;
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
),
661 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
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
),
674 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
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
),
687 identifier (identifier
), variants (variants
), adt_kind (adt_kind
),
691 ADTKind
get_adt_kind () const { return adt_kind
; }
693 ReprOptions
get_repr_options () const { return repr
; }
695 bool is_struct_struct () const { return adt_kind
== STRUCT_STRUCT
; }
697 bool is_tuple_struct () const { return adt_kind
== TUPLE_STRUCT
; }
699 bool is_union () const { return adt_kind
== UNION
; }
701 bool is_enum () const { return adt_kind
== ENUM
; }
703 void accept_vis (TyVisitor
&vis
) override
;
705 void accept_vis (TyConstVisitor
&vis
) const override
;
707 std::string
as_string () const override
;
709 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
711 bool is_equal (const BaseType
&other
) const override
;
713 std::string
get_identifier () const { return identifier
; }
715 std::string
get_name () const override final
717 return identifier
+ subst_as_string ();
720 BaseType
*clone () const final override
;
722 size_t number_of_variants () const { return variants
.size (); }
724 std::vector
<VariantDef
*> &get_variants () { return variants
; }
726 const std::vector
<VariantDef
*> &get_variants () const { return variants
; }
728 bool lookup_variant (const std::string
&lookup
,
729 VariantDef
**found_variant
) const
731 for (auto &variant
: variants
)
733 if (variant
->get_identifier ().compare (lookup
) == 0)
735 *found_variant
= variant
;
742 bool lookup_variant_by_id (HirId id
, VariantDef
**found_variant
,
743 int *index
= nullptr) const
746 for (auto &variant
: variants
)
748 if (variant
->get_id () == id
)
750 if (index
!= nullptr)
753 *found_variant
= variant
;
762 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
765 std::string identifier
;
766 std::vector
<VariantDef
*> variants
;
767 ADTType::ADTKind adt_kind
;
771 class FnType
: public CallableTypeInterface
, public SubstitutionRef
774 static constexpr auto KIND
= TypeKind::FNDEF
;
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;
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
,
791 params (std::move (params
)), type (type
), flags (flags
),
792 identifier (identifier
), id (id
), abi (abi
)
794 LocalDefId local_def_id
= id
.localDefId
;
795 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
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
,
808 params (params
), type (type
), flags (flags
), identifier (identifier
),
811 LocalDefId local_def_id
= id
.localDefId
;
812 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
815 void accept_vis (TyVisitor
&vis
) override
;
816 void accept_vis (TyConstVisitor
&vis
) const override
;
818 std::string
as_string () const override
;
820 std::string
get_name () const override final
{ return as_string (); }
822 std::string
get_identifier () const { return identifier
; }
824 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
826 bool is_equal (const BaseType
&other
) const override
;
828 size_t num_params () const { return params
.size (); }
830 bool is_method () const
832 if (num_params () == 0)
835 return (flags
& FNTYPE_IS_METHOD_FLAG
) != 0;
838 bool is_extern () const { return (flags
& FNTYPE_IS_EXTERN_FLAG
) != 0; }
840 bool is_variadic () const { return (flags
& FNTYPE_IS_VARADIC_FLAG
) != 0; }
842 DefId
get_id () const { return id
; }
844 // get the Self type for the method
845 BaseType
*get_self_type () const
847 rust_assert (is_method ());
848 return param_at (0).second
;
851 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params ()
856 const std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params () const
861 std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
)
863 return params
.at (idx
);
866 const std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
) const
868 return params
.at (idx
);
871 BaseType
*clone () const final override
;
874 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
876 ABI
get_abi () const { return abi
; }
877 uint8_t get_flags () const { return flags
; }
879 WARN_UNUSED_RESULT
size_t get_num_params () const override
881 return params
.size ();
884 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
886 return param_at (index
).second
;
889 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
895 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
;
898 std::string identifier
;
903 class FnPtr
: public CallableTypeInterface
906 static constexpr auto KIND
= TypeKind::FNPTR
;
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
},
913 params (std::move (params
)), result_type (result_type
)
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
},
921 params (params
), result_type (result_type
)
924 std::string
get_name () const override final
{ return as_string (); }
926 WARN_UNUSED_RESULT
size_t get_num_params () const override
928 return params
.size ();
931 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
933 return params
.at (index
).get_tyty ();
936 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
938 return result_type
.get_tyty ();
941 const TyVar
&get_var_return_type () const { return result_type
; }
943 size_t num_params () const { return params
.size (); }
945 void accept_vis (TyVisitor
&vis
) override
;
946 void accept_vis (TyConstVisitor
&vis
) const override
;
948 std::string
as_string () const override
;
950 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
952 bool is_equal (const BaseType
&other
) const override
;
954 BaseType
*clone () const final override
;
956 std::vector
<TyVar
> &get_params () { return params
; }
957 const std::vector
<TyVar
> &get_params () const { return params
; }
960 std::vector
<TyVar
> params
;
964 class ClosureType
: public CallableTypeInterface
, public SubstitutionRef
967 static constexpr auto KIND
= TypeKind::CLOSURE
;
969 ClosureType (HirId ref
, DefId id
, RustIdent ident
, TupleType
*parameters
,
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
),
983 LocalDefId local_def_id
= id
.localDefId
;
984 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
985 inherit_bounds (specified_bounds
);
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
),
1001 LocalDefId local_def_id
= id
.localDefId
;
1002 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1003 inherit_bounds (specified_bounds
);
1006 void accept_vis (TyVisitor
&vis
) override
;
1007 void accept_vis (TyConstVisitor
&vis
) const override
;
1009 WARN_UNUSED_RESULT
size_t get_num_params () const override
1011 return parameters
->num_fields ();
1014 WARN_UNUSED_RESULT BaseType
*get_param_type_at (size_t index
) const override
1016 return parameters
->get_field (index
);
1019 WARN_UNUSED_RESULT BaseType
*get_return_type () const override
1021 return result_type
.get_tyty ();
1024 std::string
as_string () const override
;
1025 std::string
get_name () const override final
{ return as_string (); }
1027 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1029 bool is_equal (const BaseType
&other
) const override
;
1031 BaseType
*clone () const final override
;
1034 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
1036 TyTy::TupleType
&get_parameters () const { return *parameters
; }
1037 TyTy::BaseType
&get_result_type () const { return *result_type
.get_tyty (); }
1039 DefId
get_def_id () const { return id
; }
1041 void setup_fn_once_output () const;
1043 const std::set
<NodeId
> &get_captures () const { return captures
; }
1046 TyTy::TupleType
*parameters
;
1049 std::set
<NodeId
> captures
;
1052 class ArrayType
: public BaseType
1055 static constexpr auto KIND
= TypeKind::ARRAY
;
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
)
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
)
1072 void accept_vis (TyVisitor
&vis
) override
;
1073 void accept_vis (TyConstVisitor
&vis
) const override
;
1075 std::string
as_string () const override
;
1077 std::string
get_name () const override final
{ return as_string (); }
1079 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1081 bool is_equal (const BaseType
&other
) const override
;
1083 BaseType
*get_element_type () const;
1084 const TyVar
&get_var_element_type () const;
1086 BaseType
*clone () const final override
;
1088 HIR::Expr
&get_capacity_expr () const { return capacity_expr
; }
1090 ArrayType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1094 // FIXME: I dont think this should be in tyty - tyty should already be const
1096 HIR::Expr
&capacity_expr
;
1099 class SliceType
: public BaseType
1102 static constexpr auto KIND
= TypeKind::SLICE
;
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
),
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
),
1118 void accept_vis (TyVisitor
&vis
) override
;
1119 void accept_vis (TyConstVisitor
&vis
) const override
;
1121 std::string
as_string () const override
;
1123 std::string
get_name () const override final
{ return as_string (); }
1125 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1127 bool is_equal (const BaseType
&other
) const override
;
1129 BaseType
*get_element_type () const;
1130 const TyVar
&get_var_element_type () const;
1132 BaseType
*clone () const final override
;
1134 SliceType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1140 class BoolType
: public BaseType
1143 static constexpr auto KIND
= TypeKind::BOOL
;
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
> ());
1148 void accept_vis (TyVisitor
&vis
) override
;
1149 void accept_vis (TyConstVisitor
&vis
) const override
;
1151 std::string
as_string () const override
;
1153 std::string
get_name () const override final
;
1155 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1157 BaseType
*clone () const final override
;
1160 class IntType
: public BaseType
1172 static constexpr auto KIND
= TypeKind::INT
;
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
> ());
1178 void accept_vis (TyVisitor
&vis
) override
;
1179 void accept_vis (TyConstVisitor
&vis
) const override
;
1181 std::string
as_string () const override
;
1183 std::string
get_name () const override final
;
1185 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1187 IntKind
get_int_kind () const;
1189 BaseType
*clone () const final override
;
1191 bool is_equal (const BaseType
&other
) const override
;
1197 class UintType
: public BaseType
1200 static constexpr auto KIND
= TypeKind::UINT
;
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
> ());
1216 void accept_vis (TyVisitor
&vis
) override
;
1217 void accept_vis (TyConstVisitor
&vis
) const override
;
1219 std::string
as_string () const override
;
1221 std::string
get_name () const override final
;
1223 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1225 UintKind
get_uint_kind () const;
1227 BaseType
*clone () const final override
;
1229 bool is_equal (const BaseType
&other
) const override
;
1235 class FloatType
: public BaseType
1238 static constexpr auto KIND
= TypeKind::FLOAT
;
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
> ());
1251 void accept_vis (TyVisitor
&vis
) override
;
1252 void accept_vis (TyConstVisitor
&vis
) const override
;
1254 std::string
as_string () const override
;
1255 std::string
get_name () const override final
;
1257 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1259 FloatKind
get_float_kind () const;
1261 BaseType
*clone () const final override
;
1263 bool is_equal (const BaseType
&other
) const override
;
1266 FloatKind float_kind
;
1269 class USizeType
: public BaseType
1272 static constexpr auto KIND
= TypeKind::USIZE
;
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
> ());
1278 void accept_vis (TyVisitor
&vis
) override
;
1279 void accept_vis (TyConstVisitor
&vis
) const override
;
1281 std::string
as_string () const override
;
1282 std::string
get_name () const override final
;
1284 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1286 BaseType
*clone () const final override
;
1289 class ISizeType
: public BaseType
1292 static constexpr auto KIND
= TypeKind::ISIZE
;
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
> ());
1298 void accept_vis (TyVisitor
&vis
) override
;
1299 void accept_vis (TyConstVisitor
&vis
) const override
;
1301 std::string
as_string () const override
;
1302 std::string
get_name () const override final
;
1304 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1306 BaseType
*clone () const final override
;
1309 class CharType
: public BaseType
1312 static constexpr auto KIND
= TypeKind::CHAR
;
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
> ());
1317 void accept_vis (TyVisitor
&vis
) override
;
1318 void accept_vis (TyConstVisitor
&vis
) const override
;
1320 std::string
as_string () const override
;
1321 std::string
get_name () const override final
;
1323 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1325 BaseType
*clone () const final override
;
1328 class StrType
: public BaseType
1331 static constexpr auto KIND
= TypeKind::STR
;
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
> ());
1336 std::string
get_name () const override final
;
1338 void accept_vis (TyVisitor
&vis
) override
;
1339 void accept_vis (TyConstVisitor
&vis
) const override
;
1341 std::string
as_string () const override
;
1343 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1345 bool is_equal (const BaseType
&other
) const override
;
1347 BaseType
*clone () const final override
;
1350 class DynamicObjectType
: public BaseType
1353 static constexpr auto KIND
= TypeKind::DYNAMIC
;
1355 DynamicObjectType (HirId ref
, RustIdent ident
,
1356 std::vector
<TypeBoundPredicate
> specified_bounds
,
1357 std::set
<HirId
> refs
= std::set
<HirId
> ());
1359 DynamicObjectType (HirId ref
, HirId ty_ref
, RustIdent ident
,
1360 std::vector
<TypeBoundPredicate
> specified_bounds
,
1361 std::set
<HirId
> refs
= std::set
<HirId
> ());
1363 void accept_vis (TyVisitor
&vis
) override
;
1364 void accept_vis (TyConstVisitor
&vis
) const override
;
1366 std::string
as_string () const override
;
1368 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1370 bool is_equal (const BaseType
&other
) const override
;
1372 BaseType
*clone () const final override
;
1374 std::string
get_name () const override final
;
1376 // this returns a flat list of items including super trait bounds
1378 std::pair
<const Resolver::TraitItemReference
*, const TypeBoundPredicate
*>>
1379 get_object_items () const;
1382 class ReferenceType
: public BaseType
1385 static constexpr auto KIND
= REF
;
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
> ());
1394 BaseType
*get_base () const;
1395 const TyVar
&get_var_element_type () const;
1397 void accept_vis (TyVisitor
&vis
) override
;
1398 void accept_vis (TyConstVisitor
&vis
) const override
;
1400 std::string
as_string () const override
;
1402 std::string
get_name () const override final
;
1404 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1406 bool is_equal (const BaseType
&other
) const override
;
1408 BaseType
*clone () const final override
;
1410 ReferenceType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
1412 Mutability
mutability () const;
1413 bool is_mutable () const;
1415 WARN_UNUSED_RESULT Region
get_region () const;
1416 void set_region (Region region
);
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;
1429 class PointerType
: public BaseType
1432 static constexpr auto KIND
= TypeKind::POINTER
;
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
> ());
1439 BaseType
*get_base () const;
1440 const TyVar
&get_var_element_type () const;
1442 void accept_vis (TyVisitor
&vis
) override
;
1443 void accept_vis (TyConstVisitor
&vis
) const override
;
1445 std::string
as_string () const override
;
1446 std::string
get_name () const override final
;
1448 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1450 bool is_equal (const BaseType
&other
) const override
;
1452 BaseType
*clone () const final override
;
1454 PointerType
*handle_substitions (SubstitutionArgumentMappings
&mappings
);
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;
1469 // https://doc.rust-lang.org/std/primitive.never.html
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.
1478 // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
1479 class NeverType
: public BaseType
1482 static constexpr auto KIND
= TypeKind::NEVER
;
1484 NeverType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ());
1486 NeverType (HirId ref
, HirId ty_ref
,
1487 std::set
<HirId
> refs
= std::set
<HirId
> ());
1489 void accept_vis (TyVisitor
&vis
) override
;
1491 void accept_vis (TyConstVisitor
&vis
) const override
;
1493 std::string
as_string () const override
;
1495 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1497 BaseType
*clone () const final override
;
1499 std::string
get_name () const override final
;
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
1507 static constexpr auto KIND
= TypeKind::PLACEHOLDER
;
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
> ());
1514 void accept_vis (TyVisitor
&vis
) override
;
1515 void accept_vis (TyConstVisitor
&vis
) const override
;
1517 std::string
as_string () const override
;
1519 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1521 BaseType
*clone () const final override
;
1523 std::string
get_name () const override final
;
1525 std::string
get_symbol () const;
1527 void set_associated_type (HirId ref
);
1529 void clear_associated_type ();
1531 bool can_resolve () const;
1533 BaseType
*resolve () const;
1535 bool is_equal (const BaseType
&other
) const override
;
1541 class ProjectionType
: public BaseType
, public SubstitutionRef
1544 static constexpr auto KIND
= TypeKind::PROJECTION
;
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
> ());
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
> ());
1562 void accept_vis (TyVisitor
&vis
) override
;
1563 void accept_vis (TyConstVisitor
&vis
) const override
;
1565 std::string
as_string () const override
;
1567 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1569 BaseType
*clone () const final override
;
1571 std::string
get_name () const override final
;
1573 const BaseType
*get () const;
1577 handle_substitions (SubstitutionArgumentMappings
&mappings
) override final
;
1581 const Resolver::TraitReference
*trait
;
1586 WARN_UNUSED_RESULT
inline bool
1587 BaseType::is
<CallableTypeInterface
> () const
1589 auto kind
= this->get_kind ();
1590 return kind
== FNPTR
|| kind
== FNDEF
|| kind
== CLOSURE
;
1594 WARN_UNUSED_RESULT
inline bool
1595 BaseType::is
<const CallableTypeInterface
> () const
1597 return this->is
<CallableTypeInterface
> ();
1601 WARN_UNUSED_RESULT
inline bool
1602 BaseType::is
<SubstitutionRef
> () const
1604 auto kind
= this->get_kind ();
1605 return kind
== FNPTR
|| kind
== FNDEF
|| kind
== CLOSURE
|| kind
== ADT
1606 || kind
== PROJECTION
;
1610 WARN_UNUSED_RESULT
inline bool
1611 BaseType::is
<const SubstitutionRef
> () const
1613 return this->is
<SubstitutionRef
> ();
1617 WARN_UNUSED_RESULT
inline SubstitutionRef
*
1618 BaseType::as
<SubstitutionRef
> ()
1620 auto kind
= this->get_kind ();
1624 return static_cast<FnType
*> (this);
1626 return static_cast<ClosureType
*> (this);
1628 return static_cast<ADTType
*> (this);
1630 return static_cast<ProjectionType
*> (this);
1632 rust_unreachable ();
1637 WARN_UNUSED_RESULT
inline const SubstitutionRef
*
1638 BaseType::as
<const SubstitutionRef
> () const
1640 auto kind
= this->get_kind ();
1644 return static_cast<const FnType
*> (this);
1646 return static_cast<const ClosureType
*> (this);
1648 return static_cast<const ADTType
*> (this);
1650 return static_cast<const ProjectionType
*> (this);
1652 rust_unreachable ();
1657 WARN_UNUSED_RESULT
inline SubstitutionRef
*
1658 BaseType::try_as
<SubstitutionRef
> ()
1660 if (this->is
<SubstitutionRef
> ())
1662 return this->as
<SubstitutionRef
> ();
1668 WARN_UNUSED_RESULT
inline const SubstitutionRef
*
1669 BaseType::try_as
<const SubstitutionRef
> () const
1671 if (this->is
<const SubstitutionRef
> ())
1673 return this->as
<const SubstitutionRef
> ();