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/>.
19 #ifndef RUST_TYTY_RULES
20 #define RUST_TYTY_RULES
22 #include "rust-diagnostics.h"
23 #include "rust-tyty.h"
24 #include "rust-tyty-visitor.h"
25 #include "rust-hir-map.h"
26 #include "rust-hir-type-check.h"
31 /* Rules specify how to unify two Ty. For example, the result of unifying the
32 two tuples (u64, A) and (B, i64) would be (u64, i64).
34 Performing a unification requires a double dispatch. To illustrate, suppose
35 we want to unify `ty1` and `ty2`. Here's what it looks like:
36 1. The caller calls `ty1.unify(ty2)`. This is the first dispatch.
37 2. `ty1` creates a rule specific to its type(e.g. TupleRules).
38 3. The rule calls `ty2.accept_vis(rule)`. This is the second dispatch.
39 4. `ty2` calls `rule.visit(*this)`, which will method-overload to the
40 correct implementation at compile time.
42 The nice thing about Rules is that they seperate unification logic from the
43 representation of Ty. To support unifying a new Ty, implement its
44 `accept_vis` and `unify` method to pass the unification request to Rules.
45 Then, create a new `XXXRules` class and implement one `visit` method for
46 every Ty it can unify with. */
47 class BaseRules
: public TyVisitor
50 virtual ~BaseRules () {}
52 /* Unify two ty. Returns a pointer to the newly-created unified ty, or nullptr
53 if the two types cannot be unified. The caller is responsible for releasing
54 the memory of the returned ty.
56 This method is meant to be used internally by Ty. If you're trying to unify
57 two ty, you can simply call `unify` on ty themselves. */
58 virtual BaseType
*unify (BaseType
*other
)
60 if (other
->get_kind () == TypeKind::PARAM
)
62 ParamType
*p
= static_cast<ParamType
*> (other
);
63 other
= p
->resolve ();
65 else if (other
->get_kind () == TypeKind::PLACEHOLDER
)
67 PlaceholderType
*p
= static_cast<PlaceholderType
*> (other
);
68 if (p
->can_resolve ())
70 other
= p
->resolve ();
71 return get_base ()->unify (other
);
74 else if (other
->get_kind () == TypeKind::PROJECTION
)
76 ProjectionType
*p
= static_cast<ProjectionType
*> (other
);
78 return get_base ()->unify (other
);
81 other
->accept_vis (*this);
82 if (resolved
->get_kind () == TyTy::TypeKind::ERROR
)
85 resolved
->append_reference (get_base ()->get_ref ());
86 resolved
->append_reference (other
->get_ref ());
87 for (auto ref
: get_base ()->get_combined_refs ())
88 resolved
->append_reference (ref
);
89 for (auto ref
: other
->get_combined_refs ())
90 resolved
->append_reference (ref
);
92 other
->append_reference (resolved
->get_ref ());
93 other
->append_reference (get_base ()->get_ref ());
94 get_base ()->append_reference (resolved
->get_ref ());
95 get_base ()->append_reference (other
->get_ref ());
97 bool result_resolved
= resolved
->get_kind () != TyTy::TypeKind::INFER
;
98 bool result_is_infer_var
= resolved
->get_kind () == TyTy::TypeKind::INFER
;
99 bool results_is_non_general_infer_var
100 = (result_is_infer_var
101 && (static_cast<InferType
*> (resolved
))->get_infer_kind ()
102 != TyTy::InferType::GENERAL
);
103 if (result_resolved
|| results_is_non_general_infer_var
)
105 for (auto &ref
: resolved
->get_combined_refs ())
107 TyTy::BaseType
*ref_tyty
= nullptr;
108 bool ok
= context
->lookup_type (ref
, &ref_tyty
);
112 // if any of the types are inference variables lets fix them
113 if (ref_tyty
->get_kind () == TyTy::TypeKind::INFER
)
115 context
->insert_type (
116 Analysis::NodeMapping (mappings
->get_current_crate (),
118 UNKNOWN_LOCAL_DEFID
),
126 virtual void visit (TupleType
&type
) override
{}
128 virtual void visit (ADTType
&type
) override
{}
130 virtual void visit (InferType
&type
) override
{}
132 virtual void visit (FnType
&type
) override
{}
134 virtual void visit (FnPtr
&type
) override
{}
136 virtual void visit (ArrayType
&type
) override
{}
138 virtual void visit (SliceType
&type
) override
{}
140 virtual void visit (BoolType
&type
) override
{}
142 virtual void visit (IntType
&type
) override
{}
144 virtual void visit (UintType
&type
) override
{}
146 virtual void visit (USizeType
&type
) override
{}
148 virtual void visit (ISizeType
&type
) override
{}
150 virtual void visit (FloatType
&type
) override
{}
152 virtual void visit (ErrorType
&type
) override
{}
154 virtual void visit (CharType
&type
) override
{}
156 virtual void visit (ReferenceType
&type
) override
{}
158 virtual void visit (PointerType
&type
) override
{}
160 virtual void visit (ParamType
&type
) override
{}
162 virtual void visit (StrType
&type
) override
{}
164 virtual void visit (NeverType
&type
) override
{}
166 virtual void visit (PlaceholderType
&type
) override
{}
168 virtual void visit (ProjectionType
&type
) override
{}
170 virtual void visit (DynamicObjectType
&type
) override
{}
172 virtual void visit (ClosureType
&type
) override
{}
175 BaseRules (BaseType
*base
)
176 : mappings (Analysis::Mappings::get ()),
177 context (Resolver::TypeCheckContext::get ()),
178 resolved (new ErrorType (base
->get_ref (), base
->get_ref ()))
181 Analysis::Mappings
*mappings
;
182 Resolver::TypeCheckContext
*context
;
184 /* Temporary storage for the result of a unification.
185 We could return the result directly instead of storing it in the rule
186 object, but that involves modifying the visitor pattern to accommodate
187 the return value, which is too complex. */
191 /* Returns a pointer to the ty that created this rule. */
192 virtual BaseType
*get_base () = 0;
195 class InferRules
: public BaseRules
197 using Rust::TyTy::BaseRules::visit
;
200 InferRules (InferType
*base
) : BaseRules (base
), base (base
) {}
202 void visit (BoolType
&type
) override
205 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
208 resolved
= type
.clone ();
212 BaseRules::visit (type
);
215 void visit (IntType
&type
) override
218 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
219 || (base
->get_infer_kind ()
220 == TyTy::InferType::InferTypeKind::INTEGRAL
);
223 resolved
= type
.clone ();
227 BaseRules::visit (type
);
230 void visit (UintType
&type
) override
233 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
234 || (base
->get_infer_kind ()
235 == TyTy::InferType::InferTypeKind::INTEGRAL
);
238 resolved
= type
.clone ();
242 BaseRules::visit (type
);
245 void visit (USizeType
&type
) override
248 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
249 || (base
->get_infer_kind ()
250 == TyTy::InferType::InferTypeKind::INTEGRAL
);
253 resolved
= type
.clone ();
257 BaseRules::visit (type
);
260 void visit (ISizeType
&type
) override
263 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
264 || (base
->get_infer_kind ()
265 == TyTy::InferType::InferTypeKind::INTEGRAL
);
268 resolved
= type
.clone ();
272 BaseRules::visit (type
);
275 void visit (FloatType
&type
) override
278 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
279 || (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
);
282 resolved
= type
.clone ();
286 BaseRules::visit (type
);
289 void visit (ArrayType
&type
) override
292 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
295 resolved
= type
.clone ();
299 BaseRules::visit (type
);
302 void visit (SliceType
&type
) override
305 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
308 resolved
= type
.clone ();
312 BaseRules::visit (type
);
315 void visit (ADTType
&type
) override
318 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
321 resolved
= type
.clone ();
325 BaseRules::visit (type
);
328 void visit (TupleType
&type
) override
331 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
334 resolved
= type
.clone ();
338 BaseRules::visit (type
);
341 void visit (InferType
&type
) override
343 switch (base
->get_infer_kind ())
345 case InferType::InferTypeKind::GENERAL
:
346 resolved
= type
.clone ();
349 case InferType::InferTypeKind::INTEGRAL
: {
350 if (type
.get_infer_kind () == InferType::InferTypeKind::INTEGRAL
)
352 resolved
= type
.clone ();
355 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
357 resolved
= base
->clone ();
363 case InferType::InferTypeKind::FLOAT
: {
364 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
366 resolved
= type
.clone ();
369 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
371 resolved
= base
->clone ();
378 BaseRules::visit (type
);
381 void visit (CharType
&type
) override
385 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
388 resolved
= type
.clone ();
392 BaseRules::visit (type
);
396 void visit (ReferenceType
&type
) override
399 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
402 resolved
= type
.clone ();
406 BaseRules::visit (type
);
409 void visit (PointerType
&type
) override
412 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
415 resolved
= type
.clone ();
419 BaseRules::visit (type
);
422 void visit (ParamType
&type
) override
425 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
428 resolved
= type
.clone ();
432 BaseRules::visit (type
);
435 void visit (DynamicObjectType
&type
) override
438 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
441 resolved
= type
.clone ();
445 BaseRules::visit (type
);
448 void visit (ClosureType
&type
) override
451 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
454 resolved
= type
.clone ();
458 BaseRules::visit (type
);
462 BaseType
*get_base () override
{ return base
; }
467 class FnRules
: public BaseRules
469 using Rust::TyTy::BaseRules::visit
;
472 FnRules (FnType
*base
) : BaseRules (base
), base (base
) {}
474 void visit (InferType
&type
) override
476 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
478 BaseRules::visit (type
);
482 resolved
= base
->clone ();
483 resolved
->set_ref (type
.get_ref ());
486 void visit (FnType
&type
) override
488 if (base
->num_params () != type
.num_params ())
490 BaseRules::visit (type
);
494 for (size_t i
= 0; i
< base
->num_params (); i
++)
496 auto a
= base
->param_at (i
).second
;
497 auto b
= type
.param_at (i
).second
;
499 auto unified_param
= a
->unify (b
);
500 if (unified_param
== nullptr)
502 BaseRules::visit (type
);
508 = base
->get_return_type ()->unify (type
.get_return_type ());
509 if (unified_return
== nullptr)
511 BaseRules::visit (type
);
515 resolved
= base
->clone ();
516 resolved
->set_ref (type
.get_ref ());
520 BaseType
*get_base () override
{ return base
; }
525 class FnptrRules
: public BaseRules
527 using Rust::TyTy::BaseRules::visit
;
530 FnptrRules (FnPtr
*base
) : BaseRules (base
), base (base
) {}
532 void visit (InferType
&type
) override
534 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
536 BaseRules::visit (type
);
540 resolved
= base
->clone ();
541 resolved
->set_ref (type
.get_ref ());
544 void visit (FnPtr
&type
) override
546 auto this_ret_type
= base
->get_return_type ();
547 auto other_ret_type
= type
.get_return_type ();
548 auto unified_result
= this_ret_type
->unify (other_ret_type
);
549 if (unified_result
== nullptr
550 || unified_result
->get_kind () == TypeKind::ERROR
)
552 BaseRules::visit (type
);
556 if (base
->num_params () != type
.num_params ())
558 BaseRules::visit (type
);
562 for (size_t i
= 0; i
< base
->num_params (); i
++)
564 auto this_param
= base
->param_at (i
);
565 auto other_param
= type
.param_at (i
);
566 auto unified_param
= this_param
->unify (other_param
);
567 if (unified_param
== nullptr
568 || unified_param
->get_kind () == TypeKind::ERROR
)
570 BaseRules::visit (type
);
575 resolved
= base
->clone ();
576 resolved
->set_ref (type
.get_ref ());
579 void visit (FnType
&type
) override
581 auto this_ret_type
= base
->get_return_type ();
582 auto other_ret_type
= type
.get_return_type ();
583 auto unified_result
= this_ret_type
->unify (other_ret_type
);
584 if (unified_result
== nullptr
585 || unified_result
->get_kind () == TypeKind::ERROR
)
587 BaseRules::visit (type
);
591 if (base
->num_params () != type
.num_params ())
593 BaseRules::visit (type
);
597 for (size_t i
= 0; i
< base
->num_params (); i
++)
599 auto this_param
= base
->param_at (i
);
600 auto other_param
= type
.param_at (i
).second
;
601 auto unified_param
= this_param
->unify (other_param
);
602 if (unified_param
== nullptr
603 || unified_param
->get_kind () == TypeKind::ERROR
)
605 BaseRules::visit (type
);
610 resolved
= base
->clone ();
611 resolved
->set_ref (type
.get_ref ());
615 BaseType
*get_base () override
{ return base
; }
620 class ClosureRules
: public BaseRules
622 using Rust::TyTy::BaseRules::visit
;
625 ClosureRules (ClosureType
*base
) : BaseRules (base
), base (base
) {}
630 BaseType
*get_base () override
{ return base
; }
635 class ArrayRules
: public BaseRules
637 using Rust::TyTy::BaseRules::visit
;
640 ArrayRules (ArrayType
*base
) : BaseRules (base
), base (base
) {}
642 void visit (ArrayType
&type
) override
646 = base
->get_element_type ()->unify (type
.get_element_type ());
647 if (base_resolved
== nullptr)
649 BaseRules::visit (type
);
654 = new ArrayType (type
.get_ref (), type
.get_ty_ref (),
655 type
.get_ident ().locus
, type
.get_capacity_expr (),
656 TyVar (base_resolved
->get_ref ()));
659 void visit (InferType
&type
) override
661 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
663 BaseRules::visit (type
);
667 resolved
= base
->clone ();
668 resolved
->set_ref (type
.get_ref ());
672 BaseType
*get_base () override
{ return base
; }
677 class SliceRules
: public BaseRules
679 using Rust::TyTy::BaseRules::visit
;
682 SliceRules (SliceType
*base
) : BaseRules (base
), base (base
) {}
684 void visit (SliceType
&type
) override
688 = base
->get_element_type ()->unify (type
.get_element_type ());
689 if (base_resolved
== nullptr)
691 BaseRules::visit (type
);
695 resolved
= new SliceType (type
.get_ref (), type
.get_ty_ref (),
696 type
.get_ident ().locus
,
697 TyVar (base_resolved
->get_ref ()));
700 void visit (InferType
&type
) override
702 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
704 BaseRules::visit (type
);
708 resolved
= base
->clone ();
709 resolved
->set_ref (type
.get_ref ());
713 BaseType
*get_base () override
{ return base
; }
718 class BoolRules
: public BaseRules
720 using Rust::TyTy::BaseRules::visit
;
723 BoolRules (BoolType
*base
) : BaseRules (base
), base (base
) {}
725 void visit (BoolType
&type
) override
727 resolved
= new BoolType (type
.get_ref (), type
.get_ty_ref ());
730 void visit (InferType
&type
) override
732 switch (type
.get_infer_kind ())
734 case InferType::InferTypeKind::GENERAL
:
735 resolved
= base
->clone ();
739 BaseRules::visit (type
);
745 BaseType
*get_base () override
{ return base
; }
750 class IntRules
: public BaseRules
752 using Rust::TyTy::BaseRules::visit
;
755 IntRules (IntType
*base
) : BaseRules (base
), base (base
) {}
757 void visit (InferType
&type
) override
759 // cant assign a float inference variable
760 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
762 BaseRules::visit (type
);
766 resolved
= base
->clone ();
767 resolved
->set_ref (type
.get_ref ());
770 void visit (IntType
&type
) override
772 if (type
.get_int_kind () != base
->get_int_kind ())
774 BaseRules::visit (type
);
779 = new IntType (type
.get_ref (), type
.get_ty_ref (), type
.get_int_kind ());
783 BaseType
*get_base () override
{ return base
; }
788 class UintRules
: public BaseRules
790 using Rust::TyTy::BaseRules::visit
;
793 UintRules (UintType
*base
) : BaseRules (base
), base (base
) {}
795 void visit (InferType
&type
) override
797 // cant assign a float inference variable
798 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
800 BaseRules::visit (type
);
804 resolved
= base
->clone ();
805 resolved
->set_ref (type
.get_ref ());
808 void visit (UintType
&type
) override
810 if (type
.get_uint_kind () != base
->get_uint_kind ())
812 BaseRules::visit (type
);
816 resolved
= new UintType (type
.get_ref (), type
.get_ty_ref (),
817 type
.get_uint_kind ());
821 BaseType
*get_base () override
{ return base
; }
826 class FloatRules
: public BaseRules
828 using Rust::TyTy::BaseRules::visit
;
831 FloatRules (FloatType
*base
) : BaseRules (base
), base (base
) {}
833 void visit (InferType
&type
) override
835 if (type
.get_infer_kind () == InferType::InferTypeKind::INTEGRAL
)
837 BaseRules::visit (type
);
841 resolved
= base
->clone ();
842 resolved
->set_ref (type
.get_ref ());
845 void visit (FloatType
&type
) override
847 if (type
.get_float_kind () != base
->get_float_kind ())
849 BaseRules::visit (type
);
853 resolved
= new FloatType (type
.get_ref (), type
.get_ty_ref (),
854 type
.get_float_kind ());
858 BaseType
*get_base () override
{ return base
; }
863 class ADTRules
: public BaseRules
865 using Rust::TyTy::BaseRules::visit
;
868 ADTRules (ADTType
*base
) : BaseRules (base
), base (base
) {}
870 void visit (ADTType
&type
) override
872 if (base
->get_adt_kind () != type
.get_adt_kind ())
874 BaseRules::visit (type
);
878 if (base
->get_identifier ().compare (type
.get_identifier ()) != 0)
880 BaseRules::visit (type
);
884 if (base
->number_of_variants () != type
.number_of_variants ())
886 BaseRules::visit (type
);
890 for (size_t i
= 0; i
< type
.number_of_variants (); ++i
)
892 TyTy::VariantDef
*a
= base
->get_variants ().at (i
);
893 TyTy::VariantDef
*b
= type
.get_variants ().at (i
);
895 if (a
->num_fields () != b
->num_fields ())
897 BaseRules::visit (type
);
901 for (size_t j
= 0; j
< a
->num_fields (); j
++)
903 TyTy::StructFieldType
*base_field
= a
->get_field_at_index (j
);
904 TyTy::StructFieldType
*other_field
= b
->get_field_at_index (j
);
906 TyTy::BaseType
*this_field_ty
= base_field
->get_field_type ();
907 TyTy::BaseType
*other_field_ty
= other_field
->get_field_type ();
909 BaseType
*unified_ty
= this_field_ty
->unify (other_field_ty
);
910 if (unified_ty
->get_kind () == TyTy::TypeKind::ERROR
)
915 // generic args for the unit-struct case
916 if (type
.is_unit () && base
->is_unit ())
918 rust_assert (type
.get_num_substitutions ()
919 == base
->get_num_substitutions ());
921 for (size_t i
= 0; i
< type
.get_num_substitutions (); i
++)
923 auto &a
= base
->get_substs ().at (i
);
924 auto &b
= type
.get_substs ().at (i
);
926 auto pa
= a
.get_param_ty ();
927 auto pb
= b
.get_param_ty ();
929 auto res
= pa
->unify (pb
);
930 if (res
->get_kind () == TyTy::TypeKind::ERROR
)
937 resolved
= type
.clone ();
940 void visit (InferType
&type
) override
942 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
944 BaseRules::visit (type
);
948 resolved
= base
->clone ();
949 resolved
->set_ref (type
.get_ref ());
953 BaseType
*get_base () override
{ return base
; }
958 class TupleRules
: public BaseRules
960 using Rust::TyTy::BaseRules::visit
;
963 TupleRules (TupleType
*base
) : BaseRules (base
), base (base
) {}
965 void visit (TupleType
&type
) override
967 if (base
->num_fields () != type
.num_fields ())
969 BaseRules::visit (type
);
973 std::vector
<TyVar
> fields
;
974 for (size_t i
= 0; i
< base
->num_fields (); i
++)
976 BaseType
*bo
= base
->get_field (i
);
977 BaseType
*fo
= type
.get_field (i
);
979 BaseType
*unified_ty
= bo
->unify (fo
);
980 if (unified_ty
->get_kind () == TyTy::TypeKind::ERROR
)
983 fields
.push_back (TyVar (unified_ty
->get_ref ()));
986 resolved
= new TyTy::TupleType (type
.get_ref (), type
.get_ty_ref (),
987 type
.get_ident ().locus
, fields
);
990 void visit (InferType
&type
) override
992 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
994 BaseRules::visit (type
);
998 resolved
= base
->clone ();
999 resolved
->set_ref (type
.get_ref ());
1003 BaseType
*get_base () override
{ return base
; }
1008 class USizeRules
: public BaseRules
1010 using Rust::TyTy::BaseRules::visit
;
1013 USizeRules (USizeType
*base
) : BaseRules (base
), base (base
) {}
1015 void visit (InferType
&type
) override
1017 // cant assign a float inference variable
1018 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
1020 BaseRules::visit (type
);
1024 resolved
= base
->clone ();
1025 resolved
->set_ref (type
.get_ref ());
1028 void visit (USizeType
&type
) override
{ resolved
= type
.clone (); }
1031 BaseType
*get_base () override
{ return base
; }
1036 class ISizeRules
: public BaseRules
1038 using Rust::TyTy::BaseRules::visit
;
1041 ISizeRules (ISizeType
*base
) : BaseRules (base
), base (base
) {}
1043 void visit (InferType
&type
) override
1045 // cant assign a float inference variable
1046 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
1048 BaseRules::visit (type
);
1052 resolved
= base
->clone ();
1053 resolved
->set_ref (type
.get_ref ());
1056 void visit (ISizeType
&type
) override
{ resolved
= type
.clone (); }
1059 BaseType
*get_base () override
{ return base
; }
1064 class CharRules
: public BaseRules
1066 using Rust::TyTy::BaseRules::visit
;
1069 CharRules (CharType
*base
) : BaseRules (base
), base (base
) {}
1071 void visit (InferType
&type
) override
1073 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1075 BaseRules::visit (type
);
1079 resolved
= base
->clone ();
1080 resolved
->set_ref (type
.get_ref ());
1083 void visit (CharType
&type
) override
{ resolved
= type
.clone (); }
1086 BaseType
*get_base () override
{ return base
; }
1091 class ReferenceRules
: public BaseRules
1093 using Rust::TyTy::BaseRules::visit
;
1096 ReferenceRules (ReferenceType
*base
) : BaseRules (base
), base (base
) {}
1098 void visit (ReferenceType
&type
) override
1100 auto base_type
= base
->get_base ();
1101 auto other_base_type
= type
.get_base ();
1103 TyTy::BaseType
*base_resolved
= base_type
->unify (other_base_type
);
1104 if (base_resolved
== nullptr
1105 || base_resolved
->get_kind () == TypeKind::ERROR
)
1107 BaseRules::visit (type
);
1111 // rust is permissive about mutablity here you can always go from mutable to
1112 // immutable but not the otherway round
1113 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1116 BaseRules::visit (type
);
1120 resolved
= new ReferenceType (base
->get_ref (), base
->get_ty_ref (),
1121 TyVar (base_resolved
->get_ref ()),
1122 base
->mutability ());
1125 void visit (InferType
&type
) override
1127 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1129 BaseRules::visit (type
);
1133 resolved
= base
->clone ();
1134 resolved
->set_ref (type
.get_ref ());
1138 BaseType
*get_base () override
{ return base
; }
1140 ReferenceType
*base
;
1143 class PointerRules
: public BaseRules
1145 using Rust::TyTy::BaseRules::visit
;
1148 PointerRules (PointerType
*base
) : BaseRules (base
), base (base
) {}
1150 void visit (PointerType
&type
) override
1152 auto base_type
= base
->get_base ();
1153 auto other_base_type
= type
.get_base ();
1155 TyTy::BaseType
*base_resolved
= base_type
->unify (other_base_type
);
1156 if (base_resolved
== nullptr
1157 || base_resolved
->get_kind () == TypeKind::ERROR
)
1159 BaseRules::visit (type
);
1163 // rust is permissive about mutablity here you can always go from mutable to
1164 // immutable but not the otherway round
1165 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1168 BaseRules::visit (type
);
1172 resolved
= new PointerType (base
->get_ref (), base
->get_ty_ref (),
1173 TyVar (base_resolved
->get_ref ()),
1174 base
->mutability ());
1177 void visit (InferType
&type
) override
1179 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1181 BaseRules::visit (type
);
1185 resolved
= base
->clone ();
1186 resolved
->set_ref (type
.get_ref ());
1190 BaseType
*get_base () override
{ return base
; }
1195 class ParamRules
: public BaseRules
1197 using Rust::TyTy::BaseRules::visit
;
1200 ParamRules (ParamType
*base
) : BaseRules (base
), base (base
) {}
1202 // param types are a placeholder we shouldn't have cases where we unify
1203 // against it. eg: struct foo<T> { a: T }; When we invoke it we can do either:
1205 // foo<i32>{ a: 123 }.
1206 // Then this enforces the i32 type to be referenced on the
1207 // field via an hirid.
1209 // rust also allows for a = foo{a:123}; Where we can use an Inference Variable
1210 // to handle the typing of the struct
1211 BaseType
*unify (BaseType
*other
) override final
1213 if (!base
->can_resolve ())
1214 return BaseRules::unify (other
);
1216 auto lookup
= base
->resolve ();
1217 return lookup
->unify (other
);
1220 void visit (ParamType
&type
) override
1222 if (base
->get_symbol ().compare (type
.get_symbol ()) != 0)
1224 BaseRules::visit (type
);
1228 resolved
= type
.clone ();
1231 void visit (InferType
&type
) override
1233 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1235 BaseRules::visit (type
);
1239 resolved
= base
->clone ();
1243 BaseType
*get_base () override
{ return base
; }
1248 class StrRules
: public BaseRules
1250 // FIXME we will need a enum for the StrType like ByteBuf etc..
1251 using Rust::TyTy::BaseRules::visit
;
1254 StrRules (StrType
*base
) : BaseRules (base
), base (base
) {}
1256 void visit (StrType
&type
) override
{ resolved
= type
.clone (); }
1259 BaseType
*get_base () override
{ return base
; }
1264 class NeverRules
: public BaseRules
1266 using Rust::TyTy::BaseRules::visit
;
1269 NeverRules (NeverType
*base
) : BaseRules (base
), base (base
) {}
1271 void visit (NeverType
&type
) override
{ resolved
= type
.clone (); }
1274 BaseType
*get_base () override
{ return base
; }
1279 class PlaceholderRules
: public BaseRules
1281 using Rust::TyTy::BaseRules::visit
;
1284 PlaceholderRules (PlaceholderType
*base
) : BaseRules (base
), base (base
) {}
1286 BaseType
*unify (BaseType
*other
) override final
1288 if (!base
->can_resolve ())
1289 return BaseRules::unify (other
);
1291 BaseType
*lookup
= base
->resolve ();
1292 return lookup
->unify (other
);
1295 void visit (PlaceholderType
&type
) override
1297 if (base
->get_symbol ().compare (type
.get_symbol ()) != 0)
1299 BaseRules::visit (type
);
1303 resolved
= type
.clone ();
1306 void visit (InferType
&type
) override
1308 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1310 BaseRules::visit (type
);
1314 resolved
= base
->clone ();
1318 BaseType
*get_base () override
{ return base
; }
1320 PlaceholderType
*base
;
1323 class DynamicRules
: public BaseRules
1325 using Rust::TyTy::BaseRules::visit
;
1328 DynamicRules (DynamicObjectType
*base
) : BaseRules (base
), base (base
) {}
1330 void visit (InferType
&type
) override
1332 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1334 BaseRules::visit (type
);
1338 resolved
= base
->clone ();
1341 void visit (DynamicObjectType
&type
) override
1343 if (base
->num_specified_bounds () != type
.num_specified_bounds ())
1345 BaseRules::visit (type
);
1349 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
1350 if (!base
->bounds_compatible (type
, ref_locus
, true))
1352 BaseRules::visit (type
);
1356 resolved
= base
->clone ();
1360 BaseType
*get_base () override
{ return base
; }
1362 DynamicObjectType
*base
;
1368 #endif // RUST_TYTY_RULES