1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
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 class BaseCmp
: public TyConstVisitor
34 virtual bool can_eq (const BaseType
*other
)
36 if (other
->get_kind () == TypeKind::PARAM
)
38 const ParamType
*p
= static_cast<const ParamType
*> (other
);
39 other
= p
->resolve ();
41 if (other
->get_kind () == TypeKind::PLACEHOLDER
)
43 const PlaceholderType
*p
= static_cast<const PlaceholderType
*> (other
);
44 if (p
->can_resolve ())
46 other
= p
->resolve ();
49 if (other
->get_kind () == TypeKind::PROJECTION
)
51 const ProjectionType
*p
= static_cast<const ProjectionType
*> (other
);
55 other
->accept_vis (*this);
59 virtual void visit (const TupleType
&type
) override
65 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
67 = mappings
->lookup_location (get_base ()->get_ref ());
68 rich_location
r (line_table
, ref_locus
);
69 r
.add_range (base_locus
);
70 rust_error_at (r
, "expected [%s] got [%s]",
71 get_base ()->as_string ().c_str (),
72 type
.as_string ().c_str ());
76 virtual void visit (const ADTType
&type
) override
81 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
83 = mappings
->lookup_location (get_base ()->get_ref ());
84 rich_location
r (line_table
, ref_locus
);
85 r
.add_range (base_locus
);
86 rust_error_at (r
, "expected [%s] got [%s]",
87 get_base ()->as_string ().c_str (),
88 type
.as_string ().c_str ());
92 virtual void visit (const InferType
&type
) override
97 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
99 = mappings
->lookup_location (get_base ()->get_ref ());
100 rich_location
r (line_table
, ref_locus
);
101 r
.add_range (base_locus
);
102 rust_error_at (r
, "expected [%s] got [%s]",
103 get_base ()->as_string ().c_str (),
104 type
.as_string ().c_str ());
108 virtual void visit (const FnType
&type
) override
113 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
114 location_t base_locus
115 = mappings
->lookup_location (get_base ()->get_ref ());
116 rich_location
r (line_table
, ref_locus
);
117 r
.add_range (base_locus
);
118 rust_error_at (r
, "expected [%s] got [%s]",
119 get_base ()->as_string ().c_str (),
120 type
.as_string ().c_str ());
124 virtual void visit (const FnPtr
&type
) override
129 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
130 location_t base_locus
131 = mappings
->lookup_location (get_base ()->get_ref ());
132 rich_location
r (line_table
, ref_locus
);
133 r
.add_range (base_locus
);
134 rust_error_at (r
, "expected [%s] got [%s]",
135 get_base ()->as_string ().c_str (),
136 type
.as_string ().c_str ());
140 virtual void visit (const ArrayType
&type
) override
145 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
146 location_t base_locus
147 = mappings
->lookup_location (get_base ()->get_ref ());
148 rich_location
r (line_table
, ref_locus
);
149 r
.add_range (base_locus
);
150 rust_error_at (r
, "expected [%s] got [%s]",
151 get_base ()->as_string ().c_str (),
152 type
.as_string ().c_str ());
156 virtual void visit (const SliceType
&type
) override
161 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
162 location_t base_locus
163 = mappings
->lookup_location (get_base ()->get_ref ());
164 rich_location
r (line_table
, ref_locus
);
165 r
.add_range (base_locus
);
166 rust_error_at (r
, "expected [%s] got [%s]",
167 get_base ()->as_string ().c_str (),
168 type
.as_string ().c_str ());
172 virtual void visit (const BoolType
&type
) override
177 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
178 location_t base_locus
179 = mappings
->lookup_location (get_base ()->get_ref ());
180 rich_location
r (line_table
, ref_locus
);
181 r
.add_range (base_locus
);
182 rust_error_at (r
, "expected [%s] got [%s]",
183 get_base ()->as_string ().c_str (),
184 type
.as_string ().c_str ());
188 virtual void visit (const IntType
&type
) override
193 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
194 location_t base_locus
195 = mappings
->lookup_location (get_base ()->get_ref ());
196 rich_location
r (line_table
, ref_locus
);
197 r
.add_range (base_locus
);
198 rust_error_at (r
, "expected [%s] got [%s]",
199 get_base ()->as_string ().c_str (),
200 type
.as_string ().c_str ());
204 virtual void visit (const UintType
&type
) override
209 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
210 location_t base_locus
211 = mappings
->lookup_location (get_base ()->get_ref ());
212 rich_location
r (line_table
, ref_locus
);
213 r
.add_range (base_locus
);
214 rust_error_at (r
, "expected [%s] got [%s]",
215 get_base ()->as_string ().c_str (),
216 type
.as_string ().c_str ());
220 virtual void visit (const USizeType
&type
) override
225 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
226 location_t base_locus
227 = mappings
->lookup_location (get_base ()->get_ref ());
228 rich_location
r (line_table
, ref_locus
);
229 r
.add_range (base_locus
);
230 rust_error_at (r
, "expected [%s] got [%s]",
231 get_base ()->as_string ().c_str (),
232 type
.as_string ().c_str ());
236 virtual void visit (const ISizeType
&type
) override
241 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
242 location_t base_locus
243 = mappings
->lookup_location (get_base ()->get_ref ());
244 rich_location
r (line_table
, ref_locus
);
245 r
.add_range (base_locus
);
246 rust_error_at (r
, "expected [%s] got [%s]",
247 get_base ()->as_string ().c_str (),
248 type
.as_string ().c_str ());
252 virtual void visit (const FloatType
&type
) override
257 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
258 location_t base_locus
259 = mappings
->lookup_location (get_base ()->get_ref ());
260 rich_location
r (line_table
, ref_locus
);
261 r
.add_range (base_locus
);
262 rust_error_at (r
, "expected [%s] got [%s]",
263 get_base ()->as_string ().c_str (),
264 type
.as_string ().c_str ());
268 virtual void visit (const ErrorType
&type
) override
273 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
274 location_t base_locus
275 = mappings
->lookup_location (get_base ()->get_ref ());
276 rich_location
r (line_table
, ref_locus
);
277 r
.add_range (base_locus
);
278 rust_error_at (r
, "expected [%s] got [%s]",
279 get_base ()->as_string ().c_str (),
280 type
.as_string ().c_str ());
284 virtual void visit (const CharType
&type
) override
289 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
290 location_t base_locus
291 = mappings
->lookup_location (get_base ()->get_ref ());
292 rich_location
r (line_table
, ref_locus
);
293 r
.add_range (base_locus
);
294 rust_error_at (r
, "expected [%s] got [%s]",
295 get_base ()->as_string ().c_str (),
296 type
.as_string ().c_str ());
300 virtual void visit (const ReferenceType
&type
) override
305 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
306 location_t base_locus
307 = mappings
->lookup_location (get_base ()->get_ref ());
308 rich_location
r (line_table
, ref_locus
);
309 r
.add_range (base_locus
);
310 rust_error_at (r
, "expected [%s] got [%s]",
311 get_base ()->as_string ().c_str (),
312 type
.as_string ().c_str ());
316 virtual void visit (const PointerType
&type
) override
321 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
322 location_t base_locus
323 = mappings
->lookup_location (get_base ()->get_ref ());
324 rich_location
r (line_table
, ref_locus
);
325 r
.add_range (base_locus
);
326 rust_error_at (r
, "expected [%s] got [%s]",
327 get_base ()->as_string ().c_str (),
328 type
.as_string ().c_str ());
332 virtual void visit (const StrType
&type
) override
337 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
338 location_t base_locus
339 = mappings
->lookup_location (get_base ()->get_ref ());
340 rich_location
r (line_table
, ref_locus
);
341 r
.add_range (base_locus
);
342 rust_error_at (r
, "expected [%s] got [%s]",
343 get_base ()->as_string ().c_str (),
344 type
.as_string ().c_str ());
348 virtual void visit (const NeverType
&type
) override
353 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
354 location_t base_locus
355 = mappings
->lookup_location (get_base ()->get_ref ());
356 rich_location
r (line_table
, ref_locus
);
357 r
.add_range (base_locus
);
358 rust_error_at (r
, "expected [%s] got [%s]",
359 get_base ()->as_string ().c_str (),
360 type
.as_string ().c_str ());
364 virtual void visit (const ProjectionType
&type
) override
369 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
370 location_t base_locus
371 = mappings
->lookup_location (get_base ()->get_ref ());
372 rich_location
r (line_table
, ref_locus
);
373 r
.add_range (base_locus
);
374 rust_error_at (r
, "expected [%s] got [%s]",
375 get_base ()->as_string ().c_str (),
376 type
.as_string ().c_str ());
380 virtual void visit (const PlaceholderType
&type
) override
382 // it is ok for types to can eq to a placeholder
386 virtual void visit (const ParamType
&type
) override
391 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
392 location_t base_locus
393 = mappings
->lookup_location (get_base ()->get_ref ());
394 rich_location
r (line_table
, ref_locus
);
395 r
.add_range (base_locus
);
396 rust_error_at (r
, "expected [%s] got [%s]",
397 get_base ()->as_string ().c_str (),
398 type
.as_string ().c_str ());
402 virtual void visit (const DynamicObjectType
&type
) override
407 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
408 location_t base_locus
409 = mappings
->lookup_location (get_base ()->get_ref ());
410 rich_location
r (line_table
, ref_locus
);
411 r
.add_range (base_locus
);
412 rust_error_at (r
, "expected [%s] got [%s]",
413 get_base ()->as_string ().c_str (),
414 type
.as_string ().c_str ());
418 virtual void visit (const ClosureType
&type
) override
423 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
424 location_t base_locus
425 = mappings
->lookup_location (get_base ()->get_ref ());
426 rich_location
r (line_table
, ref_locus
);
427 r
.add_range (base_locus
);
428 rust_error_at (r
, "expected [%s] got [%s]",
429 get_base ()->as_string ().c_str (),
430 type
.as_string ().c_str ());
435 BaseCmp (const BaseType
*base
, bool emit_errors
)
436 : mappings (Analysis::Mappings::get ()),
437 context (Resolver::TypeCheckContext::get ()), ok (false),
438 emit_error_flag (emit_errors
)
441 Analysis::Mappings
*mappings
;
442 Resolver::TypeCheckContext
*context
;
445 bool emit_error_flag
;
448 /* Returns a pointer to the ty that created this rule. */
449 virtual const BaseType
*get_base () const = 0;
452 class InferCmp
: public BaseCmp
454 using Rust::TyTy::BaseCmp::visit
;
457 InferCmp (const InferType
*base
, bool emit_errors
)
458 : BaseCmp (base
, emit_errors
), base (base
)
461 void visit (const BoolType
&type
) override
464 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
471 BaseCmp::visit (type
);
474 void visit (const IntType
&type
) override
477 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
478 || (base
->get_infer_kind ()
479 == TyTy::InferType::InferTypeKind::INTEGRAL
);
486 BaseCmp::visit (type
);
489 void visit (const UintType
&type
) override
492 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
493 || (base
->get_infer_kind ()
494 == TyTy::InferType::InferTypeKind::INTEGRAL
);
501 BaseCmp::visit (type
);
504 void visit (const USizeType
&type
) override
507 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
508 || (base
->get_infer_kind ()
509 == TyTy::InferType::InferTypeKind::INTEGRAL
);
516 BaseCmp::visit (type
);
519 void visit (const ISizeType
&type
) override
522 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
523 || (base
->get_infer_kind ()
524 == TyTy::InferType::InferTypeKind::INTEGRAL
);
531 BaseCmp::visit (type
);
534 void visit (const FloatType
&type
) override
537 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
)
538 || (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
);
545 BaseCmp::visit (type
);
548 void visit (const ArrayType
&type
) override
551 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
558 BaseCmp::visit (type
);
561 void visit (const SliceType
&type
) override
564 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
571 BaseCmp::visit (type
);
574 void visit (const ADTType
&type
) override
577 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
584 BaseCmp::visit (type
);
587 void visit (const TupleType
&type
) override
590 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
597 BaseCmp::visit (type
);
600 void visit (const InferType
&type
) override
602 switch (base
->get_infer_kind ())
604 case InferType::InferTypeKind::GENERAL
:
608 case InferType::InferTypeKind::INTEGRAL
: {
609 if (type
.get_infer_kind () == InferType::InferTypeKind::INTEGRAL
)
614 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
622 case InferType::InferTypeKind::FLOAT
: {
623 if (type
.get_infer_kind () == InferType::InferTypeKind::FLOAT
)
628 else if (type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
)
637 BaseCmp::visit (type
);
640 void visit (const CharType
&type
) override
644 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
651 BaseCmp::visit (type
);
655 void visit (const ReferenceType
&type
) override
658 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
665 BaseCmp::visit (type
);
668 void visit (const PointerType
&type
) override
671 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
678 BaseCmp::visit (type
);
681 void visit (const ParamType
&) override
{ ok
= true; }
683 void visit (const DynamicObjectType
&type
) override
686 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
693 BaseCmp::visit (type
);
696 void visit (const ClosureType
&type
) override
699 = (base
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
);
706 BaseCmp::visit (type
);
710 const BaseType
*get_base () const override
{ return base
; }
711 const InferType
*base
;
714 class FnCmp
: public BaseCmp
716 using Rust::TyTy::BaseCmp::visit
;
719 FnCmp (const FnType
*base
, bool emit_errors
)
720 : BaseCmp (base
, emit_errors
), base (base
)
723 void visit (const InferType
&type
) override
725 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
728 void visit (const FnType
&type
) override
730 if (base
->num_params () != type
.num_params ())
732 BaseCmp::visit (type
);
736 for (size_t i
= 0; i
< base
->num_params (); i
++)
738 auto a
= base
->param_at (i
).second
;
739 auto b
= type
.param_at (i
).second
;
741 if (!a
->can_eq (b
, emit_error_flag
))
743 emit_error_flag
= false;
744 BaseCmp::visit (type
);
749 if (!base
->get_return_type ()->can_eq (type
.get_return_type (),
752 emit_error_flag
= false;
753 BaseCmp::visit (type
);
761 const BaseType
*get_base () const override
{ return base
; }
765 class FnptrCmp
: public BaseCmp
767 using Rust::TyTy::BaseCmp::visit
;
770 FnptrCmp (const FnPtr
*base
, bool emit_errors
)
771 : BaseCmp (base
, emit_errors
), base (base
)
774 void visit (const InferType
&type
) override
776 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
778 BaseCmp::visit (type
);
785 void visit (const FnPtr
&type
) override
787 if (base
->num_params () != type
.num_params ())
789 BaseCmp::visit (type
);
793 auto this_ret_type
= base
->get_return_type ();
794 auto other_ret_type
= type
.get_return_type ();
795 if (!this_ret_type
->can_eq (other_ret_type
, emit_error_flag
))
797 BaseCmp::visit (type
);
801 for (size_t i
= 0; i
< base
->num_params (); i
++)
803 auto this_param
= base
->get_param_type_at (i
);
804 auto other_param
= type
.get_param_type_at (i
);
805 if (!this_param
->can_eq (other_param
, emit_error_flag
))
807 BaseCmp::visit (type
);
815 void visit (const FnType
&type
) override
817 if (base
->num_params () != type
.num_params ())
819 BaseCmp::visit (type
);
823 auto this_ret_type
= base
->get_return_type ();
824 auto other_ret_type
= type
.get_return_type ();
825 if (!this_ret_type
->can_eq (other_ret_type
, emit_error_flag
))
827 BaseCmp::visit (type
);
831 for (size_t i
= 0; i
< base
->num_params (); i
++)
833 auto this_param
= base
->get_param_type_at (i
);
834 auto other_param
= type
.param_at (i
).second
;
835 if (!this_param
->can_eq (other_param
, emit_error_flag
))
837 BaseCmp::visit (type
);
846 const BaseType
*get_base () const override
{ return base
; }
850 class ClosureCmp
: public BaseCmp
852 using Rust::TyTy::BaseCmp::visit
;
855 ClosureCmp (const ClosureType
*base
, bool emit_errors
)
856 : BaseCmp (base
, emit_errors
), base (base
)
859 void visit (const InferType
&type
) override
861 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
863 BaseCmp::visit (type
);
870 void visit (const ClosureType
&type
) override
872 if (base
->get_def_id () != type
.get_def_id ())
874 BaseCmp::visit (type
);
878 if (!base
->get_parameters ().can_eq (&type
.get_parameters (), false))
880 BaseCmp::visit (type
);
884 if (!base
->get_result_type ().can_eq (&type
.get_result_type (), false))
886 BaseCmp::visit (type
);
894 const BaseType
*get_base () const override
{ return base
; }
895 const ClosureType
*base
;
898 class ArrayCmp
: public BaseCmp
900 using Rust::TyTy::BaseCmp::visit
;
903 ArrayCmp (const ArrayType
*base
, bool emit_errors
)
904 : BaseCmp (base
, emit_errors
), base (base
)
907 void visit (const ArrayType
&type
) override
910 const BaseType
*base_element
= base
->get_element_type ();
911 const BaseType
*other_element
= type
.get_element_type ();
912 if (!base_element
->can_eq (other_element
, emit_error_flag
))
914 BaseCmp::visit (type
);
921 void visit (const InferType
&type
) override
923 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
925 BaseCmp::visit (type
);
933 const BaseType
*get_base () const override
{ return base
; }
934 const ArrayType
*base
;
937 class SliceCmp
: public BaseCmp
939 using Rust::TyTy::BaseCmp::visit
;
942 SliceCmp (const SliceType
*base
, bool emit_errors
)
943 : BaseCmp (base
, emit_errors
), base (base
)
946 void visit (const SliceType
&type
) override
949 const BaseType
*base_element
= base
->get_element_type ();
950 const BaseType
*other_element
= type
.get_element_type ();
951 if (!base_element
->can_eq (other_element
, emit_error_flag
))
953 BaseCmp::visit (type
);
960 void visit (const InferType
&type
) override
962 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
964 BaseCmp::visit (type
);
972 const BaseType
*get_base () const override
{ return base
; }
973 const SliceType
*base
;
976 class BoolCmp
: public BaseCmp
978 using Rust::TyTy::BaseCmp::visit
;
981 BoolCmp (const BoolType
*base
, bool emit_errors
)
982 : BaseCmp (base
, emit_errors
), base (base
)
985 void visit (const BoolType
&type
) override
{ ok
= true; }
987 void visit (const InferType
&type
) override
989 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
993 const BaseType
*get_base () const override
{ return base
; }
994 const BoolType
*base
;
997 class IntCmp
: public BaseCmp
999 using Rust::TyTy::BaseCmp::visit
;
1002 IntCmp (const IntType
*base
, bool emit_errors
)
1003 : BaseCmp (base
, emit_errors
), base (base
)
1006 void visit (const InferType
&type
) override
1008 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1011 void visit (const IntType
&type
) override
1013 ok
= type
.get_int_kind () == base
->get_int_kind ();
1017 const BaseType
*get_base () const override
{ return base
; }
1018 const IntType
*base
;
1021 class UintCmp
: public BaseCmp
1023 using Rust::TyTy::BaseCmp::visit
;
1026 UintCmp (const UintType
*base
, bool emit_errors
)
1027 : BaseCmp (base
, emit_errors
), base (base
)
1030 void visit (const InferType
&type
) override
1032 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1035 void visit (const UintType
&type
) override
1037 ok
= type
.get_uint_kind () == base
->get_uint_kind ();
1041 const BaseType
*get_base () const override
{ return base
; }
1042 const UintType
*base
;
1045 class FloatCmp
: public BaseCmp
1047 using Rust::TyTy::BaseCmp::visit
;
1050 FloatCmp (const FloatType
*base
, bool emit_errors
)
1051 : BaseCmp (base
, emit_errors
), base (base
)
1054 void visit (const InferType
&type
) override
1056 ok
= type
.get_infer_kind () != InferType::InferTypeKind::INTEGRAL
;
1059 void visit (const FloatType
&type
) override
1061 ok
= type
.get_float_kind () == base
->get_float_kind ();
1065 const BaseType
*get_base () const override
{ return base
; }
1066 const FloatType
*base
;
1069 class ADTCmp
: public BaseCmp
1071 using Rust::TyTy::BaseCmp::visit
;
1074 ADTCmp (const ADTType
*base
, bool emit_errors
)
1075 : BaseCmp (base
, emit_errors
), base (base
)
1078 void visit (const ADTType
&type
) override
1080 if (base
->get_adt_kind () != type
.get_adt_kind ())
1082 BaseCmp::visit (type
);
1086 if (base
->get_identifier ().compare (type
.get_identifier ()) != 0)
1088 BaseCmp::visit (type
);
1092 if (base
->number_of_variants () != type
.number_of_variants ())
1094 BaseCmp::visit (type
);
1098 for (size_t i
= 0; i
< type
.number_of_variants (); ++i
)
1100 TyTy::VariantDef
*a
= base
->get_variants ().at (i
);
1101 TyTy::VariantDef
*b
= type
.get_variants ().at (i
);
1103 if (a
->num_fields () != b
->num_fields ())
1105 BaseCmp::visit (type
);
1109 for (size_t j
= 0; j
< a
->num_fields (); j
++)
1111 TyTy::StructFieldType
*base_field
= a
->get_field_at_index (j
);
1112 TyTy::StructFieldType
*other_field
= b
->get_field_at_index (j
);
1114 TyTy::BaseType
*this_field_ty
= base_field
->get_field_type ();
1115 TyTy::BaseType
*other_field_ty
= other_field
->get_field_type ();
1117 if (!this_field_ty
->can_eq (other_field_ty
, emit_error_flag
))
1119 BaseCmp::visit (type
);
1128 void visit (const InferType
&type
) override
1130 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1132 BaseCmp::visit (type
);
1140 const BaseType
*get_base () const override
{ return base
; }
1141 const ADTType
*base
;
1144 class TupleCmp
: public BaseCmp
1146 using Rust::TyTy::BaseCmp::visit
;
1149 TupleCmp (const TupleType
*base
, bool emit_errors
)
1150 : BaseCmp (base
, emit_errors
), base (base
)
1153 void visit (const TupleType
&type
) override
1155 if (base
->num_fields () != type
.num_fields ())
1157 BaseCmp::visit (type
);
1161 for (size_t i
= 0; i
< base
->num_fields (); i
++)
1163 BaseType
*bo
= base
->get_field (i
);
1164 BaseType
*fo
= type
.get_field (i
);
1166 if (!bo
->can_eq (fo
, emit_error_flag
))
1168 BaseCmp::visit (type
);
1176 void visit (const InferType
&type
) override
1178 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1180 BaseCmp::visit (type
);
1188 const BaseType
*get_base () const override
{ return base
; }
1189 const TupleType
*base
;
1192 class USizeCmp
: public BaseCmp
1194 using Rust::TyTy::BaseCmp::visit
;
1197 USizeCmp (const USizeType
*base
, bool emit_errors
)
1198 : BaseCmp (base
, emit_errors
), base (base
)
1201 void visit (const InferType
&type
) override
1203 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1206 void visit (const USizeType
&type
) override
{ ok
= true; }
1209 const BaseType
*get_base () const override
{ return base
; }
1210 const USizeType
*base
;
1213 class ISizeCmp
: public BaseCmp
1215 using Rust::TyTy::BaseCmp::visit
;
1218 ISizeCmp (const ISizeType
*base
, bool emit_errors
)
1219 : BaseCmp (base
, emit_errors
), base (base
)
1222 void visit (const InferType
&type
) override
1224 ok
= type
.get_infer_kind () != InferType::InferTypeKind::FLOAT
;
1227 void visit (const ISizeType
&type
) override
{ ok
= true; }
1230 const BaseType
*get_base () const override
{ return base
; }
1231 const ISizeType
*base
;
1234 class CharCmp
: public BaseCmp
1236 using Rust::TyTy::BaseCmp::visit
;
1239 CharCmp (const CharType
*base
, bool emit_errors
)
1240 : BaseCmp (base
, emit_errors
), base (base
)
1243 void visit (const InferType
&type
) override
1245 ok
= type
.get_infer_kind () == InferType::InferTypeKind::GENERAL
;
1248 void visit (const CharType
&type
) override
{ ok
= true; }
1251 const BaseType
*get_base () const override
{ return base
; }
1252 const CharType
*base
;
1255 class ReferenceCmp
: public BaseCmp
1257 using Rust::TyTy::BaseCmp::visit
;
1260 ReferenceCmp (const ReferenceType
*base
, bool emit_errors
)
1261 : BaseCmp (base
, emit_errors
), base (base
)
1264 void visit (const ReferenceType
&type
) override
1266 auto base_type
= base
->get_base ();
1267 auto other_base_type
= type
.get_base ();
1269 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1272 BaseCmp::visit (type
);
1276 if (!base_type
->can_eq (other_base_type
, emit_error_flag
))
1278 BaseCmp::visit (type
);
1285 void visit (const InferType
&type
) override
1287 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1289 BaseCmp::visit (type
);
1297 const BaseType
*get_base () const override
{ return base
; }
1298 const ReferenceType
*base
;
1301 class PointerCmp
: public BaseCmp
1303 using Rust::TyTy::BaseCmp::visit
;
1306 PointerCmp (const PointerType
*base
, bool emit_errors
)
1307 : BaseCmp (base
, emit_errors
), base (base
)
1310 void visit (const PointerType
&type
) override
1312 auto base_type
= base
->get_base ();
1313 auto other_base_type
= type
.get_base ();
1315 bool mutability_ok
= base
->is_mutable () ? type
.is_mutable () : true;
1318 BaseCmp::visit (type
);
1322 if (!base_type
->can_eq (other_base_type
, emit_error_flag
))
1324 BaseCmp::visit (type
);
1331 void visit (const InferType
&type
) override
1333 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1335 BaseCmp::visit (type
);
1343 const BaseType
*get_base () const override
{ return base
; }
1344 const PointerType
*base
;
1347 class ParamCmp
: public BaseCmp
1349 using Rust::TyTy::BaseCmp::visit
;
1352 ParamCmp (const ParamType
*base
, bool emit_errors
)
1353 : BaseCmp (base
, emit_errors
), base (base
)
1356 // param types are a placeholder we shouldn't have cases where we unify
1357 // against it. eg: struct foo<T> { a: T }; When we invoke it we can do either:
1359 // foo<i32>{ a: 123 }.
1360 // Then this enforces the i32 type to be referenced on the
1361 // field via an hirid.
1363 // rust also allows for a = foo{a:123}; Where we can use an Inference Variable
1364 // to handle the typing of the struct
1365 bool can_eq (const BaseType
*other
) override
1367 if (!base
->can_resolve ())
1368 return BaseCmp::can_eq (other
);
1370 auto lookup
= base
->resolve ();
1371 return lookup
->can_eq (other
, emit_error_flag
);
1374 // imagine the case where we have:
1375 // struct Foo<T>(T);
1376 // Then we declare a generic impl block
1377 // impl <X>Foo<X> { ... }
1378 // both of these types are compatible so we mostly care about the number of
1379 // generic arguments
1380 void visit (const ParamType
&) override
{ ok
= true; }
1382 void visit (const TupleType
&) override
{ ok
= true; }
1384 void visit (const InferType
&) override
{ ok
= true; }
1386 void visit (const FnType
&) override
{ ok
= true; }
1388 void visit (const FnPtr
&) override
{ ok
= true; }
1390 void visit (const ADTType
&) override
{ ok
= true; }
1392 void visit (const ArrayType
&) override
{ ok
= true; }
1394 void visit (const SliceType
&) override
{ ok
= true; }
1396 void visit (const BoolType
&) override
{ ok
= true; }
1398 void visit (const IntType
&) override
{ ok
= true; }
1400 void visit (const UintType
&) override
{ ok
= true; }
1402 void visit (const USizeType
&) override
{ ok
= true; }
1404 void visit (const ISizeType
&) override
{ ok
= true; }
1406 void visit (const FloatType
&) override
{ ok
= true; }
1408 void visit (const CharType
&) override
{ ok
= true; }
1410 void visit (const ReferenceType
&) override
{ ok
= true; }
1412 void visit (const PointerType
&) override
{ ok
= true; }
1414 void visit (const StrType
&) override
{ ok
= true; }
1416 void visit (const NeverType
&) override
{ ok
= true; }
1418 void visit (const DynamicObjectType
&) override
{ ok
= true; }
1420 void visit (const PlaceholderType
&type
) override
1422 ok
= base
->get_symbol ().compare (type
.get_symbol ()) == 0;
1426 const BaseType
*get_base () const override
{ return base
; }
1427 const ParamType
*base
;
1430 class StrCmp
: public BaseCmp
1432 // FIXME we will need a enum for the StrType like ByteBuf etc..
1433 using Rust::TyTy::BaseCmp::visit
;
1436 StrCmp (const StrType
*base
, bool emit_errors
)
1437 : BaseCmp (base
, emit_errors
), base (base
)
1440 void visit (const StrType
&type
) override
{ ok
= true; }
1442 void visit (const InferType
&type
) override
1444 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1446 BaseCmp::visit (type
);
1454 const BaseType
*get_base () const override
{ return base
; }
1455 const StrType
*base
;
1458 class NeverCmp
: public BaseCmp
1460 using Rust::TyTy::BaseCmp::visit
;
1463 NeverCmp (const NeverType
*base
, bool emit_errors
)
1464 : BaseCmp (base
, emit_errors
), base (base
)
1467 void visit (const NeverType
&type
) override
{ ok
= true; }
1469 void visit (const InferType
&type
) override
1471 if (type
.get_infer_kind () != InferType::InferTypeKind::GENERAL
)
1473 BaseCmp::visit (type
);
1481 const BaseType
*get_base () const override
{ return base
; }
1482 const NeverType
*base
;
1485 class PlaceholderCmp
: public BaseCmp
1487 using Rust::TyTy::BaseCmp::visit
;
1490 PlaceholderCmp (const PlaceholderType
*base
, bool emit_errors
)
1491 : BaseCmp (base
, emit_errors
), base (base
)
1494 bool can_eq (const BaseType
*other
) override
1496 if (!base
->can_resolve ())
1497 return BaseCmp::can_eq (other
);
1499 BaseType
*lookup
= base
->resolve ();
1500 return lookup
->can_eq (other
, emit_error_flag
);
1503 void visit (const TupleType
&) override
{ ok
= true; }
1505 void visit (const ADTType
&) override
{ ok
= true; }
1507 void visit (const InferType
&) override
{ ok
= true; }
1509 void visit (const FnType
&) override
{ ok
= true; }
1511 void visit (const FnPtr
&) override
{ ok
= true; }
1513 void visit (const ArrayType
&) override
{ ok
= true; }
1515 void visit (const BoolType
&) override
{ ok
= true; }
1517 void visit (const IntType
&) override
{ ok
= true; }
1519 void visit (const UintType
&) override
{ ok
= true; }
1521 void visit (const USizeType
&) override
{ ok
= true; }
1523 void visit (const ISizeType
&) override
{ ok
= true; }
1525 void visit (const FloatType
&) override
{ ok
= true; }
1527 void visit (const ErrorType
&) override
{ ok
= true; }
1529 void visit (const CharType
&) override
{ ok
= true; }
1531 void visit (const ReferenceType
&) override
{ ok
= true; }
1533 void visit (const ParamType
&) override
{ ok
= true; }
1535 void visit (const StrType
&) override
{ ok
= true; }
1537 void visit (const NeverType
&) override
{ ok
= true; }
1539 void visit (const SliceType
&) override
{ ok
= true; }
1542 const BaseType
*get_base () const override
{ return base
; }
1544 const PlaceholderType
*base
;
1547 class DynamicCmp
: public BaseCmp
1549 using Rust::TyTy::BaseCmp::visit
;
1552 DynamicCmp (const DynamicObjectType
*base
, bool emit_errors
)
1553 : BaseCmp (base
, emit_errors
), base (base
)
1556 void visit (const DynamicObjectType
&type
) override
1558 if (base
->num_specified_bounds () != type
.num_specified_bounds ())
1560 BaseCmp::visit (type
);
1564 location_t ref_locus
= mappings
->lookup_location (type
.get_ref ());
1565 ok
= base
->bounds_compatible (type
, ref_locus
, false);
1569 const BaseType
*get_base () const override
{ return base
; }
1571 const DynamicObjectType
*base
;
1577 #endif // RUST_TYTY_CMP_H