1 // Copyright (C) 2020-2023 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-hir-full.h"
24 #include "rust-diagnostics.h"
26 #include "rust-common.h"
27 #include "rust-identifier.h"
33 class TraitItemReference
;
34 class AssociatedImplTrait
;
35 } // namespace Resolver
39 // https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
40 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
66 // there are more to add...
71 is_primitive_type_kind (TypeKind kind
);
76 static std::string
to_string (TypeKind kind
);
80 class TypeBoundPredicate
;
81 class TypeBoundPredicateItem
84 TypeBoundPredicateItem (const TypeBoundPredicate
*parent
,
85 const Resolver::TraitItemReference
*trait_item_ref
)
86 : parent (parent
), trait_item_ref (trait_item_ref
)
89 static TypeBoundPredicateItem
error ()
91 return TypeBoundPredicateItem (nullptr, nullptr);
94 bool is_error () const
96 return parent
== nullptr || trait_item_ref
== nullptr;
99 BaseType
*get_tyty_for_receiver (const TyTy::BaseType
*receiver
);
101 const Resolver::TraitItemReference
*get_raw_item () const;
103 bool needs_implementation () const;
105 const TypeBoundPredicate
*get_parent () const { return parent
; }
107 Location
get_locus () const;
110 const TypeBoundPredicate
*parent
;
111 const Resolver::TraitItemReference
*trait_item_ref
;
114 class TypeBoundsMappings
117 TypeBoundsMappings (std::vector
<TypeBoundPredicate
> specified_bounds
);
120 std::vector
<TypeBoundPredicate
> &get_specified_bounds ();
122 const std::vector
<TypeBoundPredicate
> &get_specified_bounds () const;
124 size_t num_specified_bounds () const;
126 std::string
raw_bounds_as_string () const;
128 std::string
bounds_as_string () const;
130 std::string
raw_bounds_as_name () const;
133 void add_bound (TypeBoundPredicate predicate
);
135 std::vector
<TypeBoundPredicate
> specified_bounds
;
139 class TyConstVisitor
;
140 class BaseType
: public TypeBoundsMappings
143 virtual ~BaseType () {}
145 HirId
get_ref () const { return ref
; }
147 void set_ref (HirId id
)
150 append_reference (ref
);
154 HirId
get_ty_ref () const { return ty_ref
; }
156 void set_ty_ref (HirId id
) { ty_ref
= id
; }
158 virtual void accept_vis (TyVisitor
&vis
) = 0;
160 virtual void accept_vis (TyConstVisitor
&vis
) const = 0;
162 virtual std::string
as_string () const = 0;
164 virtual std::string
get_name () const = 0;
166 // Unify two types. Returns a pointer to the newly-created unified ty, or
167 // nullptr if the two ty cannot be unified. The caller is responsible for
168 // releasing the memory of the returned ty.
169 virtual BaseType
*unify (BaseType
*other
) = 0;
171 // similar to unify but does not actually perform type unification but
172 // determines whether they are compatible. Consider the following
174 // fn foo<T>() -> T { ... }
175 // fn foo() -> i32 { ... }
177 // when the function has been substituted they can be considered equal.
179 // It can also be used to optional emit errors for trait item compatibility
181 virtual bool can_eq (const BaseType
*other
, bool emit_errors
) const = 0;
183 // Check value equality between two ty. Type inference rules are ignored. Two
184 // ty are considered equal if they're of the same kind, and
185 // 1. (For ADTs, arrays, tuples, refs) have the same underlying ty
186 // 2. (For functions) have the same signature
187 virtual bool is_equal (const BaseType
&other
) const
189 return get_kind () == other
.get_kind ();
192 bool satisfies_bound (const TypeBoundPredicate
&predicate
) const;
194 bool bounds_compatible (const BaseType
&other
, Location locus
,
195 bool emit_error
) const;
197 void inherit_bounds (const BaseType
&other
);
199 void inherit_bounds (
200 const std::vector
<TyTy::TypeBoundPredicate
> &specified_bounds
);
202 virtual bool is_unit () const { return false; }
204 virtual bool is_concrete () const = 0;
206 TypeKind
get_kind () const { return kind
; }
208 /* Returns a pointer to a clone of this. The caller is responsible for
209 * releasing the memory of the returned ty. */
210 virtual BaseType
*clone () const = 0;
213 virtual BaseType
*monomorphized_clone () const = 0;
215 // get_combined_refs returns the chain of node refs involved in unification
216 std::set
<HirId
> get_combined_refs () const { return combined
; }
218 void append_reference (HirId id
) { combined
.insert (id
); }
220 virtual bool supports_substitutions () const { return false; }
222 virtual bool has_subsititions_defined () const { return false; }
224 virtual bool can_substitute () const
226 return supports_substitutions () && has_subsititions_defined ();
229 virtual bool needs_generic_substitutions () const { return false; }
231 bool contains_type_parameters () const { return !is_concrete (); }
233 std::string
mappings_str () const
235 std::string buffer
= "Ref: " + std::to_string (get_ref ())
236 + " TyRef: " + std::to_string (get_ty_ref ());
238 for (auto &ref
: combined
)
239 buffer
+= std::to_string (ref
) + ",";
241 return "(" + buffer
+ ")";
244 std::string
debug_str () const
246 return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
247 + mappings_str () + ":" + bounds_as_string ();
252 rust_debug ("[%p] %s", static_cast<const void *> (this),
253 debug_str ().c_str ());
256 // FIXME this will eventually go away
257 const BaseType
*get_root () const;
259 // This will get the monomorphized type from Params, Placeholders or
260 // Projections if available or error
261 const BaseType
*destructure () const;
263 const RustIdent
&get_ident () const { return ident
; }
265 Location
get_locus () const { return ident
.locus
; }
268 BaseType (HirId ref
, HirId ty_ref
, TypeKind kind
, RustIdent ident
,
269 std::set
<HirId
> refs
= std::set
<HirId
> ())
270 : TypeBoundsMappings ({}), kind (kind
), ref (ref
), ty_ref (ty_ref
),
271 combined (refs
), ident (ident
), mappings (Analysis::Mappings::get ())
274 BaseType (HirId ref
, HirId ty_ref
, TypeKind kind
, RustIdent ident
,
275 std::vector
<TypeBoundPredicate
> specified_bounds
,
276 std::set
<HirId
> refs
= std::set
<HirId
> ())
277 : TypeBoundsMappings (specified_bounds
), kind (kind
), ref (ref
),
278 ty_ref (ty_ref
), combined (refs
), ident (ident
),
279 mappings (Analysis::Mappings::get ())
285 std::set
<HirId
> combined
;
288 Analysis::Mappings
*mappings
;
291 // this is a placeholder for types that can change like inference variables
295 explicit TyVar (HirId ref
);
297 HirId
get_ref () const { return ref
; }
299 BaseType
*get_tyty () const;
301 TyVar
clone () const;
303 TyVar
monomorphized_clone () const;
305 static TyVar
get_implicit_infer_var (Location locus
);
307 static TyVar
subst_covariant_var (TyTy::BaseType
*orig
,
308 TyTy::BaseType
*subst
);
317 TyWithLocation (BaseType
*ty
, Location locus
);
318 TyWithLocation (BaseType
*ty
);
320 BaseType
*get_ty () const { return ty
; }
321 Location
get_locus () const { return locus
; }
328 class InferType
: public BaseType
338 InferType (HirId ref
, InferTypeKind infer_kind
, Location locus
,
339 std::set
<HirId
> refs
= std::set
<HirId
> ())
340 : BaseType (ref
, ref
, TypeKind::INFER
,
341 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
342 infer_kind (infer_kind
)
345 InferType (HirId ref
, HirId ty_ref
, InferTypeKind infer_kind
, Location locus
,
346 std::set
<HirId
> refs
= std::set
<HirId
> ())
347 : BaseType (ref
, ty_ref
, TypeKind::INFER
,
348 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
349 infer_kind (infer_kind
)
352 void accept_vis (TyVisitor
&vis
) override
;
353 void accept_vis (TyConstVisitor
&vis
) const override
;
355 std::string
as_string () const override
;
357 BaseType
*unify (BaseType
*other
) override
;
359 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
361 BaseType
*clone () const final override
;
362 BaseType
*monomorphized_clone () const final override
;
364 InferTypeKind
get_infer_kind () const { return infer_kind
; }
366 std::string
get_name () const override final
{ return as_string (); }
368 bool default_type (BaseType
**type
) const;
370 bool is_concrete () const final override
{ return true; }
373 InferTypeKind infer_kind
;
376 class ErrorType
: public BaseType
379 ErrorType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
380 : BaseType (ref
, ref
, TypeKind::ERROR
,
381 {Resolver::CanonicalPath::create_empty (), Location ()}, refs
)
384 ErrorType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
385 : BaseType (ref
, ty_ref
, TypeKind::ERROR
,
386 {Resolver::CanonicalPath::create_empty (), Location ()}, refs
)
389 void accept_vis (TyVisitor
&vis
) override
;
390 void accept_vis (TyConstVisitor
&vis
) const override
;
392 bool is_unit () const override
{ return true; }
394 std::string
as_string () const override
;
396 BaseType
*unify (BaseType
*other
) override
;
397 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
399 BaseType
*clone () const final override
;
400 BaseType
*monomorphized_clone () const final override
;
402 std::string
get_name () const override final
{ return as_string (); }
404 bool is_concrete () const final override
{ return false; }
407 class SubstitutionArgumentMappings
;
408 class ParamType
: public BaseType
411 ParamType (std::string symbol
, Location locus
, HirId ref
,
412 HIR::GenericParam
¶m
,
413 std::vector
<TypeBoundPredicate
> specified_bounds
,
414 std::set
<HirId
> refs
= std::set
<HirId
> ())
415 : BaseType (ref
, ref
, TypeKind::PARAM
,
416 {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID
, symbol
),
418 specified_bounds
, refs
),
419 symbol (symbol
), param (param
)
422 ParamType (std::string symbol
, Location locus
, HirId ref
, HirId ty_ref
,
423 HIR::GenericParam
¶m
,
424 std::vector
<TypeBoundPredicate
> specified_bounds
,
425 std::set
<HirId
> refs
= std::set
<HirId
> ())
426 : BaseType (ref
, ty_ref
, TypeKind::PARAM
,
427 {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID
, symbol
),
429 specified_bounds
, refs
),
430 symbol (symbol
), param (param
)
433 void accept_vis (TyVisitor
&vis
) override
;
434 void accept_vis (TyConstVisitor
&vis
) const override
;
436 std::string
as_string () const override
;
438 BaseType
*unify (BaseType
*other
) override
;
439 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
441 BaseType
*clone () const final override
;
442 BaseType
*monomorphized_clone () const final override
;
444 std::string
get_symbol () const;
446 HIR::GenericParam
&get_generic_param () { return param
; }
448 bool can_resolve () const { return get_ref () != get_ty_ref (); }
450 BaseType
*resolve () const;
452 std::string
get_name () const override final
;
454 bool is_equal (const BaseType
&other
) const override
;
456 bool is_concrete () const override final
462 return r
->is_concrete ();
465 ParamType
*handle_substitions (SubstitutionArgumentMappings mappings
);
469 HIR::GenericParam
¶m
;
472 class StructFieldType
475 StructFieldType (HirId ref
, std::string name
, BaseType
*ty
)
476 : ref (ref
), name (name
), ty (ty
)
479 HirId
get_ref () const { return ref
; }
481 std::string
as_string () const;
483 bool is_equal (const StructFieldType
&other
) const;
485 std::string
get_name () const { return name
; }
487 BaseType
*get_field_type () const { return ty
; }
489 void set_field_type (BaseType
*fty
) { ty
= fty
; }
491 StructFieldType
*clone () const;
493 StructFieldType
*monomorphized_clone () const;
495 bool is_concrete () const { return ty
->is_concrete (); }
497 void debug () const { rust_debug ("%s", as_string ().c_str ()); }
505 class TupleType
: public BaseType
508 TupleType (HirId ref
, Location locus
,
509 std::vector
<TyVar
> fields
= std::vector
<TyVar
> (),
510 std::set
<HirId
> refs
= std::set
<HirId
> ())
511 : BaseType (ref
, ref
, TypeKind::TUPLE
,
512 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
516 TupleType (HirId ref
, HirId ty_ref
, Location locus
,
517 std::vector
<TyVar
> fields
= std::vector
<TyVar
> (),
518 std::set
<HirId
> refs
= std::set
<HirId
> ())
519 : BaseType (ref
, ty_ref
, TypeKind::TUPLE
,
520 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
524 static TupleType
*get_unit_type (HirId ref
)
526 return new TupleType (ref
, Linemap::predeclared_location ());
529 void accept_vis (TyVisitor
&vis
) override
;
530 void accept_vis (TyConstVisitor
&vis
) const override
;
532 bool is_unit () const override
{ return this->fields
.empty (); }
534 std::string
as_string () const override
;
536 BaseType
*unify (BaseType
*other
) override
;
537 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
539 bool is_equal (const BaseType
&other
) const override
;
541 size_t num_fields () const { return fields
.size (); }
543 BaseType
*get_field (size_t index
) const;
545 BaseType
*clone () const final override
;
546 BaseType
*monomorphized_clone () const final override
;
548 bool is_concrete () const override final
550 for (size_t i
= 0; i
< num_fields (); i
++)
552 if (!get_field (i
)->is_concrete ())
558 const std::vector
<TyVar
> &get_fields () const { return fields
; }
560 std::string
get_name () const override final
{ return as_string (); }
562 TupleType
*handle_substitions (SubstitutionArgumentMappings mappings
);
565 std::vector
<TyVar
> fields
;
568 class SubstitutionParamMapping
571 SubstitutionParamMapping (const HIR::TypeParam
&generic
, ParamType
*param
)
572 : generic (generic
), param (param
)
575 SubstitutionParamMapping (const SubstitutionParamMapping
&other
)
576 : generic (other
.generic
), param (other
.param
)
579 std::string
as_string () const
581 if (param
== nullptr)
584 return param
->get_name ();
587 bool fill_param_ty (SubstitutionArgumentMappings
&subst_mappings
,
590 SubstitutionParamMapping
clone () const
592 return SubstitutionParamMapping (generic
, static_cast<ParamType
*> (
596 ParamType
*get_param_ty () { return param
; }
598 const ParamType
*get_param_ty () const { return param
; }
600 const HIR::TypeParam
&get_generic_param () { return generic
; };
602 // this is used for the backend to override the HirId ref of the param to
603 // what the concrete type is for the rest of the context
604 void override_context ();
606 bool needs_substitution () const
608 return !(get_param_ty ()->is_concrete ());
611 Location
get_param_locus () const { return generic
.get_locus (); }
613 bool param_has_default_ty () const { return generic
.has_type (); }
615 BaseType
*get_default_ty () const
617 TyVar
var (generic
.get_type_mappings ().get_hirid ());
618 return var
.get_tyty ();
621 bool need_substitution () const;
624 const HIR::TypeParam
&generic
;
628 class SubstitutionArg
631 SubstitutionArg (const SubstitutionParamMapping
*param
, BaseType
*argument
)
632 : param (param
), argument (argument
)
636 // the copy constructors need removed - they are unsafe see
637 // TypeBoundPredicate
638 SubstitutionArg (const SubstitutionArg
&other
)
639 : param (other
.param
), argument (other
.argument
)
642 SubstitutionArg
&operator= (const SubstitutionArg
&other
)
645 argument
= other
.argument
;
649 BaseType
*get_tyty () { return argument
; }
651 const BaseType
*get_tyty () const { return argument
; }
653 const SubstitutionParamMapping
*get_param_mapping () const { return param
; }
655 static SubstitutionArg
error () { return SubstitutionArg (nullptr, nullptr); }
657 bool is_error () const { return param
== nullptr || argument
== nullptr; }
659 bool is_conrete () const
661 if (argument
!= nullptr)
664 if (argument
->get_kind () == TyTy::TypeKind::PARAM
)
667 return argument
->is_concrete ();
670 std::string
as_string () const
672 return param
->as_string ()
673 + (argument
!= nullptr ? ":" + argument
->as_string () : "");
677 const SubstitutionParamMapping
*param
;
681 typedef std::function
<void (const ParamType
&, const SubstitutionArg
&)>
683 class SubstitutionArgumentMappings
686 SubstitutionArgumentMappings (std::vector
<SubstitutionArg
> mappings
,
688 ParamSubstCb param_subst_cb
= nullptr,
689 bool trait_item_flag
= false)
690 : mappings (mappings
), locus (locus
), param_subst_cb (param_subst_cb
),
691 trait_item_flag (trait_item_flag
)
694 SubstitutionArgumentMappings (const SubstitutionArgumentMappings
&other
)
695 : mappings (other
.mappings
), locus (other
.locus
),
696 param_subst_cb (other
.param_subst_cb
),
697 trait_item_flag (other
.trait_item_flag
)
700 SubstitutionArgumentMappings
&
701 operator= (const SubstitutionArgumentMappings
&other
)
703 mappings
= other
.mappings
;
705 param_subst_cb
= other
.param_subst_cb
;
706 trait_item_flag
= other
.trait_item_flag
;
711 static SubstitutionArgumentMappings
error ()
713 return SubstitutionArgumentMappings ({}, Location (), nullptr, false);
716 bool is_error () const { return mappings
.size () == 0; }
718 bool get_argument_for_symbol (const ParamType
*param_to_find
,
719 SubstitutionArg
*argument
)
721 for (auto &mapping
: mappings
)
723 const SubstitutionParamMapping
*param
= mapping
.get_param_mapping ();
724 const ParamType
*p
= param
->get_param_ty ();
726 if (p
->get_symbol ().compare (param_to_find
->get_symbol ()) == 0)
735 bool get_argument_at (size_t index
, SubstitutionArg
*argument
)
737 if (index
> mappings
.size ())
740 *argument
= mappings
.at (index
);
744 // is_concrete means if the used args is non error, ie: non empty this will
745 // verify if actual real types have been put in place of are they still
747 bool is_concrete () const
749 for (auto &mapping
: mappings
)
751 if (!mapping
.is_conrete ())
757 Location
get_locus () const { return locus
; }
759 size_t size () const { return mappings
.size (); }
761 bool is_empty () const { return size () == 0; }
763 std::vector
<SubstitutionArg
> &get_mappings () { return mappings
; }
765 const std::vector
<SubstitutionArg
> &get_mappings () const { return mappings
; }
767 std::string
as_string () const
770 for (auto &mapping
: mappings
)
772 buffer
+= mapping
.as_string () + ", ";
774 return "<" + buffer
+ ">";
777 void on_param_subst (const ParamType
&p
, const SubstitutionArg
&a
) const
779 if (param_subst_cb
== nullptr)
782 param_subst_cb (p
, a
);
785 ParamSubstCb
get_subst_cb () const { return param_subst_cb
; }
787 bool trait_item_mode () const { return trait_item_flag
; }
790 std::vector
<SubstitutionArg
> mappings
;
792 ParamSubstCb param_subst_cb
;
793 bool trait_item_flag
;
796 class SubstitutionRef
799 SubstitutionRef (std::vector
<SubstitutionParamMapping
> substitutions
,
800 SubstitutionArgumentMappings arguments
)
801 : substitutions (substitutions
), used_arguments (arguments
)
804 bool has_substitutions () const { return substitutions
.size () > 0; }
806 std::string
subst_as_string () const
809 for (size_t i
= 0; i
< substitutions
.size (); i
++)
811 const SubstitutionParamMapping
&sub
= substitutions
.at (i
);
812 buffer
+= sub
.as_string ();
814 if ((i
+ 1) < substitutions
.size ())
818 return buffer
.empty () ? "" : "<" + buffer
+ ">";
821 size_t get_num_substitutions () const { return substitutions
.size (); }
823 std::vector
<SubstitutionParamMapping
> &get_substs () { return substitutions
; }
825 const std::vector
<SubstitutionParamMapping
> &get_substs () const
827 return substitutions
;
830 std::vector
<SubstitutionParamMapping
> clone_substs () const
832 std::vector
<SubstitutionParamMapping
> clone
;
834 for (auto &sub
: substitutions
)
835 clone
.push_back (sub
.clone ());
840 void override_context ()
842 for (auto &sub
: substitutions
)
844 sub
.override_context ();
848 bool needs_substitution () const
850 for (auto &sub
: substitutions
)
852 if (sub
.need_substitution ())
858 bool was_substituted () const { return !needs_substitution (); }
860 SubstitutionArgumentMappings
get_substitution_arguments () const
862 return used_arguments
;
865 // this is the count of type params that are not substituted fuly
866 size_t num_required_substitutions () const
869 for (auto &p
: substitutions
)
871 if (p
.needs_substitution ())
877 // this is the count of type params that need substituted taking into account
879 size_t min_required_substitutions () const
882 for (auto &p
: substitutions
)
884 if (p
.needs_substitution () && !p
.param_has_default_ty ())
890 // We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
891 // in the case of Foo<i32,f32>{...}
893 // the substitions we have here define X,Y but the arguments have no bindings
894 // so its a matter of ordering
895 SubstitutionArgumentMappings
896 get_mappings_from_generic_args (HIR::GenericArgs
&args
);
898 // Recursive substitutions
899 // Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
901 // we have bindings for X Y Z and need to propagate the binding Y,Z into Foo
902 // Which binds to A,B
903 SubstitutionArgumentMappings
904 adjust_mappings_for_this (SubstitutionArgumentMappings
&mappings
);
906 // Are the mappings here actually bound to this type. For example imagine the
911 // fn test(self) { ... }
914 // In this case we have a generic ADT of Foo and an impl block of a generic T
915 // on Foo for the Self type. When we it comes to path resolution we can have:
917 // Foo::<i32>::test()
919 // This means the first segment of Foo::<i32> returns the ADT Foo<i32> not the
920 // Self ADT bound to the T from the impl block. This means when it comes to
921 // the next segment of test which resolves to the function we need to check
922 // wether the arguments in the struct definition of foo can be bound here
923 // before substituting the previous segments type here. This functions acts as
924 // a guard for the solve_mappings_from_receiver_for_self to handle the case
925 // where arguments are not bound. This is important for this next case:
927 // struct Baz<A, B>(A, B);
928 // impl Baz<i32, f32> {
929 // fn test<X>(a: X) -> X {
934 // In this case Baz has been already substituted for the impl's Self to become
935 // ADT<i32, f32> so that the function test only has 1 generic argument of X.
936 // The path for this will be:
938 // Baz::test::<_>(123)
940 // So the first segment here will be Baz<_, _> to try and infer the arguments
941 // which will be taken from the impl's Self type in this case since it is
942 // already substituted and like the previous case the check to see if we need
943 // to inherit the previous segments generic arguments takes place but the
944 // generic arguments are not bound to this type as they have already been
947 // Its important to remember from the first example the FnType actually looks
950 // fn <T>test(self :Foo<T>(T))
952 // As the generic parameters are "bound" to each of the items in the impl
953 // block. So this check is about wether the arguments we have here can
954 // actually be bound to this type.
955 bool are_mappings_bound (SubstitutionArgumentMappings
&mappings
);
957 // struct Foo<A, B>(A, B);
959 // impl<T> Foo<T, f32>;
960 // -> fn test<X>(self, a: X) -> X
962 // We might invoke this via:
964 // a = Foo(123, 456f32);
965 // b = a.test::<bool>(false);
967 // we need to figure out relevant generic arguemts for self to apply to the
969 SubstitutionArgumentMappings
solve_mappings_from_receiver_for_self (
970 SubstitutionArgumentMappings
&mappings
) const;
973 SubstitutionArgumentMappings
974 solve_missing_mappings_from_this (SubstitutionRef
&ref
, SubstitutionRef
&to
);
977 BaseType
*infer_substitions (Location locus
)
979 std::vector
<SubstitutionArg
> args
;
980 std::map
<std::string
, BaseType
*> argument_mappings
;
981 for (auto &p
: get_substs ())
983 if (p
.needs_substitution ())
985 const std::string
&symbol
= p
.get_param_ty ()->get_symbol ();
986 auto it
= argument_mappings
.find (symbol
);
987 if (it
== argument_mappings
.end ())
989 TyVar infer_var
= TyVar::get_implicit_infer_var (locus
);
990 args
.push_back (SubstitutionArg (&p
, infer_var
.get_tyty ()));
991 argument_mappings
[symbol
] = infer_var
.get_tyty ();
995 args
.push_back (SubstitutionArg (&p
, it
->second
));
1001 SubstitutionArg (&p
, p
.get_param_ty ()->resolve ()));
1005 SubstitutionArgumentMappings
infer_arguments (std::move (args
), locus
);
1006 return handle_substitions (std::move (infer_arguments
));
1010 bool monomorphize ();
1013 virtual BaseType
*handle_substitions (SubstitutionArgumentMappings mappings
)
1016 SubstitutionArgumentMappings
get_used_arguments () const
1018 return used_arguments
;
1022 std::vector
<SubstitutionParamMapping
> substitutions
;
1023 SubstitutionArgumentMappings used_arguments
;
1026 class TypeBoundPredicate
: public SubstitutionRef
1029 TypeBoundPredicate (const Resolver::TraitReference
&trait_reference
,
1032 TypeBoundPredicate (DefId reference
,
1033 std::vector
<SubstitutionParamMapping
> substitutions
,
1036 TypeBoundPredicate (const TypeBoundPredicate
&other
);
1038 TypeBoundPredicate
&operator= (const TypeBoundPredicate
&other
);
1040 static TypeBoundPredicate
error ();
1042 std::string
as_string () const;
1044 std::string
as_name () const;
1046 const Resolver::TraitReference
*get () const;
1048 Location
get_locus () const { return locus
; }
1050 std::string
get_name () const;
1052 // check that this predicate is object-safe see:
1053 // https://doc.rust-lang.org/reference/items/traits.html#object-safety
1054 bool is_object_safe (bool emit_error
, Location locus
) const;
1056 void apply_generic_arguments (HIR::GenericArgs
*generic_args
);
1058 bool contains_item (const std::string
&search
) const;
1060 TypeBoundPredicateItem
1061 lookup_associated_item (const std::string
&search
) const;
1063 TypeBoundPredicateItem
1064 lookup_associated_item (const Resolver::TraitItemReference
*ref
) const;
1066 // WARNING THIS WILL ALWAYS RETURN NULLPTR
1068 handle_substitions (SubstitutionArgumentMappings mappings
) override final
;
1070 bool is_error () const;
1072 bool requires_generic_args () const;
1080 // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
1091 static std::string
variant_type_string (VariantType type
)
1106 VariantDef (HirId id
, std::string identifier
, RustIdent ident
,
1107 HIR::Expr
*discriminant
)
1108 : id (id
), identifier (identifier
), ident (ident
),
1109 discriminant (discriminant
)
1112 type
= VariantType::NUM
;
1116 VariantDef (HirId id
, std::string identifier
, RustIdent ident
,
1117 VariantType type
, HIR::Expr
*discriminant
,
1118 std::vector
<StructFieldType
*> fields
)
1119 : id (id
), identifier (identifier
), ident (ident
), type (type
),
1120 discriminant (discriminant
), fields (fields
)
1123 (type
== VariantType::NUM
&& fields
.empty ())
1124 || (type
== VariantType::TUPLE
|| type
== VariantType::STRUCT
));
1127 VariantDef (const VariantDef
&other
)
1128 : id (other
.id
), identifier (other
.identifier
), ident (other
.ident
),
1129 type (other
.type
), discriminant (other
.discriminant
),
1130 fields (other
.fields
)
1133 VariantDef
&operator= (const VariantDef
&other
)
1136 identifier
= other
.identifier
;
1138 discriminant
= other
.discriminant
;
1139 fields
= other
.fields
;
1140 ident
= other
.ident
;
1145 static VariantDef
&get_error_node ()
1147 static VariantDef node
1148 = VariantDef (UNKNOWN_HIRID
, "",
1149 {Resolver::CanonicalPath::create_empty (),
1150 Linemap::unknown_location ()},
1156 bool is_error () const { return get_id () == UNKNOWN_HIRID
; }
1158 HirId
get_id () const { return id
; }
1160 VariantType
get_variant_type () const { return type
; }
1161 bool is_data_variant () const { return type
!= VariantType::NUM
; }
1162 bool is_dataless_variant () const { return type
== VariantType::NUM
; }
1164 std::string
get_identifier () const { return identifier
; }
1166 size_t num_fields () const { return fields
.size (); }
1167 StructFieldType
*get_field_at_index (size_t index
)
1169 rust_assert (index
< fields
.size ());
1170 return fields
.at (index
);
1173 std::vector
<StructFieldType
*> &get_fields ()
1175 rust_assert (type
!= NUM
);
1179 bool lookup_field (const std::string
&lookup
, StructFieldType
**field_lookup
,
1180 size_t *index
) const
1183 for (auto &field
: fields
)
1185 if (field
->get_name ().compare (lookup
) == 0)
1187 if (index
!= nullptr)
1190 if (field_lookup
!= nullptr)
1191 *field_lookup
= field
;
1200 HIR::Expr
*get_discriminant () const
1202 rust_assert (discriminant
!= nullptr);
1203 return discriminant
;
1206 std::string
as_string () const
1208 if (type
== VariantType::NUM
)
1209 return identifier
+ " = " + discriminant
->as_string ();
1212 for (size_t i
= 0; i
< fields
.size (); ++i
)
1214 buffer
+= fields
.at (i
)->as_string ();
1215 if ((i
+ 1) < fields
.size ())
1219 if (type
== VariantType::TUPLE
)
1220 return identifier
+ " (" + buffer
+ ")";
1222 return identifier
+ " {" + buffer
+ "}";
1225 bool is_equal (const VariantDef
&other
) const
1227 if (type
!= other
.type
)
1230 if (identifier
.compare (other
.identifier
) != 0)
1233 if (discriminant
!= other
.discriminant
)
1236 if (fields
.size () != other
.fields
.size ())
1239 for (size_t i
= 0; i
< fields
.size (); i
++)
1241 if (!fields
.at (i
)->is_equal (*other
.fields
.at (i
)))
1248 VariantDef
*clone () const
1250 std::vector
<StructFieldType
*> cloned_fields
;
1251 for (auto &f
: fields
)
1252 cloned_fields
.push_back ((StructFieldType
*) f
->clone ());
1254 return new VariantDef (id
, identifier
, ident
, type
, discriminant
,
1258 VariantDef
*monomorphized_clone () const
1260 std::vector
<StructFieldType
*> cloned_fields
;
1261 for (auto &f
: fields
)
1262 cloned_fields
.push_back ((StructFieldType
*) f
->monomorphized_clone ());
1264 return new VariantDef (id
, identifier
, ident
, type
, discriminant
,
1268 const RustIdent
&get_ident () const { return ident
; }
1272 std::string identifier
;
1275 // can either be a structure or a discriminant value
1276 HIR::Expr
*discriminant
;
1277 std::vector
<StructFieldType
*> fields
;
1280 class ADTType
: public BaseType
, public SubstitutionRef
1291 // Representation options, specified via attributes e.g. #[repr(packed)]
1295 // bool is_transparent;
1298 // For align and pack: 0 = unspecified. Nonzero = byte alignment.
1299 // It is an error for both to be nonzero, this should be caught when
1300 // parsing the #[repr] attribute.
1301 unsigned char align
= 0;
1302 unsigned char pack
= 0;
1305 ADTType (HirId ref
, std::string identifier
, RustIdent ident
, ADTKind adt_kind
,
1306 std::vector
<VariantDef
*> variants
,
1307 std::vector
<SubstitutionParamMapping
> subst_refs
,
1308 SubstitutionArgumentMappings generic_arguments
1309 = SubstitutionArgumentMappings::error (),
1310 std::set
<HirId
> refs
= std::set
<HirId
> ())
1311 : BaseType (ref
, ref
, TypeKind::ADT
, ident
, refs
),
1312 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
)),
1313 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
1316 ADTType (HirId ref
, HirId ty_ref
, std::string identifier
, RustIdent ident
,
1317 ADTKind adt_kind
, std::vector
<VariantDef
*> variants
,
1318 std::vector
<SubstitutionParamMapping
> subst_refs
,
1319 SubstitutionArgumentMappings generic_arguments
1320 = SubstitutionArgumentMappings::error (),
1321 std::set
<HirId
> refs
= std::set
<HirId
> ())
1322 : BaseType (ref
, ty_ref
, TypeKind::ADT
, ident
, refs
),
1323 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
)),
1324 identifier (identifier
), variants (variants
), adt_kind (adt_kind
)
1327 ADTType (HirId ref
, HirId ty_ref
, std::string identifier
, RustIdent ident
,
1328 ADTKind adt_kind
, std::vector
<VariantDef
*> variants
,
1329 std::vector
<SubstitutionParamMapping
> subst_refs
, ReprOptions repr
,
1330 SubstitutionArgumentMappings generic_arguments
1331 = SubstitutionArgumentMappings::error (),
1332 std::set
<HirId
> refs
= std::set
<HirId
> ())
1333 : BaseType (ref
, ty_ref
, TypeKind::ADT
, ident
, refs
),
1334 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
)),
1335 identifier (identifier
), variants (variants
), adt_kind (adt_kind
),
1339 ADTKind
get_adt_kind () const { return adt_kind
; }
1340 ReprOptions
get_repr_options () const { return repr
; }
1342 bool is_struct_struct () const { return adt_kind
== STRUCT_STRUCT
; }
1343 bool is_tuple_struct () const { return adt_kind
== TUPLE_STRUCT
; }
1344 bool is_union () const { return adt_kind
== UNION
; }
1345 bool is_enum () const { return adt_kind
== ENUM
; }
1347 bool is_unit () const override
1349 if (number_of_variants () == 0)
1352 if (number_of_variants () == 1)
1353 return variants
.at (0)->num_fields () == 0;
1358 void accept_vis (TyVisitor
&vis
) override
;
1359 void accept_vis (TyConstVisitor
&vis
) const override
;
1361 std::string
as_string () const override
;
1363 BaseType
*unify (BaseType
*other
) override
;
1364 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1366 bool is_equal (const BaseType
&other
) const override
;
1368 std::string
get_identifier () const { return identifier
; }
1370 std::string
get_name () const override final
1372 return identifier
+ subst_as_string ();
1375 bool is_concrete () const override final
1377 for (auto &variant
: variants
)
1379 for (auto &field
: variant
->get_fields ())
1381 if (!field
->is_concrete ())
1388 BaseType
*clone () const final override
;
1389 BaseType
*monomorphized_clone () const final override
;
1391 bool needs_generic_substitutions () const override final
1393 return needs_substitution ();
1396 bool supports_substitutions () const override final
{ return true; }
1398 bool has_subsititions_defined () const override final
1400 return has_substitutions ();
1403 size_t number_of_variants () const { return variants
.size (); }
1405 std::vector
<VariantDef
*> &get_variants () { return variants
; }
1406 const std::vector
<VariantDef
*> &get_variants () const { return variants
; }
1408 bool lookup_variant (const std::string
&lookup
,
1409 VariantDef
**found_variant
) const
1411 for (auto &variant
: variants
)
1413 if (variant
->get_identifier ().compare (lookup
) == 0)
1415 *found_variant
= variant
;
1422 bool lookup_variant_by_id (HirId id
, VariantDef
**found_variant
,
1423 int *index
= nullptr) const
1426 for (auto &variant
: variants
)
1428 if (variant
->get_id () == id
)
1430 if (index
!= nullptr)
1433 *found_variant
= variant
;
1442 handle_substitions (SubstitutionArgumentMappings mappings
) override final
;
1445 std::string identifier
;
1446 std::vector
<VariantDef
*> variants
;
1447 ADTType::ADTKind adt_kind
;
1451 class FnType
: public BaseType
, public SubstitutionRef
1454 static const uint8_t FNTYPE_DEFAULT_FLAGS
= 0x00;
1455 static const uint8_t FNTYPE_IS_METHOD_FLAG
= 0x01;
1456 static const uint8_t FNTYPE_IS_EXTERN_FLAG
= 0x02;
1457 static const uint8_t FNTYPE_IS_VARADIC_FLAG
= 0X04;
1459 FnType (HirId ref
, DefId id
, std::string identifier
, RustIdent ident
,
1460 uint8_t flags
, ABI abi
,
1461 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
,
1462 BaseType
*type
, std::vector
<SubstitutionParamMapping
> subst_refs
,
1463 std::set
<HirId
> refs
= std::set
<HirId
> ())
1464 : BaseType (ref
, ref
, TypeKind::FNDEF
, ident
, refs
),
1465 SubstitutionRef (std::move (subst_refs
),
1466 SubstitutionArgumentMappings::error ()),
1467 params (std::move (params
)), type (type
), flags (flags
),
1468 identifier (identifier
), id (id
), abi (abi
)
1470 LocalDefId local_def_id
= id
.localDefId
;
1471 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1474 FnType (HirId ref
, HirId ty_ref
, DefId id
, std::string identifier
,
1475 RustIdent ident
, uint8_t flags
, ABI abi
,
1476 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
,
1477 BaseType
*type
, std::vector
<SubstitutionParamMapping
> subst_refs
,
1478 std::set
<HirId
> refs
= std::set
<HirId
> ())
1479 : BaseType (ref
, ty_ref
, TypeKind::FNDEF
, ident
, refs
),
1480 SubstitutionRef (std::move (subst_refs
),
1481 SubstitutionArgumentMappings::error ()),
1482 params (params
), type (type
), flags (flags
), identifier (identifier
),
1485 LocalDefId local_def_id
= id
.localDefId
;
1486 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1489 void accept_vis (TyVisitor
&vis
) override
;
1490 void accept_vis (TyConstVisitor
&vis
) const override
;
1492 std::string
as_string () const override
;
1494 std::string
get_name () const override final
{ return as_string (); }
1496 std::string
get_identifier () const { return identifier
; }
1498 BaseType
*unify (BaseType
*other
) override
;
1499 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1501 bool is_equal (const BaseType
&other
) const override
;
1503 size_t num_params () const { return params
.size (); }
1505 bool is_method () const
1507 if (num_params () == 0)
1510 return (flags
& FNTYPE_IS_METHOD_FLAG
) != 0;
1513 bool is_extern () const { return (flags
& FNTYPE_IS_EXTERN_FLAG
) != 0; }
1515 bool is_varadic () const { return (flags
& FNTYPE_IS_VARADIC_FLAG
) != 0; }
1517 DefId
get_id () const { return id
; }
1519 // get the Self type for the method
1520 BaseType
*get_self_type () const
1522 rust_assert (is_method ());
1523 return param_at (0).second
;
1526 bool is_concrete () const override final
1528 for (const auto ¶m
: params
)
1530 const BaseType
*p
= param
.second
;
1531 if (!p
->is_concrete ())
1534 return get_return_type ()->is_concrete ();
1537 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params ()
1542 const std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> &get_params () const
1547 std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
)
1549 return params
.at (idx
);
1552 const std::pair
<HIR::Pattern
*, BaseType
*> ¶m_at (size_t idx
) const
1554 return params
.at (idx
);
1557 BaseType
*get_return_type () const { return type
; }
1559 BaseType
*clone () const final override
;
1560 BaseType
*monomorphized_clone () const final override
;
1562 bool needs_generic_substitutions () const override final
1564 return needs_substitution ();
1567 bool supports_substitutions () const override final
{ return true; }
1569 bool has_subsititions_defined () const override final
1571 return has_substitutions ();
1575 handle_substitions (SubstitutionArgumentMappings mappings
) override final
;
1577 ABI
get_abi () const { return abi
; }
1580 std::vector
<std::pair
<HIR::Pattern
*, BaseType
*>> params
;
1583 std::string identifier
;
1588 class FnPtr
: public BaseType
1591 FnPtr (HirId ref
, Location locus
, std::vector
<TyVar
> params
,
1592 TyVar result_type
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1593 : BaseType (ref
, ref
, TypeKind::FNPTR
,
1594 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1595 params (std::move (params
)), result_type (result_type
)
1598 FnPtr (HirId ref
, HirId ty_ref
, Location locus
, std::vector
<TyVar
> params
,
1599 TyVar result_type
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1600 : BaseType (ref
, ty_ref
, TypeKind::FNPTR
,
1601 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1602 params (params
), result_type (result_type
)
1605 std::string
get_name () const override final
{ return as_string (); }
1607 BaseType
*get_return_type () const { return result_type
.get_tyty (); }
1609 size_t num_params () const { return params
.size (); }
1611 BaseType
*param_at (size_t idx
) const { return params
.at (idx
).get_tyty (); }
1613 void accept_vis (TyVisitor
&vis
) override
;
1614 void accept_vis (TyConstVisitor
&vis
) const override
;
1616 std::string
as_string () const override
;
1618 BaseType
*unify (BaseType
*other
) override
;
1619 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1621 bool is_equal (const BaseType
&other
) const override
;
1623 BaseType
*clone () const final override
;
1624 BaseType
*monomorphized_clone () const final override
;
1626 void iterate_params (std::function
<bool (BaseType
*)> cb
) const
1628 for (auto &p
: params
)
1630 if (!cb (p
.get_tyty ()))
1635 std::vector
<TyVar
> &get_params () { return params
; }
1636 const std::vector
<TyVar
> &get_params () const { return params
; }
1638 bool is_concrete () const override final
1640 for (auto &p
: params
)
1642 if (!p
.get_tyty ()->is_concrete ())
1645 return result_type
.get_tyty ()->is_concrete ();
1649 std::vector
<TyVar
> params
;
1653 class ClosureType
: public BaseType
, public SubstitutionRef
1656 ClosureType (HirId ref
, DefId id
, RustIdent ident
,
1657 std::vector
<TyVar
> parameter_types
, TyVar result_type
,
1658 std::vector
<SubstitutionParamMapping
> subst_refs
,
1659 std::set
<HirId
> refs
= std::set
<HirId
> ())
1660 : BaseType (ref
, ref
, TypeKind::CLOSURE
, ident
, refs
),
1661 SubstitutionRef (std::move (subst_refs
),
1662 SubstitutionArgumentMappings::error ()),
1663 parameter_types (std::move (parameter_types
)),
1664 result_type (std::move (result_type
)), id (id
)
1666 LocalDefId local_def_id
= id
.localDefId
;
1667 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1670 ClosureType (HirId ref
, HirId ty_ref
, RustIdent ident
, DefId id
,
1671 std::vector
<TyVar
> parameter_types
, TyVar result_type
,
1672 std::vector
<SubstitutionParamMapping
> subst_refs
,
1673 std::set
<HirId
> refs
= std::set
<HirId
> ())
1674 : BaseType (ref
, ty_ref
, TypeKind::CLOSURE
, ident
, refs
),
1675 SubstitutionRef (std::move (subst_refs
),
1676 SubstitutionArgumentMappings::error ()),
1677 parameter_types (std::move (parameter_types
)),
1678 result_type (std::move (result_type
)), id (id
)
1680 LocalDefId local_def_id
= id
.localDefId
;
1681 rust_assert (local_def_id
!= UNKNOWN_LOCAL_DEFID
);
1684 void accept_vis (TyVisitor
&vis
) override
;
1685 void accept_vis (TyConstVisitor
&vis
) const override
;
1687 std::string
as_string () const override
;
1688 std::string
get_name () const override final
{ return as_string (); }
1690 BaseType
*unify (BaseType
*other
) override
;
1691 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1693 bool is_equal (const BaseType
&other
) const override
;
1695 BaseType
*clone () const final override
;
1696 BaseType
*monomorphized_clone () const final override
;
1698 bool is_concrete () const override final
1700 for (auto ¶m
: parameter_types
)
1702 auto p
= param
.get_tyty ();
1703 if (!p
->is_concrete ())
1706 return result_type
.get_tyty ()->is_concrete ();
1709 bool needs_generic_substitutions () const override final
1711 return needs_substitution ();
1714 bool supports_substitutions () const override final
{ return true; }
1716 bool has_subsititions_defined () const override final
1718 return has_substitutions ();
1722 handle_substitions (SubstitutionArgumentMappings mappings
) override final
;
1725 std::vector
<TyVar
> parameter_types
;
1730 class ArrayType
: public BaseType
1733 ArrayType (HirId ref
, Location locus
, HIR::Expr
&capacity_expr
, TyVar base
,
1734 std::set
<HirId
> refs
= std::set
<HirId
> ())
1735 : BaseType (ref
, ref
, TypeKind::ARRAY
,
1736 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1737 element_type (base
), capacity_expr (capacity_expr
)
1740 ArrayType (HirId ref
, HirId ty_ref
, Location locus
, HIR::Expr
&capacity_expr
,
1741 TyVar base
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1742 : BaseType (ref
, ty_ref
, TypeKind::ARRAY
,
1743 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1744 element_type (base
), capacity_expr (capacity_expr
)
1747 void accept_vis (TyVisitor
&vis
) override
;
1748 void accept_vis (TyConstVisitor
&vis
) const override
;
1750 std::string
as_string () const override
;
1752 std::string
get_name () const override final
{ return as_string (); }
1754 BaseType
*unify (BaseType
*other
) override
;
1755 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1757 bool is_equal (const BaseType
&other
) const override
;
1759 BaseType
*get_element_type () const;
1761 BaseType
*clone () const final override
;
1762 BaseType
*monomorphized_clone () const final override
;
1764 bool is_concrete () const final override
1766 return get_element_type ()->is_concrete ();
1769 HIR::Expr
&get_capacity_expr () const { return capacity_expr
; }
1771 ArrayType
*handle_substitions (SubstitutionArgumentMappings mappings
);
1775 HIR::Expr
&capacity_expr
;
1778 class SliceType
: public BaseType
1781 SliceType (HirId ref
, Location locus
, TyVar base
,
1782 std::set
<HirId
> refs
= std::set
<HirId
> ())
1783 : BaseType (ref
, ref
, TypeKind::SLICE
,
1784 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1788 SliceType (HirId ref
, HirId ty_ref
, Location locus
, TyVar base
,
1789 std::set
<HirId
> refs
= std::set
<HirId
> ())
1790 : BaseType (ref
, ty_ref
, TypeKind::SLICE
,
1791 {Resolver::CanonicalPath::create_empty (), locus
}, refs
),
1795 void accept_vis (TyVisitor
&vis
) override
;
1796 void accept_vis (TyConstVisitor
&vis
) const override
;
1798 std::string
as_string () const override
;
1800 std::string
get_name () const override final
{ return as_string (); }
1802 BaseType
*unify (BaseType
*other
) override
;
1803 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1805 bool is_equal (const BaseType
&other
) const override
;
1807 BaseType
*get_element_type () const;
1809 BaseType
*clone () const final override
;
1810 BaseType
*monomorphized_clone () const final override
;
1812 bool is_concrete () const final override
1814 return get_element_type ()->is_concrete ();
1817 SliceType
*handle_substitions (SubstitutionArgumentMappings mappings
);
1823 class BoolType
: public BaseType
1826 BoolType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1827 : BaseType (ref
, ref
, TypeKind::BOOL
,
1828 {Resolver::CanonicalPath::create_empty (),
1829 Linemap::predeclared_location ()},
1833 BoolType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1834 : BaseType (ref
, ty_ref
, TypeKind::BOOL
,
1835 {Resolver::CanonicalPath::create_empty (),
1836 Linemap::predeclared_location ()},
1840 void accept_vis (TyVisitor
&vis
) override
;
1841 void accept_vis (TyConstVisitor
&vis
) const override
;
1843 std::string
as_string () const override
;
1845 std::string
get_name () const override final
{ return as_string (); }
1847 BaseType
*unify (BaseType
*other
) override
;
1848 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1850 BaseType
*clone () const final override
;
1851 BaseType
*monomorphized_clone () const final override
;
1852 bool is_concrete () const override final
{ return true; }
1855 class IntType
: public BaseType
1867 IntType (HirId ref
, IntKind kind
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1868 : BaseType (ref
, ref
, TypeKind::INT
,
1869 {Resolver::CanonicalPath::create_empty (),
1870 Linemap::predeclared_location ()},
1875 IntType (HirId ref
, HirId ty_ref
, IntKind kind
,
1876 std::set
<HirId
> refs
= std::set
<HirId
> ())
1877 : BaseType (ref
, ty_ref
, TypeKind::INT
,
1878 {Resolver::CanonicalPath::create_empty (),
1879 Linemap::predeclared_location ()},
1884 void accept_vis (TyVisitor
&vis
) override
;
1885 void accept_vis (TyConstVisitor
&vis
) const override
;
1887 std::string
as_string () const override
;
1889 std::string
get_name () const override final
{ return as_string (); }
1891 BaseType
*unify (BaseType
*other
) override
;
1892 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1894 IntKind
get_int_kind () const { return int_kind
; }
1896 BaseType
*clone () const final override
;
1897 BaseType
*monomorphized_clone () const final override
;
1899 bool is_equal (const BaseType
&other
) const override
;
1900 bool is_concrete () const override final
{ return true; }
1906 class UintType
: public BaseType
1918 UintType (HirId ref
, UintKind kind
, std::set
<HirId
> refs
= std::set
<HirId
> ())
1919 : BaseType (ref
, ref
, TypeKind::UINT
,
1920 {Resolver::CanonicalPath::create_empty (),
1921 Linemap::predeclared_location ()},
1926 UintType (HirId ref
, HirId ty_ref
, UintKind kind
,
1927 std::set
<HirId
> refs
= std::set
<HirId
> ())
1928 : BaseType (ref
, ty_ref
, TypeKind::UINT
,
1929 {Resolver::CanonicalPath::create_empty (),
1930 Linemap::predeclared_location ()},
1935 void accept_vis (TyVisitor
&vis
) override
;
1936 void accept_vis (TyConstVisitor
&vis
) const override
;
1938 std::string
as_string () const override
;
1940 std::string
get_name () const override final
{ return as_string (); }
1942 BaseType
*unify (BaseType
*other
) override
;
1943 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1945 UintKind
get_uint_kind () const { return uint_kind
; }
1947 BaseType
*clone () const final override
;
1948 BaseType
*monomorphized_clone () const final override
;
1950 bool is_equal (const BaseType
&other
) const override
;
1951 bool is_concrete () const override final
{ return true; }
1957 class FloatType
: public BaseType
1966 FloatType (HirId ref
, FloatKind kind
,
1967 std::set
<HirId
> refs
= std::set
<HirId
> ())
1968 : BaseType (ref
, ref
, TypeKind::FLOAT
,
1969 {Resolver::CanonicalPath::create_empty (),
1970 Linemap::predeclared_location ()},
1975 FloatType (HirId ref
, HirId ty_ref
, FloatKind kind
,
1976 std::set
<HirId
> refs
= std::set
<HirId
> ())
1977 : BaseType (ref
, ty_ref
, TypeKind::FLOAT
,
1978 {Resolver::CanonicalPath::create_empty (),
1979 Linemap::predeclared_location ()},
1984 void accept_vis (TyVisitor
&vis
) override
;
1985 void accept_vis (TyConstVisitor
&vis
) const override
;
1987 std::string
as_string () const override
;
1989 std::string
get_name () const override final
{ return as_string (); }
1991 BaseType
*unify (BaseType
*other
) override
;
1992 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
1994 FloatKind
get_float_kind () const { return float_kind
; }
1996 BaseType
*clone () const final override
;
1997 BaseType
*monomorphized_clone () const final override
;
1999 bool is_equal (const BaseType
&other
) const override
;
2000 bool is_concrete () const override final
{ return true; }
2003 FloatKind float_kind
;
2006 class USizeType
: public BaseType
2009 USizeType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2010 : BaseType (ref
, ref
, TypeKind::USIZE
,
2011 {Resolver::CanonicalPath::create_empty (),
2012 Linemap::predeclared_location ()},
2016 USizeType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2017 : BaseType (ref
, ty_ref
, TypeKind::USIZE
,
2018 {Resolver::CanonicalPath::create_empty (),
2019 Linemap::predeclared_location ()},
2023 void accept_vis (TyVisitor
&vis
) override
;
2024 void accept_vis (TyConstVisitor
&vis
) const override
;
2026 std::string
as_string () const override
;
2028 std::string
get_name () const override final
{ return as_string (); }
2030 BaseType
*unify (BaseType
*other
) override
;
2031 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2033 BaseType
*clone () const final override
;
2034 BaseType
*monomorphized_clone () const final override
;
2035 bool is_concrete () const override final
{ return true; }
2038 class ISizeType
: public BaseType
2041 ISizeType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2042 : BaseType (ref
, ref
, TypeKind::ISIZE
,
2043 {Resolver::CanonicalPath::create_empty (),
2044 Linemap::predeclared_location ()},
2048 ISizeType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2049 : BaseType (ref
, ty_ref
, TypeKind::ISIZE
,
2050 {Resolver::CanonicalPath::create_empty (),
2051 Linemap::predeclared_location ()},
2055 void accept_vis (TyVisitor
&vis
) override
;
2056 void accept_vis (TyConstVisitor
&vis
) const override
;
2058 std::string
as_string () const override
;
2060 std::string
get_name () const override final
{ return as_string (); }
2062 BaseType
*unify (BaseType
*other
) override
;
2063 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2065 BaseType
*clone () const final override
;
2066 BaseType
*monomorphized_clone () const final override
;
2067 bool is_concrete () const override final
{ return true; }
2070 class CharType
: public BaseType
2073 CharType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2074 : BaseType (ref
, ref
, TypeKind::CHAR
,
2075 {Resolver::CanonicalPath::create_empty (),
2076 Linemap::predeclared_location ()},
2080 CharType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2081 : BaseType (ref
, ty_ref
, TypeKind::CHAR
,
2082 {Resolver::CanonicalPath::create_empty (),
2083 Linemap::predeclared_location ()},
2087 void accept_vis (TyVisitor
&vis
) override
;
2088 void accept_vis (TyConstVisitor
&vis
) const override
;
2090 std::string
as_string () const override
;
2092 std::string
get_name () const override final
{ return as_string (); }
2094 BaseType
*unify (BaseType
*other
) override
;
2095 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2097 BaseType
*clone () const final override
;
2098 BaseType
*monomorphized_clone () const final override
;
2099 bool is_concrete () const override final
{ return true; }
2102 class StrType
: public BaseType
2105 StrType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2106 : BaseType (ref
, ref
, TypeKind::STR
,
2107 {Resolver::CanonicalPath::create_empty (),
2108 Linemap::predeclared_location ()},
2112 StrType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2113 : BaseType (ref
, ty_ref
, TypeKind::STR
,
2114 {Resolver::CanonicalPath::create_empty (),
2115 Linemap::predeclared_location ()},
2119 std::string
get_name () const override final
{ return as_string (); }
2121 void accept_vis (TyVisitor
&vis
) override
;
2122 void accept_vis (TyConstVisitor
&vis
) const override
;
2124 std::string
as_string () const override
;
2126 BaseType
*unify (BaseType
*other
) override
;
2127 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2129 bool is_equal (const BaseType
&other
) const override
;
2131 BaseType
*clone () const final override
;
2132 BaseType
*monomorphized_clone () const final override
;
2133 bool is_concrete () const override final
{ return true; }
2136 class ReferenceType
: public BaseType
2139 ReferenceType (HirId ref
, TyVar base
, Mutability mut
,
2140 std::set
<HirId
> refs
= std::set
<HirId
> ())
2141 : BaseType (ref
, ref
, TypeKind::REF
,
2142 {Resolver::CanonicalPath::create_empty (),
2143 Linemap::predeclared_location ()},
2145 base (base
), mut (mut
)
2148 ReferenceType (HirId ref
, HirId ty_ref
, TyVar base
, Mutability mut
,
2149 std::set
<HirId
> refs
= std::set
<HirId
> ())
2150 : BaseType (ref
, ty_ref
, TypeKind::REF
,
2151 {Resolver::CanonicalPath::create_empty (),
2152 Linemap::predeclared_location ()},
2154 base (base
), mut (mut
)
2157 BaseType
*get_base () const;
2159 void accept_vis (TyVisitor
&vis
) override
;
2160 void accept_vis (TyConstVisitor
&vis
) const override
;
2162 std::string
as_string () const override
;
2164 std::string
get_name () const override final
2166 return "&" + get_base ()->get_name ();
2169 BaseType
*unify (BaseType
*other
) override
;
2170 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2172 bool is_equal (const BaseType
&other
) const override
;
2174 BaseType
*clone () const final override
;
2175 BaseType
*monomorphized_clone () const final override
;
2177 bool is_concrete () const override final
2179 return get_base ()->is_concrete ();
2182 ReferenceType
*handle_substitions (SubstitutionArgumentMappings mappings
);
2184 Mutability
mutability () const { return mut
; }
2186 bool is_mutable () const { return mut
== Mutability::Mut
; }
2188 bool is_dyn_object () const
2190 return is_dyn_slice_type () || is_dyn_str_type ();
2193 bool is_dyn_slice_type (const TyTy::SliceType
**slice
= nullptr) const
2195 const TyTy::BaseType
*element
= get_base ()->destructure ();
2196 if (element
->get_kind () != TyTy::TypeKind::SLICE
)
2198 if (slice
== nullptr)
2201 *slice
= static_cast<const TyTy::SliceType
*> (element
);
2205 bool is_dyn_str_type (const TyTy::StrType
**str
= nullptr) const
2207 const TyTy::BaseType
*element
= get_base ()->destructure ();
2208 if (element
->get_kind () != TyTy::TypeKind::STR
)
2213 *str
= static_cast<const TyTy::StrType
*> (element
);
2222 class PointerType
: public BaseType
2225 PointerType (HirId ref
, TyVar base
, Mutability mut
,
2226 std::set
<HirId
> refs
= std::set
<HirId
> ())
2227 : BaseType (ref
, ref
, TypeKind::POINTER
,
2228 {Resolver::CanonicalPath::create_empty (),
2229 Linemap::predeclared_location ()},
2231 base (base
), mut (mut
)
2234 PointerType (HirId ref
, HirId ty_ref
, TyVar base
, Mutability mut
,
2235 std::set
<HirId
> refs
= std::set
<HirId
> ())
2236 : BaseType (ref
, ty_ref
, TypeKind::POINTER
,
2237 {Resolver::CanonicalPath::create_empty (),
2238 Linemap::predeclared_location ()},
2240 base (base
), mut (mut
)
2243 BaseType
*get_base () const;
2245 void accept_vis (TyVisitor
&vis
) override
;
2246 void accept_vis (TyConstVisitor
&vis
) const override
;
2248 std::string
as_string () const override
;
2250 std::string
get_name () const override final
2252 return "*" + get_base ()->get_name ();
2255 BaseType
*unify (BaseType
*other
) override
;
2256 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2258 bool is_equal (const BaseType
&other
) const override
;
2260 BaseType
*clone () const final override
;
2261 BaseType
*monomorphized_clone () const final override
;
2263 bool is_concrete () const override final
2265 return get_base ()->is_concrete ();
2268 PointerType
*handle_substitions (SubstitutionArgumentMappings mappings
);
2270 Mutability
mutability () const { return mut
; }
2272 bool is_mutable () const { return mut
== Mutability::Mut
; }
2274 bool is_const () const { return mut
== Mutability::Imm
; }
2276 bool is_dyn_object () const
2278 return is_dyn_slice_type () || is_dyn_str_type ();
2281 bool is_dyn_slice_type (const TyTy::SliceType
**slice
= nullptr) const
2283 const TyTy::BaseType
*element
= get_base ()->destructure ();
2284 if (element
->get_kind () != TyTy::TypeKind::SLICE
)
2286 if (slice
== nullptr)
2289 *slice
= static_cast<const TyTy::SliceType
*> (element
);
2293 bool is_dyn_str_type (const TyTy::StrType
**str
= nullptr) const
2295 const TyTy::BaseType
*element
= get_base ()->destructure ();
2296 if (element
->get_kind () != TyTy::TypeKind::STR
)
2301 *str
= static_cast<const TyTy::StrType
*> (element
);
2310 // https://doc.rust-lang.org/std/primitive.never.html
2312 // Since the `!` type is really complicated and it is even still unstable
2313 // in rustc, only fairly limited support for this type is introduced here.
2314 // Unification between `!` and ANY other type (including `<T?>`) is simply
2315 // not allowed. If it is needed, it should be handled manually. For example,
2316 // unifying `!` with other types is very necessary when resolving types of
2317 // `if/else` expressions.
2319 // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
2320 class NeverType
: public BaseType
2323 NeverType (HirId ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2324 : BaseType (ref
, ref
, TypeKind::NEVER
,
2325 {Resolver::CanonicalPath::create_empty (),
2326 Linemap::predeclared_location ()},
2330 NeverType (HirId ref
, HirId ty_ref
, std::set
<HirId
> refs
= std::set
<HirId
> ())
2331 : BaseType (ref
, ty_ref
, TypeKind::NEVER
,
2332 {Resolver::CanonicalPath::create_empty (),
2333 Linemap::predeclared_location ()},
2337 void accept_vis (TyVisitor
&vis
) override
;
2338 void accept_vis (TyConstVisitor
&vis
) const override
;
2340 std::string
as_string () const override
;
2342 BaseType
*unify (BaseType
*other
) override
;
2343 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2345 BaseType
*clone () const final override
;
2346 BaseType
*monomorphized_clone () const final override
;
2348 std::string
get_name () const override final
{ return as_string (); }
2350 bool is_unit () const override
{ return true; }
2351 bool is_concrete () const override final
{ return true; }
2354 // used at the type in associated types in traits
2355 // see: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
2356 class PlaceholderType
: public BaseType
2359 PlaceholderType (std::string symbol
, HirId ref
,
2360 std::set
<HirId
> refs
= std::set
<HirId
> ())
2361 : BaseType (ref
, ref
, TypeKind::PLACEHOLDER
,
2362 {Resolver::CanonicalPath::create_empty (),
2363 Linemap::predeclared_location ()},
2368 PlaceholderType (std::string symbol
, HirId ref
, HirId ty_ref
,
2369 std::set
<HirId
> refs
= std::set
<HirId
> ())
2370 : BaseType (ref
, ty_ref
, TypeKind::PLACEHOLDER
,
2371 {Resolver::CanonicalPath::create_empty (),
2372 Linemap::predeclared_location ()},
2377 void accept_vis (TyVisitor
&vis
) override
;
2378 void accept_vis (TyConstVisitor
&vis
) const override
;
2380 std::string
as_string () const override
;
2382 BaseType
*unify (BaseType
*other
) override
;
2383 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2385 BaseType
*clone () const final override
;
2386 BaseType
*monomorphized_clone () const final override
;
2388 std::string
get_name () const override final
{ return as_string (); }
2390 bool is_unit () const override
2392 rust_assert (can_resolve ());
2393 return resolve ()->is_unit ();
2396 std::string
get_symbol () const { return symbol
; }
2398 void set_associated_type (HirId ref
);
2400 void clear_associated_type ();
2402 bool can_resolve () const;
2404 BaseType
*resolve () const;
2406 bool is_equal (const BaseType
&other
) const override
;
2408 bool is_concrete () const override final
2410 if (!can_resolve ())
2413 return resolve ()->is_concrete ();
2420 class ProjectionType
: public BaseType
, public SubstitutionRef
2423 ProjectionType (HirId ref
, BaseType
*base
,
2424 const Resolver::TraitReference
*trait
, DefId item
,
2425 std::vector
<SubstitutionParamMapping
> subst_refs
,
2426 SubstitutionArgumentMappings generic_arguments
2427 = SubstitutionArgumentMappings::error (),
2428 std::set
<HirId
> refs
= std::set
<HirId
> ())
2429 : BaseType (ref
, ref
, TypeKind::PROJECTION
,
2430 {Resolver::CanonicalPath::create_empty (),
2431 Linemap::predeclared_location ()},
2433 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
)),
2434 base (base
), trait (trait
), item (item
)
2437 ProjectionType (HirId ref
, HirId ty_ref
, BaseType
*base
,
2438 const Resolver::TraitReference
*trait
, DefId item
,
2439 std::vector
<SubstitutionParamMapping
> subst_refs
,
2440 SubstitutionArgumentMappings generic_arguments
2441 = SubstitutionArgumentMappings::error (),
2442 std::set
<HirId
> refs
= std::set
<HirId
> ())
2443 : BaseType (ref
, ty_ref
, TypeKind::PROJECTION
,
2444 {Resolver::CanonicalPath::create_empty (),
2445 Linemap::predeclared_location ()},
2447 SubstitutionRef (std::move (subst_refs
), std::move (generic_arguments
)),
2448 base (base
), trait (trait
), item (item
)
2451 void accept_vis (TyVisitor
&vis
) override
;
2452 void accept_vis (TyConstVisitor
&vis
) const override
;
2454 std::string
as_string () const override
;
2456 BaseType
*unify (BaseType
*other
) override
;
2457 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2459 BaseType
*clone () const final override
;
2460 BaseType
*monomorphized_clone () const final override
;
2462 std::string
get_name () const override final
{ return as_string (); }
2464 bool is_unit () const override
{ return false; }
2466 bool needs_generic_substitutions () const override final
2468 return needs_substitution ();
2471 bool supports_substitutions () const override final
{ return true; }
2473 bool has_subsititions_defined () const override final
2475 return has_substitutions ();
2478 const BaseType
*get () const { return base
; }
2479 BaseType
*get () { return base
; }
2481 bool is_concrete () const override final
{ return base
->is_concrete (); }
2484 handle_substitions (SubstitutionArgumentMappings mappings
) override final
;
2488 const Resolver::TraitReference
*trait
;
2492 class DynamicObjectType
: public BaseType
2495 DynamicObjectType (HirId ref
, RustIdent ident
,
2496 std::vector
<TypeBoundPredicate
> specified_bounds
,
2497 std::set
<HirId
> refs
= std::set
<HirId
> ())
2498 : BaseType (ref
, ref
, TypeKind::DYNAMIC
, ident
, specified_bounds
, refs
)
2501 DynamicObjectType (HirId ref
, HirId ty_ref
, RustIdent ident
,
2502 std::vector
<TypeBoundPredicate
> specified_bounds
,
2503 std::set
<HirId
> refs
= std::set
<HirId
> ())
2504 : BaseType (ref
, ty_ref
, TypeKind::DYNAMIC
, ident
, specified_bounds
, refs
)
2507 void accept_vis (TyVisitor
&vis
) override
;
2508 void accept_vis (TyConstVisitor
&vis
) const override
;
2510 std::string
as_string () const override
;
2512 BaseType
*unify (BaseType
*other
) override
;
2513 bool can_eq (const BaseType
*other
, bool emit_errors
) const override final
;
2515 bool is_equal (const BaseType
&other
) const override
;
2517 BaseType
*clone () const final override
;
2518 BaseType
*monomorphized_clone () const final override
;
2520 std::string
get_name () const override final
;
2522 bool is_concrete () const override final
{ return true; }
2524 // this returns a flat list of items including super trait bounds
2526 std::pair
<const Resolver::TraitItemReference
*, const TypeBoundPredicate
*>>
2527 get_object_items () const;