]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/typecheck/rust-tyty-cmp.h
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #ifndef RUST_TYTY_CMP_H
20 #define RUST_TYTY_CMP_H
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 // we need to fix this properly by implementing the match for assembling
33 extern bool autoderef_cmp_flag
;
35 class BaseCmp
: public TyConstVisitor
38 virtual bool can_eq (const BaseType
*other
)
40 if (other
->get_kind () == TypeKind::PARAM
)
42 const ParamType
*p
= static_cast<const ParamType
*> (other
);
43 other
= p
->resolve ();
45 if (other
->get_kind () == TypeKind::PLACEHOLDER
)
47 const PlaceholderType
*p
= static_cast<const PlaceholderType
*> (other
);
48 if (p
->can_resolve ())
50 other
= p
->resolve ();
53 if (other
->get_kind () == TypeKind::PROJECTION
)
55 const ProjectionType
*p
= static_cast<const ProjectionType
*> (other
);
59 other
->accept_vis (*this);
63 virtual void visit (const TupleType
&type
) override
69 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
71 = mappings
->lookup_location (get_base ()->get_ref ());
72 RichLocation
r (ref_locus
);
73 r
.add_range (base_locus
);
74 rust_error_at (r
, "expected [%s] got [%s]",
75 get_base ()->as_string ().c_str (),
76 type
.as_string ().c_str ());
80 virtual void visit (const ADTType
&type
) override
85 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
87 = mappings
->lookup_location (get_base ()->get_ref ());
88 RichLocation
r (ref_locus
);
89 r
.add_range (base_locus
);
90 rust_error_at (r
, "expected [%s] got [%s]",
91 get_base ()->as_string ().c_str (),
92 type
.as_string ().c_str ());
96 virtual void visit (const InferType
&type
) override
101 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
103 = mappings
->lookup_location (get_base ()->get_ref ());
104 RichLocation
r (ref_locus
);
105 r
.add_range (base_locus
);
106 rust_error_at (r
, "expected [%s] got [%s]",
107 get_base ()->as_string ().c_str (),
108 type
.as_string ().c_str ());
112 virtual void visit (const FnType
&type
) override
117 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
119 = mappings
->lookup_location (get_base ()->get_ref ());
120 RichLocation
r (ref_locus
);
121 r
.add_range (base_locus
);
122 rust_error_at (r
, "expected [%s] got [%s]",
123 get_base ()->as_string ().c_str (),
124 type
.as_string ().c_str ());
128 virtual void visit (const FnPtr
&type
) override
133 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
135 = mappings
->lookup_location (get_base ()->get_ref ());
136 RichLocation
r (ref_locus
);
137 r
.add_range (base_locus
);
138 rust_error_at (r
, "expected [%s] got [%s]",
139 get_base ()->as_string ().c_str (),
140 type
.as_string ().c_str ());
144 virtual void visit (const ArrayType
&type
) override
149 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
151 = mappings
->lookup_location (get_base ()->get_ref ());
152 RichLocation
r (ref_locus
);
153 r
.add_range (base_locus
);
154 rust_error_at (r
, "expected [%s] got [%s]",
155 get_base ()->as_string ().c_str (),
156 type
.as_string ().c_str ());
160 virtual void visit (const SliceType
&type
) override
165 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
167 = mappings
->lookup_location (get_base ()->get_ref ());
168 RichLocation
r (ref_locus
);
169 r
.add_range (base_locus
);
170 rust_error_at (r
, "expected [%s] got [%s]",
171 get_base ()->as_string ().c_str (),
172 type
.as_string ().c_str ());
176 virtual void visit (const BoolType
&type
) override
181 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
183 = mappings
->lookup_location (get_base ()->get_ref ());
184 RichLocation
r (ref_locus
);
185 r
.add_range (base_locus
);
186 rust_error_at (r
, "expected [%s] got [%s]",
187 get_base ()->as_string ().c_str (),
188 type
.as_string ().c_str ());
192 virtual void visit (const IntType
&type
) override
197 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
199 = mappings
->lookup_location (get_base ()->get_ref ());
200 RichLocation
r (ref_locus
);
201 r
.add_range (base_locus
);
202 rust_error_at (r
, "expected [%s] got [%s]",
203 get_base ()->as_string ().c_str (),
204 type
.as_string ().c_str ());
208 virtual void visit (const UintType
&type
) override
213 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
215 = mappings
->lookup_location (get_base ()->get_ref ());
216 RichLocation
r (ref_locus
);
217 r
.add_range (base_locus
);
218 rust_error_at (r
, "expected [%s] got [%s]",
219 get_base ()->as_string ().c_str (),
220 type
.as_string ().c_str ());
224 virtual void visit (const USizeType
&type
) override
229 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
231 = mappings
->lookup_location (get_base ()->get_ref ());
232 RichLocation
r (ref_locus
);
233 r
.add_range (base_locus
);
234 rust_error_at (r
, "expected [%s] got [%s]",
235 get_base ()->as_string ().c_str (),
236 type
.as_string ().c_str ());
240 virtual void visit (const ISizeType
&type
) override
245 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
247 = mappings
->lookup_location (get_base ()->get_ref ());
248 RichLocation
r (ref_locus
);
249 r
.add_range (base_locus
);
250 rust_error_at (r
, "expected [%s] got [%s]",
251 get_base ()->as_string ().c_str (),
252 type
.as_string ().c_str ());
256 virtual void visit (const FloatType
&type
) override
261 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
263 = mappings
->lookup_location (get_base ()->get_ref ());
264 RichLocation
r (ref_locus
);
265 r
.add_range (base_locus
);
266 rust_error_at (r
, "expected [%s] got [%s]",
267 get_base ()->as_string ().c_str (),
268 type
.as_string ().c_str ());
272 virtual void visit (const ErrorType
&type
) override
277 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
279 = mappings
->lookup_location (get_base ()->get_ref ());
280 RichLocation
r (ref_locus
);
281 r
.add_range (base_locus
);
282 rust_error_at (r
, "expected [%s] got [%s]",
283 get_base ()->as_string ().c_str (),
284 type
.as_string ().c_str ());
288 virtual void visit (const CharType
&type
) override
293 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
295 = mappings
->lookup_location (get_base ()->get_ref ());
296 RichLocation
r (ref_locus
);
297 r
.add_range (base_locus
);
298 rust_error_at (r
, "expected [%s] got [%s]",
299 get_base ()->as_string ().c_str (),
300 type
.as_string ().c_str ());
304 virtual void visit (const ReferenceType
&type
) override
309 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
311 = mappings
->lookup_location (get_base ()->get_ref ());
312 RichLocation
r (ref_locus
);
313 r
.add_range (base_locus
);
314 rust_error_at (r
, "expected [%s] got [%s]",
315 get_base ()->as_string ().c_str (),
316 type
.as_string ().c_str ());
320 virtual void visit (const PointerType
&type
) override
325 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
327 = mappings
->lookup_location (get_base ()->get_ref ());
328 RichLocation
r (ref_locus
);
329 r
.add_range (base_locus
);
330 rust_error_at (r
, "expected [%s] got [%s]",
331 get_base ()->as_string ().c_str (),
332 type
.as_string ().c_str ());
336 virtual void visit (const StrType
&type
) override
341 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
343 = mappings
->lookup_location (get_base ()->get_ref ());
344 RichLocation
r (ref_locus
);
345 r
.add_range (base_locus
);
346 rust_error_at (r
, "expected [%s] got [%s]",
347 get_base ()->as_string ().c_str (),
348 type
.as_string ().c_str ());
352 virtual void visit (const NeverType
&type
) override
357 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
359 = mappings
->lookup_location (get_base ()->get_ref ());
360 RichLocation
r (ref_locus
);
361 r
.add_range (base_locus
);
362 rust_error_at (r
, "expected [%s] got [%s]",
363 get_base ()->as_string ().c_str (),
364 type
.as_string ().c_str ());
368 virtual void visit (const ProjectionType
&type
) override
373 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
375 = mappings
->lookup_location (get_base ()->get_ref ());
376 RichLocation
r (ref_locus
);
377 r
.add_range (base_locus
);
378 rust_error_at (r
, "expected [%s] got [%s]",
379 get_base ()->as_string ().c_str (),
380 type
.as_string ().c_str ());
384 virtual void visit (const PlaceholderType
&type
) override
386 // it is ok for types to can eq to a placeholder
390 virtual void visit (const ParamType
&type
) override
395 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
397 = mappings
->lookup_location (get_base ()->get_ref ());
398 RichLocation
r (ref_locus
);
399 r
.add_range (base_locus
);
400 rust_error_at (r
, "expected [%s] got [%s]",
401 get_base ()->as_string ().c_str (),
402 type
.as_string ().c_str ());
406 virtual void visit (const DynamicObjectType
&type
) override
411 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
413 = mappings
->lookup_location (get_base ()->get_ref ());
414 RichLocation
r (ref_locus
);
415 r
.add_range (base_locus
);
416 rust_error_at (r
, "expected [%s] got [%s]",
417 get_base ()->as_string ().c_str (),
418 type
.as_string ().c_str ());
422 virtual void visit (const ClosureType
&type
) override
427 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
429 = mappings
->lookup_location (get_base ()->get_ref ());
430 RichLocation
r (ref_locus
);
431 r
.add_range (base_locus
);
432 rust_error_at (r
, "expected [%s] got [%s]",
433 get_base ()->as_string ().c_str (),
434 type
.as_string ().c_str ());
439 BaseCmp (const BaseType
*base
, bool emit_errors
)
440 : mappings (Analysis::Mappings::get ()),
441 context (Resolver::TypeCheckContext::get ()), ok (false),
442 emit_error_flag (emit_errors
)
445 Analysis::Mappings
*mappings
;
446 Resolver::TypeCheckContext
*context
;
449 bool emit_error_flag
;
452 /* Returns a pointer to the ty that created this rule. */
453 virtual const BaseType
*get_base () const = 0;
456 class InferCmp
: public BaseCmp
458 using Rust::TyTy::BaseCmp::visit
;
461 InferCmp (const InferType
*base
, bool emit_errors
)
462 : BaseCmp (base
, emit_errors
), base (base
)
465 void visit (const BoolType
&type
) override
468 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
475 BaseCmp::visit (type
);
478 void visit (const IntType
&type
) override
481 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
482 || (base
->get_infer_kind ()
483 == TyTy::InferType::InferTypeKind::INTEGRAL
);
490 BaseCmp::visit (type
);
493 void visit (const UintType
&type
) override
496 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
497 || (base
->get_infer_kind ()
498 == TyTy::InferType::InferTypeKind::INTEGRAL
);
505 BaseCmp::visit (type
);
508 void visit (const USizeType
&type
) override
511 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
512 || (base
->get_infer_kind ()
513 == TyTy::InferType::InferTypeKind::INTEGRAL
);
520 BaseCmp::visit (type
);
523 void visit (const ISizeType
&type
) override
526 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
527 || (base
->get_infer_kind ()
528 == TyTy::InferType::InferTypeKind::INTEGRAL
);
535 BaseCmp::visit (type
);
538 void visit (const FloatType
&type
) override
541 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
542 || (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
);
549 BaseCmp::visit (type
);
552 void visit (const ArrayType
&type
) override
555 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
562 BaseCmp::visit (type
);
565 void visit (const SliceType
&type
) override
568 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
575 BaseCmp::visit (type
);
578 void visit (const ADTType
&type
) override
581 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
588 BaseCmp::visit (type
);
591 void visit (const TupleType
&type
) override
594 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
601 BaseCmp::visit (type
);
604 void visit (const InferType
&type
) override
606 switch (base
->get_infer_kind ())
608 case InferType::InferTypeKind::GENERAL
:
612 case InferType::InferTypeKind::INTEGRAL
: {
613 if (type
.get_infer_kind () == InferType::InferTypeKind::INTEGRAL
)
618 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
626 case InferType::InferTypeKind::FLOAT
: {
627 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
632 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
641 BaseCmp::visit (type
);
644 void visit (const CharType
&type
) override
648 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
655 BaseCmp::visit (type
);
659 void visit (const ReferenceType
&type
) override
662 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
669 BaseCmp::visit (type
);
672 void visit (const PointerType
&type
) override
675 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
682 BaseCmp::visit (type
);
685 void visit (const ParamType
&) override
{ ok
= true; }
687 void visit (const DynamicObjectType
&type
) override
690 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
697 BaseCmp::visit (type
);
700 void visit (const ClosureType
&type
) override
703 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
710 BaseCmp::visit (type
);
714 const BaseType
*get_base () const override
{ return base
; }
715 const InferType
*base
;
718 class FnCmp
: public BaseCmp
720 using Rust::TyTy::BaseCmp::visit
;
723 FnCmp (const FnType
*base
, bool emit_errors
)
724 : BaseCmp (base
, emit_errors
), base (base
)
727 void visit (const InferType
&type
) override
729 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
732 void visit (const FnType
&type
) override
734 if (base
->num_params () != type
.num_params ())
736 BaseCmp::visit (type
);
740 for (size_t i
= 0; i
< base
->num_params (); i
++)
742 auto a
= base
->param_at (i
).second
;
743 auto b
= type
.param_at (i
).second
;
745 if (!a
->can_eq (b
, emit_error_flag
))
747 emit_error_flag
= false;
748 BaseCmp::visit (type
);
753 if (!base
->get_return_type ()->can_eq (type
.get_return_type (),
756 emit_error_flag
= false;
757 BaseCmp::visit (type
);
765 const BaseType
*get_base () const override
{ return base
; }
769 class FnptrCmp
: public BaseCmp
771 using Rust::TyTy::BaseCmp::visit
;
774 FnptrCmp (const FnPtr
*base
, bool emit_errors
)
775 : BaseCmp (base
, emit_errors
), base (base
)
778 void visit (const InferType
&type
) override
780 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
782 BaseCmp::visit (type
);
789 void visit (const FnPtr
&type
) override
791 if (base
->num_params () != type
.num_params ())
793 BaseCmp::visit (type
);
797 auto this_ret_type
= base
->get_return_type ();
798 auto other_ret_type
= type
.get_return_type ();
799 if (!this_ret_type
->can_eq (other_ret_type
, emit_error_flag
))
801 BaseCmp::visit (type
);
805 for (size_t i
= 0; i
< base
->num_params (); i
++)
807 auto this_param
= base
->param_at (i
);
808 auto other_param
= type
.param_at (i
);
809 if (!this_param
->can_eq (other_param
, emit_error_flag
))
811 BaseCmp::visit (type
);
819 void visit (const FnType
&type
) override
821 if (base
->num_params () != type
.num_params ())
823 BaseCmp::visit (type
);
827 auto this_ret_type
= base
->get_return_type ();
828 auto other_ret_type
= type
.get_return_type ();
829 if (!this_ret_type
->can_eq (other_ret_type
, emit_error_flag
))
831 BaseCmp::visit (type
);
835 for (size_t i
= 0; i
< base
->num_params (); i
++)
837 auto this_param
= base
->param_at (i
);
838 auto other_param
= type
.param_at (i
).second
;
839 if (!this_param
->can_eq (other_param
, emit_error_flag
))
841 BaseCmp::visit (type
);
850 const BaseType
*get_base () const override
{ return base
; }
854 class ClosureCmp
: public BaseCmp
856 using Rust::TyTy::BaseCmp::visit
;
859 ClosureCmp (const ClosureType
*base
, bool emit_errors
)
860 : BaseCmp (base
, emit_errors
), base (base
)
863 void visit (const InferType
&type
) override
865 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
867 BaseCmp::visit (type
);
874 void visit (const ClosureType
&type
) override
876 if (base
->get_def_id () != type
.get_def_id ())
878 BaseCmp::visit (type
);
882 if (!base
->get_parameters ().can_eq (&type
.get_parameters (), false))
884 BaseCmp::visit (type
);
888 if (!base
->get_result_type ().can_eq (&type
.get_result_type (), false))
890 BaseCmp::visit (type
);
898 const BaseType
*get_base () const override
{ return base
; }
899 const ClosureType
*base
;
902 class ArrayCmp
: public BaseCmp
904 using Rust::TyTy::BaseCmp::visit
;
907 ArrayCmp (const ArrayType
*base
, bool emit_errors
)
908 : BaseCmp (base
, emit_errors
), base (base
)
911 void visit (const ArrayType
&type
) override
914 const BaseType
*base_element
= base
->get_element_type ();
915 const BaseType
*other_element
= type
.get_element_type ();
916 if (!base_element
->can_eq (other_element
, emit_error_flag
))
918 BaseCmp::visit (type
);
925 void visit (const InferType
&type
) override
927 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
929 BaseCmp::visit (type
);
937 const BaseType
*get_base () const override
{ return base
; }
938 const ArrayType
*base
;
941 class SliceCmp
: public BaseCmp
943 using Rust::TyTy::BaseCmp::visit
;
946 SliceCmp (const SliceType
*base
, bool emit_errors
)
947 : BaseCmp (base
, emit_errors
), base (base
)
950 void visit (const SliceType
&type
) override
953 const BaseType
*base_element
= base
->get_element_type ();
954 const BaseType
*other_element
= type
.get_element_type ();
955 if (!base_element
->can_eq (other_element
, emit_error_flag
))
957 BaseCmp::visit (type
);
964 void visit (const InferType
&type
) override
966 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
968 BaseCmp::visit (type
);
976 const BaseType
*get_base () const override
{ return base
; }
977 const SliceType
*base
;
980 class BoolCmp
: public BaseCmp
982 using Rust::TyTy::BaseCmp::visit
;
985 BoolCmp (const BoolType
*base
, bool emit_errors
)
986 : BaseCmp (base
, emit_errors
), base (base
)
989 void visit (const BoolType
&type
) override
{ ok
= true; }
991 void visit (const InferType
&type
) override
993 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
997 const BaseType
*get_base () const override
{ return base
; }
998 const BoolType
*base
;
1001 class IntCmp
: public BaseCmp
1003 using Rust::TyTy::BaseCmp::visit
;
1006 IntCmp (const IntType
*base
, bool emit_errors
)
1007 : BaseCmp (base
, emit_errors
), base (base
)
1010 void visit (const InferType
&type
) override
1012 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1015 void visit (const IntType
&type
) override
1017 ok
= type
.get_int_kind () == base
->get_int_kind ();
1021 const BaseType
*get_base () const override
{ return base
; }
1022 const IntType
*base
;
1025 class UintCmp
: public BaseCmp
1027 using Rust::TyTy::BaseCmp::visit
;
1030 UintCmp (const UintType
*base
, bool emit_errors
)
1031 : BaseCmp (base
, emit_errors
), base (base
)
1034 void visit (const InferType
&type
) override
1036 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1039 void visit (const UintType
&type
) override
1041 ok
= type
.get_uint_kind () == base
->get_uint_kind ();
1045 const BaseType
*get_base () const override
{ return base
; }
1046 const UintType
*base
;
1049 class FloatCmp
: public BaseCmp
1051 using Rust::TyTy::BaseCmp::visit
;
1054 FloatCmp (const FloatType
*base
, bool emit_errors
)
1055 : BaseCmp (base
, emit_errors
), base (base
)
1058 void visit (const InferType
&type
) override
1060 ok
= type
.get_infer_kind () != InferType::InferTypeKind::INTEGRAL
;
1063 void visit (const FloatType
&type
) override
1065 ok
= type
.get_float_kind () == base
->get_float_kind ();
1069 const BaseType
*get_base () const override
{ return base
; }
1070 const FloatType
*base
;
1073 class ADTCmp
: public BaseCmp
1075 using Rust::TyTy::BaseCmp::visit
;
1078 ADTCmp (const ADTType
*base
, bool emit_errors
)
1079 : BaseCmp (base
, emit_errors
), base (base
)
1082 void visit (const ADTType
&type
) override
1084 if (base
->get_adt_kind () != type
.get_adt_kind ())
1086 BaseCmp::visit (type
);
1090 if (base
->get_identifier ().compare (type
.get_identifier ()) != 0)
1092 BaseCmp::visit (type
);
1096 if (base
->number_of_variants () != type
.number_of_variants ())
1098 BaseCmp::visit (type
);
1102 for (size_t i
= 0; i
< type
.number_of_variants (); ++i
)
1104 TyTy::VariantDef
*a
= base
->get_variants ().at (i
);
1105 TyTy::VariantDef
*b
= type
.get_variants ().at (i
);
1107 if (a
->num_fields () != b
->num_fields ())
1109 BaseCmp::visit (type
);
1113 for (size_t j
= 0; j
< a
->num_fields (); j
++)
1115 TyTy::StructFieldType
*base_field
= a
->get_field_at_index (j
);
1116 TyTy::StructFieldType
*other_field
= b
->get_field_at_index (j
);
1118 TyTy::BaseType
*this_field_ty
= base_field
->get_field_type ();
1119 TyTy::BaseType
*other_field_ty
= other_field
->get_field_type ();
1121 if (!this_field_ty
->can_eq (other_field_ty
, emit_error_flag
))
1123 BaseCmp::visit (type
);
1132 void visit (const InferType
&type
) override
1134 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1136 BaseCmp::visit (type
);
1144 const BaseType
*get_base () const override
{ return base
; }
1145 const ADTType
*base
;
1148 class TupleCmp
: public BaseCmp
1150 using Rust::TyTy::BaseCmp::visit
;
1153 TupleCmp (const TupleType
*base
, bool emit_errors
)
1154 : BaseCmp (base
, emit_errors
), base (base
)
1157 void visit (const TupleType
&type
) override
1159 if (base
->num_fields () != type
.num_fields ())
1161 BaseCmp::visit (type
);
1165 for (size_t i
= 0; i
< base
->num_fields (); i
++)
1167 BaseType
*bo
= base
->get_field (i
);
1168 BaseType
*fo
= type
.get_field (i
);
1170 if (!bo
->can_eq (fo
, emit_error_flag
))
1172 BaseCmp::visit (type
);
1180 void visit (const InferType
&type
) override
1182 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1184 BaseCmp::visit (type
);
1192 const BaseType
*get_base () const override
{ return base
; }
1193 const TupleType
*base
;
1196 class USizeCmp
: public BaseCmp
1198 using Rust::TyTy::BaseCmp::visit
;
1201 USizeCmp (const USizeType
*base
, bool emit_errors
)
1202 : BaseCmp (base
, emit_errors
), base (base
)
1205 void visit (const InferType
&type
) override
1207 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1210 void visit (const USizeType
&type
) override
{ ok
= true; }
1213 const BaseType
*get_base () const override
{ return base
; }
1214 const USizeType
*base
;
1217 class ISizeCmp
: public BaseCmp
1219 using Rust::TyTy::BaseCmp::visit
;
1222 ISizeCmp (const ISizeType
*base
, bool emit_errors
)
1223 : BaseCmp (base
, emit_errors
), base (base
)
1226 void visit (const InferType
&type
) override
1228 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1231 void visit (const ISizeType
&type
) override
{ ok
= true; }
1234 const BaseType
*get_base () const override
{ return base
; }
1235 const ISizeType
*base
;
1238 class CharCmp
: public BaseCmp
1240 using Rust::TyTy::BaseCmp::visit
;
1243 CharCmp (const CharType
*base
, bool emit_errors
)
1244 : BaseCmp (base
, emit_errors
), base (base
)
1247 void visit (const InferType
&type
) override
1249 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
1252 void visit (const CharType
&type
) override
{ ok
= true; }
1255 const BaseType
*get_base () const override
{ return base
; }
1256 const CharType
*base
;
1259 class ReferenceCmp
: public BaseCmp
1261 using Rust::TyTy::BaseCmp::visit
;
1264 ReferenceCmp (const ReferenceType
*base
, bool emit_errors
)
1265 : BaseCmp (base
, emit_errors
), base (base
)
1268 void visit (const ReferenceType
&type
) override
1270 auto base_type
= base
->get_base ();
1271 auto other_base_type
= type
.get_base ();
1273 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1274 if (autoderef_cmp_flag
)
1275 mutability_ok
= base
->mutability () == type
.mutability ();
1279 BaseCmp::visit (type
);
1283 if (!base_type
->can_eq (other_base_type
, emit_error_flag
))
1285 BaseCmp::visit (type
);
1292 void visit (const InferType
&type
) override
1294 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1296 BaseCmp::visit (type
);
1304 const BaseType
*get_base () const override
{ return base
; }
1305 const ReferenceType
*base
;
1308 class PointerCmp
: public BaseCmp
1310 using Rust::TyTy::BaseCmp::visit
;
1313 PointerCmp (const PointerType
*base
, bool emit_errors
)
1314 : BaseCmp (base
, emit_errors
), base (base
)
1317 void visit (const PointerType
&type
) override
1319 auto base_type
= base
->get_base ();
1320 auto other_base_type
= type
.get_base ();
1322 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1323 if (autoderef_cmp_flag
)
1324 mutability_ok
= base
->mutability () == type
.mutability ();
1328 BaseCmp::visit (type
);
1332 if (!base_type
->can_eq (other_base_type
, emit_error_flag
))
1334 BaseCmp::visit (type
);
1341 void visit (const InferType
&type
) override
1343 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1345 BaseCmp::visit (type
);
1353 const BaseType
*get_base () const override
{ return base
; }
1354 const PointerType
*base
;
1357 class ParamCmp
: public BaseCmp
1359 using Rust::TyTy::BaseCmp::visit
;
1362 ParamCmp (const ParamType
*base
, bool emit_errors
)
1363 : BaseCmp (base
, emit_errors
), base (base
)
1366 // param types are a placeholder we shouldn't have cases where we unify
1367 // against it. eg: struct foo<T> { a: T }; When we invoke it we can do either:
1369 // foo<i32>{ a: 123 }.
1370 // Then this enforces the i32 type to be referenced on the
1371 // field via an hirid.
1373 // rust also allows for a = foo{a:123}; Where we can use an Inference Variable
1374 // to handle the typing of the struct
1375 bool can_eq (const BaseType
*other
) override
1377 if (!base
->can_resolve ())
1378 return BaseCmp::can_eq (other
);
1380 auto lookup
= base
->resolve ();
1381 return lookup
->can_eq (other
, emit_error_flag
);
1384 // imagine the case where we have:
1385 // struct Foo<T>(T);
1386 // Then we declare a generic impl block
1387 // impl <X>Foo<X> { ... }
1388 // both of these types are compatible so we mostly care about the number of
1389 // generic arguments
1390 void visit (const ParamType
&) override
{ ok
= true; }
1392 void visit (const TupleType
&) override
{ ok
= true; }
1394 void visit (const InferType
&) override
{ ok
= true; }
1396 void visit (const FnType
&) override
{ ok
= true; }
1398 void visit (const FnPtr
&) override
{ ok
= true; }
1400 void visit (const ADTType
&) override
{ ok
= true; }
1402 void visit (const ArrayType
&) override
{ ok
= true; }
1404 void visit (const SliceType
&) override
{ ok
= !autoderef_cmp_flag
; }
1406 void visit (const BoolType
&) override
{ ok
= true; }
1408 void visit (const IntType
&) override
{ ok
= true; }
1410 void visit (const UintType
&) override
{ ok
= true; }
1412 void visit (const USizeType
&) override
{ ok
= true; }
1414 void visit (const ISizeType
&) override
{ ok
= true; }
1416 void visit (const FloatType
&) override
{ ok
= true; }
1418 void visit (const CharType
&) override
{ ok
= true; }
1420 void visit (const ReferenceType
&) override
{ ok
= true; }
1422 void visit (const PointerType
&) override
{ ok
= true; }
1424 void visit (const StrType
&) override
{ ok
= true; }
1426 void visit (const NeverType
&) override
{ ok
= true; }
1428 void visit (const DynamicObjectType
&) override
{ ok
= true; }
1430 void visit (const PlaceholderType
&type
) override
1432 ok
= base
->get_symbol ().compare (type
.get_symbol ()) == 0;
1436 const BaseType
*get_base () const override
{ return base
; }
1437 const ParamType
*base
;
1440 class StrCmp
: public BaseCmp
1442 // FIXME we will need a enum for the StrType like ByteBuf etc..
1443 using Rust::TyTy::BaseCmp::visit
;
1446 StrCmp (const StrType
*base
, bool emit_errors
)
1447 : BaseCmp (base
, emit_errors
), base (base
)
1450 void visit (const StrType
&type
) override
{ ok
= true; }
1452 void visit (const InferType
&type
) override
1454 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1456 BaseCmp::visit (type
);
1464 const BaseType
*get_base () const override
{ return base
; }
1465 const StrType
*base
;
1468 class NeverCmp
: public BaseCmp
1470 using Rust::TyTy::BaseCmp::visit
;
1473 NeverCmp (const NeverType
*base
, bool emit_errors
)
1474 : BaseCmp (base
, emit_errors
), base (base
)
1477 void visit (const NeverType
&type
) override
{ ok
= true; }
1479 void visit (const InferType
&type
) override
1481 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1483 BaseCmp::visit (type
);
1491 const BaseType
*get_base () const override
{ return base
; }
1492 const NeverType
*base
;
1495 class PlaceholderCmp
: public BaseCmp
1497 using Rust::TyTy::BaseCmp::visit
;
1500 PlaceholderCmp (const PlaceholderType
*base
, bool emit_errors
)
1501 : BaseCmp (base
, emit_errors
), base (base
)
1504 bool can_eq (const BaseType
*other
) override
1506 if (!base
->can_resolve ())
1507 return BaseCmp::can_eq (other
);
1509 BaseType
*lookup
= base
->resolve ();
1510 return lookup
->can_eq (other
, emit_error_flag
);
1513 void visit (const TupleType
&) override
{ ok
= true; }
1515 void visit (const ADTType
&) override
{ ok
= true; }
1517 void visit (const InferType
&) override
{ ok
= true; }
1519 void visit (const FnType
&) override
{ ok
= true; }
1521 void visit (const FnPtr
&) override
{ ok
= true; }
1523 void visit (const ArrayType
&) override
{ ok
= true; }
1525 void visit (const BoolType
&) override
{ ok
= true; }
1527 void visit (const IntType
&) override
{ ok
= true; }
1529 void visit (const UintType
&) override
{ ok
= true; }
1531 void visit (const USizeType
&) override
{ ok
= true; }
1533 void visit (const ISizeType
&) override
{ ok
= true; }
1535 void visit (const FloatType
&) override
{ ok
= true; }
1537 void visit (const ErrorType
&) override
{ ok
= true; }
1539 void visit (const CharType
&) override
{ ok
= true; }
1541 void visit (const ReferenceType
&) override
{ ok
= true; }
1543 void visit (const ParamType
&) override
{ ok
= true; }
1545 void visit (const StrType
&) override
{ ok
= true; }
1547 void visit (const NeverType
&) override
{ ok
= true; }
1549 void visit (const SliceType
&) override
{ ok
= true; }
1552 const BaseType
*get_base () const override
{ return base
; }
1554 const PlaceholderType
*base
;
1557 class DynamicCmp
: public BaseCmp
1559 using Rust::TyTy::BaseCmp::visit
;
1562 DynamicCmp (const DynamicObjectType
*base
, bool emit_errors
)
1563 : BaseCmp (base
, emit_errors
), base (base
)
1566 void visit (const DynamicObjectType
&type
) override
1568 if (base
->num_specified_bounds () != type
.num_specified_bounds ())
1570 BaseCmp::visit (type
);
1574 Location ref_locus
= mappings
->lookup_location (type
.get_ref ());
1575 ok
= base
->bounds_compatible (type
, ref_locus
, false);
1579 const BaseType
*get_base () const override
{ return base
; }
1581 const DynamicObjectType
*base
;
1587 #endif // RUST_TYTY_CMP_H