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 #include "rust-unify.h"
20 #include "rust-tyty.h"
25 UnifyRules::UnifyRules (TyTy::TyWithLocation lhs
, TyTy::TyWithLocation rhs
,
26 location_t locus
, bool commit_flag
, bool emit_error
,
27 bool infer
, std::vector
<CommitSite
> &commits
,
28 std::vector
<InferenceSite
> &infers
)
29 : lhs (lhs
), rhs (rhs
), locus (locus
), commit_flag (commit_flag
),
30 emit_error (emit_error
), infer_flag (infer
), commits (commits
),
31 infers (infers
), mappings (*Analysis::Mappings::get ()),
32 context (*TypeCheckContext::get ())
36 UnifyRules::Resolve (TyTy::TyWithLocation lhs
, TyTy::TyWithLocation rhs
,
37 location_t locus
, bool commit_flag
, bool emit_error
,
38 bool infer
, std::vector
<CommitSite
> &commits
,
39 std::vector
<InferenceSite
> &infers
)
41 UnifyRules
r (lhs
, rhs
, locus
, commit_flag
, emit_error
, infer
, commits
,
44 TyTy::BaseType
*result
= r
.go ();
45 commits
.push_back ({lhs
.get_ty (), rhs
.get_ty (), result
});
47 UnifyRules::commit (lhs
.get_ty (), rhs
.get_ty (), result
);
49 bool failed
= result
->get_kind () == TyTy::TypeKind::ERROR
;
50 if (failed
&& r
.emit_error
)
51 r
.emit_type_mismatch ();
57 UnifyRules::get_base ()
59 return lhs
.get_ty ()->destructure ();
63 UnifyRules::get_other ()
65 return rhs
.get_ty ()->destructure ();
69 UnifyRules::commit (TyTy::BaseType
*base
, TyTy::BaseType
*other
,
70 TyTy::BaseType
*resolved
)
72 TypeCheckContext
&context
= *TypeCheckContext::get ();
73 Analysis::Mappings
&mappings
= *Analysis::Mappings::get ();
75 TyTy::BaseType
*b
= base
->destructure ();
76 TyTy::BaseType
*o
= other
->destructure ();
78 resolved
->append_reference (b
->get_ref ());
79 resolved
->append_reference (o
->get_ref ());
80 for (auto ref
: b
->get_combined_refs ())
81 resolved
->append_reference (ref
);
82 for (auto ref
: o
->get_combined_refs ())
83 resolved
->append_reference (ref
);
85 o
->append_reference (resolved
->get_ref ());
86 o
->append_reference (b
->get_ref ());
87 b
->append_reference (resolved
->get_ref ());
88 b
->append_reference (o
->get_ref ());
90 bool result_resolved
= resolved
->get_kind () != TyTy::TypeKind::INFER
;
91 bool result_is_infer_var
= resolved
->get_kind () == TyTy::TypeKind::INFER
;
92 bool results_is_non_general_infer_var
93 = (result_is_infer_var
94 && (static_cast<TyTy::InferType
*> (resolved
))->get_infer_kind ()
95 != TyTy::InferType::GENERAL
);
96 if (result_resolved
|| results_is_non_general_infer_var
)
98 for (auto &ref
: resolved
->get_combined_refs ())
100 TyTy::BaseType
*ref_tyty
= nullptr;
101 bool ok
= context
.lookup_type (ref
, &ref_tyty
);
105 // if any of the types are inference variables lets fix them
106 if (ref_tyty
->get_kind () == TyTy::TypeKind::INFER
)
108 auto node
= Analysis::NodeMapping (mappings
.get_current_crate (),
110 UNKNOWN_LOCAL_DEFID
);
111 context
.insert_type (node
, resolved
->clone ());
118 UnifyRules::emit_type_mismatch () const
120 TyTy::BaseType
*expected
= lhs
.get_ty ();
121 TyTy::BaseType
*expr
= rhs
.get_ty ();
123 rich_location
r (line_table
, locus
);
124 r
.add_range (lhs
.get_locus ());
125 r
.add_range (rhs
.get_locus ());
126 rust_error_at (r
, ErrorCode::E0308
,
127 "mismatched types, expected %qs but got %qs",
128 expected
->get_name ().c_str (), expr
->get_name ().c_str ());
132 UnifyRules::emit_abi_mismatch (const TyTy::FnType
&expected
,
133 const TyTy::FnType
&got
) const
135 rich_location
r (line_table
, locus
);
136 r
.add_range (lhs
.get_locus ());
137 r
.add_range (rhs
.get_locus ());
138 rust_error_at (r
, "mistached abi %qs got %qs",
139 get_string_from_abi (expected
.get_abi ()).c_str (),
140 get_string_from_abi (got
.get_abi ()).c_str ());
146 TyTy::BaseType
*ltype
= lhs
.get_ty ();
147 TyTy::BaseType
*rtype
= rhs
.get_ty ();
149 ltype
= lhs
.get_ty ()->destructure ();
150 rtype
= rhs
.get_ty ()->destructure ();
152 rust_debug ("unify::go ltype={%s} rtype={%s}", ltype
->debug_str ().c_str (),
153 rtype
->debug_str ().c_str ());
156 bool ltype_is_placeholder
= ltype
->get_kind () == TyTy::TypeKind::PLACEHOLDER
;
157 bool rtype_is_placeholder
= rtype
->get_kind () == TyTy::TypeKind::PLACEHOLDER
;
158 bool types_equal
= ltype
->is_equal (*rtype
);
159 bool should_check_bounds
160 = !types_equal
&& !(ltype_is_placeholder
|| rtype_is_placeholder
);
161 if (should_check_bounds
)
163 if (ltype
->num_specified_bounds () > 0)
165 if (!ltype
->bounds_compatible (*rtype
, locus
, emit_error
))
167 // already emitted an error
169 return new TyTy::ErrorType (0);
172 else if (rtype
->num_specified_bounds () > 0)
174 if (!rtype
->bounds_compatible (*ltype
, locus
, emit_error
))
176 // already emitted an error
178 return new TyTy::ErrorType (0);
185 bool rgot_param
= rtype
->get_kind () == TyTy::TypeKind::PARAM
;
186 bool lhs_is_infer_var
= ltype
->get_kind () == TyTy::TypeKind::INFER
;
187 bool lhs_is_general_infer_var
189 && static_cast<TyTy::InferType
*> (ltype
)->get_infer_kind ()
190 == TyTy::InferType::GENERAL
;
191 bool expected_is_concrete
192 = ltype
->is_concrete () && !lhs_is_general_infer_var
;
193 bool rneeds_infer
= expected_is_concrete
&& rgot_param
;
195 bool lgot_param
= ltype
->get_kind () == TyTy::TypeKind::PARAM
;
196 bool rhs_is_infer_var
= rtype
->get_kind () == TyTy::TypeKind::INFER
;
197 bool rhs_is_general_infer_var
199 && static_cast<TyTy::InferType
*> (rtype
)->get_infer_kind ()
200 == TyTy::InferType::GENERAL
;
201 bool receiver_is_concrete
202 = rtype
->is_concrete () && !rhs_is_general_infer_var
;
203 bool lneeds_infer
= receiver_is_concrete
&& lgot_param
;
207 TyTy::ParamType
*p
= static_cast<TyTy::ParamType
*> (rtype
);
209 = TyTy::TyVar::get_implicit_infer_var (rhs
.get_locus ());
210 rust_assert (iv
.get_tyty ()->get_kind () == TyTy::TypeKind::INFER
);
211 TyTy::InferType
*i
= static_cast<TyTy::InferType
*> (iv
.get_tyty ());
213 infers
.push_back ({p
->get_ref (), p
->get_ty_ref (), p
, i
});
216 // this is hacky to set the implicit param lets make this a function
217 p
->set_ty_ref (i
->get_ref ());
219 // set the rtype now to the new inference var
222 else if (lneeds_infer
)
224 TyTy::ParamType
*p
= static_cast<TyTy::ParamType
*> (ltype
);
226 = TyTy::TyVar::get_implicit_infer_var (lhs
.get_locus ());
227 rust_assert (iv
.get_tyty ()->get_kind () == TyTy::TypeKind::INFER
);
228 TyTy::InferType
*i
= static_cast<TyTy::InferType
*> (iv
.get_tyty ());
230 infers
.push_back ({p
->get_ref (), p
->get_ty_ref (), p
, i
});
233 // this is hacky to set the implicit param lets make this a function
234 p
->set_ty_ref (i
->get_ref ());
236 // set the rtype now to the new inference var
241 // The never type should always get coerced to the type it's being matched
242 // against, so in that case, ltype. This avoids doing the same check in all
243 // the `expect_*` functions.
244 // However, this does not work if we have an annoying ltype - like INFER.
245 // TODO: Is ltype == Infer the only special case here? What about projections?
247 if (rtype
->get_kind () == TyTy::NEVER
&& ltype
->get_kind () != TyTy::INFER
)
248 return ltype
->clone ();
250 switch (ltype
->get_kind ())
253 return expect_inference_variable (static_cast<TyTy::InferType
*> (ltype
),
257 return expect_adt (static_cast<TyTy::ADTType
*> (ltype
), rtype
);
260 return expect_str (static_cast<TyTy::StrType
*> (ltype
), rtype
);
263 return expect_reference (static_cast<TyTy::ReferenceType
*> (ltype
),
267 return expect_pointer (static_cast<TyTy::PointerType
*> (ltype
), rtype
);
270 return expect_param (static_cast<TyTy::ParamType
*> (ltype
), rtype
);
273 return expect_array (static_cast<TyTy::ArrayType
*> (ltype
), rtype
);
276 return expect_slice (static_cast<TyTy::SliceType
*> (ltype
), rtype
);
279 return expect_fndef (static_cast<TyTy::FnType
*> (ltype
), rtype
);
282 return expect_fnptr (static_cast<TyTy::FnPtr
*> (ltype
), rtype
);
285 return expect_tuple (static_cast<TyTy::TupleType
*> (ltype
), rtype
);
288 return expect_bool (static_cast<TyTy::BoolType
*> (ltype
), rtype
);
291 return expect_char (static_cast<TyTy::CharType
*> (ltype
), rtype
);
294 return expect_int (static_cast<TyTy::IntType
*> (ltype
), rtype
);
297 return expect_uint (static_cast<TyTy::UintType
*> (ltype
), rtype
);
300 return expect_float (static_cast<TyTy::FloatType
*> (ltype
), rtype
);
303 return expect_usize (static_cast<TyTy::USizeType
*> (ltype
), rtype
);
306 return expect_isize (static_cast<TyTy::ISizeType
*> (ltype
), rtype
);
309 return expect_never (static_cast<TyTy::NeverType
*> (ltype
), rtype
);
311 case TyTy::PLACEHOLDER
:
312 return expect_placeholder (static_cast<TyTy::PlaceholderType
*> (ltype
),
315 case TyTy::PROJECTION
:
316 return expect_projection (static_cast<TyTy::ProjectionType
*> (ltype
),
320 return expect_dyn (static_cast<TyTy::DynamicObjectType
*> (ltype
), rtype
);
323 return expect_closure (static_cast<TyTy::ClosureType
*> (ltype
), rtype
);
326 return new TyTy::ErrorType (0);
329 return new TyTy::ErrorType (0);
333 UnifyRules::expect_inference_variable (TyTy::InferType
*ltype
,
334 TyTy::BaseType
*rtype
)
336 switch (rtype
->get_kind ())
339 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
340 switch (ltype
->get_infer_kind ())
342 case TyTy::InferType::InferTypeKind::GENERAL
:
343 return rtype
->clone ();
345 case TyTy::InferType::InferTypeKind::INTEGRAL
: {
346 bool is_valid
= r
->get_infer_kind ()
347 == TyTy::InferType::InferTypeKind::INTEGRAL
348 || r
->get_infer_kind ()
349 == TyTy::InferType::InferTypeKind::GENERAL
;
351 return rtype
->clone ();
355 case TyTy::InferType::InferTypeKind::FLOAT
: {
357 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
358 || r
->get_infer_kind ()
359 == TyTy::InferType::InferTypeKind::GENERAL
;
361 return rtype
->clone ();
372 bool is_valid
= (ltype
->get_infer_kind ()
373 == TyTy::InferType::InferTypeKind::GENERAL
)
374 || (ltype
->get_infer_kind ()
375 == TyTy::InferType::InferTypeKind::INTEGRAL
);
378 ltype
->apply_primitive_type_hint (*rtype
);
379 return rtype
->clone ();
385 bool is_valid
= (ltype
->get_infer_kind ()
386 == TyTy::InferType::InferTypeKind::GENERAL
)
387 || (ltype
->get_infer_kind ()
388 == TyTy::InferType::InferTypeKind::FLOAT
);
391 ltype
->apply_primitive_type_hint (*rtype
);
392 return rtype
->clone ();
410 case TyTy::PLACEHOLDER
:
411 case TyTy::PROJECTION
:
413 case TyTy::CLOSURE
: {
414 bool is_valid
= (ltype
->get_infer_kind ()
415 == TyTy::InferType::InferTypeKind::GENERAL
);
417 return rtype
->clone ();
422 return new TyTy::ErrorType (0);
425 return new TyTy::ErrorType (0);
429 UnifyRules::expect_adt (TyTy::ADTType
*ltype
, TyTy::BaseType
*rtype
)
431 switch (rtype
->get_kind ())
434 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
436 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
438 return ltype
->clone ();
443 TyTy::ADTType
&type
= *static_cast<TyTy::ADTType
*> (rtype
);
444 if (ltype
->get_adt_kind () != type
.get_adt_kind ())
446 return new TyTy::ErrorType (0);
449 if (ltype
->get_identifier ().compare (type
.get_identifier ()) != 0)
451 return new TyTy::ErrorType (0);
454 if (ltype
->number_of_variants () != type
.number_of_variants ())
456 return new TyTy::ErrorType (0);
459 for (size_t i
= 0; i
< type
.number_of_variants (); ++i
)
461 TyTy::VariantDef
*a
= ltype
->get_variants ().at (i
);
462 TyTy::VariantDef
*b
= type
.get_variants ().at (i
);
464 if (a
->num_fields () != b
->num_fields ())
466 return new TyTy::ErrorType (0);
469 for (size_t j
= 0; j
< a
->num_fields (); j
++)
471 TyTy::StructFieldType
*base_field
= a
->get_field_at_index (j
);
472 TyTy::StructFieldType
*other_field
= b
->get_field_at_index (j
);
474 TyTy::BaseType
*this_field_ty
= base_field
->get_field_type ();
475 TyTy::BaseType
*other_field_ty
= other_field
->get_field_type ();
477 TyTy::BaseType
*unified_ty
478 = UnifyRules::Resolve (TyTy::TyWithLocation (this_field_ty
),
479 TyTy::TyWithLocation (other_field_ty
),
481 false /* emit_error */, infer_flag
,
483 if (unified_ty
->get_kind () == TyTy::TypeKind::ERROR
)
485 return new TyTy::ErrorType (0);
490 // generic args for the unit-struct case
491 if (type
.is_unit () && ltype
->is_unit ())
493 rust_assert (type
.get_num_substitutions ()
494 == ltype
->get_num_substitutions ());
496 for (size_t i
= 0; i
< type
.get_num_substitutions (); i
++)
498 auto &a
= ltype
->get_substs ().at (i
);
499 auto &b
= type
.get_substs ().at (i
);
501 auto pa
= a
.get_param_ty ();
502 auto pb
= b
.get_param_ty ();
505 = UnifyRules::Resolve (TyTy::TyWithLocation (pa
),
506 TyTy::TyWithLocation (pb
), locus
,
507 commit_flag
, false /* emit_error */,
508 infer_flag
, commits
, infers
);
509 if (res
->get_kind () == TyTy::TypeKind::ERROR
)
511 return new TyTy::ErrorType (0);
516 return type
.clone ();
537 case TyTy::PLACEHOLDER
:
538 case TyTy::PROJECTION
:
542 return new TyTy::ErrorType (0);
544 return new TyTy::ErrorType (0);
548 UnifyRules::expect_str (TyTy::StrType
*ltype
, TyTy::BaseType
*rtype
)
550 switch (rtype
->get_kind ())
553 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
555 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
557 return ltype
->clone ();
562 return rtype
->clone ();
581 case TyTy::PLACEHOLDER
:
582 case TyTy::PROJECTION
:
586 return new TyTy::ErrorType (0);
588 return new TyTy::ErrorType (0);
592 UnifyRules::expect_reference (TyTy::ReferenceType
*ltype
, TyTy::BaseType
*rtype
)
594 switch (rtype
->get_kind ())
597 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
599 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
601 return ltype
->clone ();
606 TyTy::ReferenceType
&type
= *static_cast<TyTy::ReferenceType
*> (rtype
);
607 auto base_type
= ltype
->get_base ();
608 auto other_base_type
= type
.get_base ();
610 TyTy::BaseType
*base_resolved
611 = UnifyRules::Resolve (TyTy::TyWithLocation (base_type
),
612 TyTy::TyWithLocation (other_base_type
), locus
,
613 commit_flag
, false /* emit_error */,
614 infer_flag
, commits
, infers
);
615 if (base_resolved
->get_kind () == TyTy::TypeKind::ERROR
)
617 return new TyTy::ErrorType (0);
620 // rust is permissive about mutablity here you can always go from
621 // mutable to immutable but not the otherway round
622 bool mutability_ok
= ltype
->is_mutable () ? type
.is_mutable () : true;
625 return new TyTy::ErrorType (0);
628 return new TyTy::ReferenceType (ltype
->get_ref (), ltype
->get_ty_ref (),
629 TyTy::TyVar (base_resolved
->get_ref ()),
630 ltype
->mutability ());
651 case TyTy::PLACEHOLDER
:
652 case TyTy::PROJECTION
:
656 return new TyTy::ErrorType (0);
658 return new TyTy::ErrorType (0);
662 UnifyRules::expect_pointer (TyTy::PointerType
*ltype
, TyTy::BaseType
*rtype
)
664 switch (rtype
->get_kind ())
667 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
669 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
671 return ltype
->clone ();
675 case TyTy::POINTER
: {
676 TyTy::PointerType
&type
= *static_cast<TyTy::PointerType
*> (rtype
);
677 auto base_type
= ltype
->get_base ();
678 auto other_base_type
= type
.get_base ();
680 TyTy::BaseType
*base_resolved
681 = UnifyRules::Resolve (TyTy::TyWithLocation (base_type
),
682 TyTy::TyWithLocation (other_base_type
), locus
,
683 commit_flag
, false /* emit_error */,
684 infer_flag
, commits
, infers
);
685 if (base_resolved
->get_kind () == TyTy::TypeKind::ERROR
)
687 return new TyTy::ErrorType (0);
690 // rust is permissive about mutablity here you can always go from
691 // mutable to immutable but not the otherway round
692 bool mutability_ok
= ltype
->is_mutable () ? type
.is_mutable () : true;
695 return new TyTy::ErrorType (0);
698 return new TyTy::PointerType (ltype
->get_ref (), ltype
->get_ty_ref (),
699 TyTy::TyVar (base_resolved
->get_ref ()),
700 ltype
->mutability ());
721 case TyTy::PLACEHOLDER
:
722 case TyTy::PROJECTION
:
726 return new TyTy::ErrorType (0);
728 return new TyTy::ErrorType (0);
732 UnifyRules::expect_param (TyTy::ParamType
*ltype
, TyTy::BaseType
*rtype
)
734 switch (rtype
->get_kind ())
737 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
739 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
741 return ltype
->clone ();
746 TyTy::ParamType
&type
= *static_cast<TyTy::ParamType
*> (rtype
);
747 // bool symbol_matches
748 // = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
750 // // I think rustc checks a debruinj index
751 // if (symbol_matches)
753 // return type.clone ();
756 // matching symbol is not going to work when we mix symbol's and have
759 // bounds match? FIXME
761 return type
.clone ();
782 case TyTy::PLACEHOLDER
:
783 case TyTy::PROJECTION
:
787 return new TyTy::ErrorType (0);
789 return new TyTy::ErrorType (0);
793 UnifyRules::expect_array (TyTy::ArrayType
*ltype
, TyTy::BaseType
*rtype
)
795 switch (rtype
->get_kind ())
798 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
800 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
802 return ltype
->clone ();
807 TyTy::ArrayType
&type
= *static_cast<TyTy::ArrayType
*> (rtype
);
808 TyTy::BaseType
*element_unify
= UnifyRules::Resolve (
809 TyTy::TyWithLocation (ltype
->get_element_type ()),
810 TyTy::TyWithLocation (type
.get_element_type ()), locus
, commit_flag
,
811 false /* emit_error*/, infer_flag
, commits
, infers
);
813 if (element_unify
->get_kind () != TyTy::TypeKind::ERROR
)
815 return new TyTy::ArrayType (type
.get_ref (), type
.get_ty_ref (),
816 type
.get_ident ().locus
,
817 type
.get_capacity_expr (),
819 element_unify
->get_ref ()));
841 case TyTy::PLACEHOLDER
:
842 case TyTy::PROJECTION
:
846 return new TyTy::ErrorType (0);
848 return new TyTy::ErrorType (0);
852 UnifyRules::expect_slice (TyTy::SliceType
*ltype
, TyTy::BaseType
*rtype
)
854 switch (rtype
->get_kind ())
857 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
859 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
861 return ltype
->clone ();
866 TyTy::SliceType
&type
= *static_cast<TyTy::SliceType
*> (rtype
);
867 TyTy::BaseType
*element_unify
= UnifyRules::Resolve (
868 TyTy::TyWithLocation (ltype
->get_element_type ()),
869 TyTy::TyWithLocation (type
.get_element_type ()), locus
, commit_flag
,
870 false /* emit_error*/, infer_flag
, commits
, infers
);
872 if (element_unify
->get_kind () != TyTy::TypeKind::ERROR
)
874 return new TyTy::SliceType (type
.get_ref (), type
.get_ty_ref (),
875 type
.get_ident ().locus
,
877 element_unify
->get_ref ()));
899 case TyTy::PLACEHOLDER
:
900 case TyTy::PROJECTION
:
904 return new TyTy::ErrorType (0);
906 return new TyTy::ErrorType (0);
910 UnifyRules::expect_fndef (TyTy::FnType
*ltype
, TyTy::BaseType
*rtype
)
912 switch (rtype
->get_kind ())
915 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
917 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
919 return ltype
->clone ();
924 TyTy::FnType
&type
= *static_cast<TyTy::FnType
*> (rtype
);
925 if (ltype
->num_params () != type
.num_params ())
927 return new TyTy::ErrorType (0);
930 for (size_t i
= 0; i
< ltype
->num_params (); i
++)
932 auto a
= ltype
->param_at (i
).second
;
933 auto b
= type
.param_at (i
).second
;
936 = UnifyRules::Resolve (TyTy::TyWithLocation (a
),
937 TyTy::TyWithLocation (b
), locus
,
938 commit_flag
, false /* emit_errors */,
939 infer_flag
, commits
, infers
);
940 if (unified_param
->get_kind () == TyTy::TypeKind::ERROR
)
942 return new TyTy::ErrorType (0);
946 auto unified_return
= UnifyRules::Resolve (
947 TyTy::TyWithLocation (ltype
->get_return_type ()),
948 TyTy::TyWithLocation (type
.get_return_type ()), locus
, commit_flag
,
949 false /* emit_errors */, infer_flag
, commits
, infers
);
950 if (unified_return
->get_kind () == TyTy::TypeKind::ERROR
)
952 return new TyTy::ErrorType (0);
956 // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/extern.20blocks/near/346416045
957 if (ltype
->get_abi () != type
.get_abi ())
961 emit_abi_mismatch (*ltype
, type
);
963 return new TyTy::ErrorType (0);
966 // DEF Id match? see https://github.com/Rust-GCC/gccrs/issues/2053
968 return ltype
->clone ();
989 case TyTy::PLACEHOLDER
:
990 case TyTy::PROJECTION
:
994 return new TyTy::ErrorType (0);
996 return new TyTy::ErrorType (0);
1000 UnifyRules::expect_fnptr (TyTy::FnPtr
*ltype
, TyTy::BaseType
*rtype
)
1002 switch (rtype
->get_kind ())
1005 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1007 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1009 return ltype
->clone ();
1014 TyTy::FnPtr
&type
= *static_cast<TyTy::FnPtr
*> (rtype
);
1015 if (ltype
->num_params () != type
.num_params ())
1017 return new TyTy::ErrorType (0);
1020 for (size_t i
= 0; i
< ltype
->num_params (); i
++)
1022 auto a
= ltype
->get_param_type_at (i
);
1023 auto b
= type
.get_param_type_at (i
);
1026 = UnifyRules::Resolve (TyTy::TyWithLocation (a
),
1027 TyTy::TyWithLocation (b
), locus
,
1028 commit_flag
, false /* emit_errors */,
1029 infer_flag
, commits
, infers
);
1030 if (unified_param
->get_kind () == TyTy::TypeKind::ERROR
)
1032 return new TyTy::ErrorType (0);
1036 auto unified_return
= UnifyRules::Resolve (
1037 TyTy::TyWithLocation (ltype
->get_return_type ()),
1038 TyTy::TyWithLocation (type
.get_return_type ()), locus
, commit_flag
,
1039 false /* emit_errors */, infer_flag
, commits
, infers
);
1040 if (unified_return
->get_kind () == TyTy::TypeKind::ERROR
)
1042 return new TyTy::ErrorType (0);
1045 return ltype
->clone ();
1050 TyTy::FnType
&type
= *static_cast<TyTy::FnType
*> (rtype
);
1051 auto this_ret_type
= ltype
->get_return_type ();
1052 auto other_ret_type
= type
.get_return_type ();
1055 = UnifyRules::Resolve (TyTy::TyWithLocation (this_ret_type
),
1056 TyTy::TyWithLocation (other_ret_type
), locus
,
1057 commit_flag
, false /*emit_errors*/, infer_flag
,
1059 if (unified_result
->get_kind () == TyTy::TypeKind::ERROR
)
1061 return new TyTy::ErrorType (0);
1064 if (ltype
->num_params () != type
.num_params ())
1066 return new TyTy::ErrorType (0);
1069 for (size_t i
= 0; i
< ltype
->num_params (); i
++)
1071 auto this_param
= ltype
->get_param_type_at (i
);
1072 auto other_param
= type
.param_at (i
).second
;
1075 = UnifyRules::Resolve (TyTy::TyWithLocation (this_param
),
1076 TyTy::TyWithLocation (other_param
), locus
,
1077 commit_flag
, false /* emit_errors */,
1078 infer_flag
, commits
, infers
);
1079 if (unified_param
->get_kind () == TyTy::TypeKind::ERROR
)
1081 return new TyTy::ErrorType (0);
1085 return ltype
->clone ();
1105 case TyTy::PLACEHOLDER
:
1106 case TyTy::PROJECTION
:
1110 return new TyTy::ErrorType (0);
1112 return new TyTy::ErrorType (0);
1116 UnifyRules::expect_tuple (TyTy::TupleType
*ltype
, TyTy::BaseType
*rtype
)
1118 switch (rtype
->get_kind ())
1121 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1123 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1125 return ltype
->clone ();
1130 TyTy::TupleType
&type
= *static_cast<TyTy::TupleType
*> (rtype
);
1131 if (ltype
->num_fields () != type
.num_fields ())
1133 return new TyTy::ErrorType (0);
1136 std::vector
<TyTy::TyVar
> fields
;
1137 for (size_t i
= 0; i
< ltype
->num_fields (); i
++)
1139 TyTy::BaseType
*bo
= ltype
->get_field (i
);
1140 TyTy::BaseType
*fo
= type
.get_field (i
);
1142 TyTy::BaseType
*unified_ty
1143 = UnifyRules::Resolve (TyTy::TyWithLocation (bo
),
1144 TyTy::TyWithLocation (fo
), locus
,
1145 commit_flag
, false /* emit_errors */,
1146 infer_flag
, commits
, infers
);
1147 if (unified_ty
->get_kind () == TyTy::TypeKind::ERROR
)
1148 return new TyTy::ErrorType (0);
1150 fields
.push_back (TyTy::TyVar (unified_ty
->get_ref ()));
1153 return new TyTy::TupleType (type
.get_ref (), type
.get_ty_ref (),
1154 type
.get_ident ().locus
, fields
);
1175 case TyTy::PLACEHOLDER
:
1176 case TyTy::PROJECTION
:
1180 return new TyTy::ErrorType (0);
1182 return new TyTy::ErrorType (0);
1186 UnifyRules::expect_bool (TyTy::BoolType
*ltype
, TyTy::BaseType
*rtype
)
1188 switch (rtype
->get_kind ())
1191 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1193 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1196 r
->apply_primitive_type_hint (*ltype
);
1197 return ltype
->clone ();
1203 return rtype
->clone ();
1222 case TyTy::PLACEHOLDER
:
1223 case TyTy::PROJECTION
:
1227 return new TyTy::ErrorType (0);
1229 return new TyTy::ErrorType (0);
1233 UnifyRules::expect_char (TyTy::CharType
*ltype
, TyTy::BaseType
*rtype
)
1235 switch (rtype
->get_kind ())
1238 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1240 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1243 r
->apply_primitive_type_hint (*ltype
);
1244 return ltype
->clone ();
1250 return rtype
->clone ();
1269 case TyTy::PLACEHOLDER
:
1270 case TyTy::PROJECTION
:
1274 return new TyTy::ErrorType (0);
1276 return new TyTy::ErrorType (0);
1280 UnifyRules::expect_int (TyTy::IntType
*ltype
, TyTy::BaseType
*rtype
)
1282 switch (rtype
->get_kind ())
1285 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1287 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1288 || r
->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL
;
1291 r
->apply_primitive_type_hint (*ltype
);
1292 return ltype
->clone ();
1298 TyTy::IntType
&type
= *static_cast<TyTy::IntType
*> (rtype
);
1299 bool is_valid
= ltype
->get_int_kind () == type
.get_int_kind ();
1301 return new TyTy::IntType (type
.get_ref (), type
.get_ty_ref (),
1302 type
.get_int_kind ());
1323 case TyTy::PLACEHOLDER
:
1324 case TyTy::PROJECTION
:
1328 return new TyTy::ErrorType (0);
1330 return new TyTy::ErrorType (0);
1334 UnifyRules::expect_uint (TyTy::UintType
*ltype
, TyTy::BaseType
*rtype
)
1336 switch (rtype
->get_kind ())
1339 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1341 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1342 || r
->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL
;
1345 r
->apply_primitive_type_hint (*ltype
);
1346 return ltype
->clone ();
1352 TyTy::UintType
&type
= *static_cast<TyTy::UintType
*> (rtype
);
1353 bool is_valid
= ltype
->get_uint_kind () == type
.get_uint_kind ();
1355 return new TyTy::UintType (type
.get_ref (), type
.get_ty_ref (),
1356 type
.get_uint_kind ());
1377 case TyTy::PLACEHOLDER
:
1378 case TyTy::PROJECTION
:
1382 return new TyTy::ErrorType (0);
1384 return new TyTy::ErrorType (0);
1388 UnifyRules::expect_float (TyTy::FloatType
*ltype
, TyTy::BaseType
*rtype
)
1390 switch (rtype
->get_kind ())
1393 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1395 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1396 || r
->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
;
1399 r
->apply_primitive_type_hint (*ltype
);
1400 return ltype
->clone ();
1406 TyTy::FloatType
&type
= *static_cast<TyTy::FloatType
*> (rtype
);
1407 bool is_valid
= ltype
->get_float_kind () == type
.get_float_kind ();
1409 return new TyTy::FloatType (type
.get_ref (), type
.get_ty_ref (),
1410 type
.get_float_kind ());
1431 case TyTy::PLACEHOLDER
:
1432 case TyTy::PROJECTION
:
1436 return new TyTy::ErrorType (0);
1438 return new TyTy::ErrorType (0);
1442 UnifyRules::expect_isize (TyTy::ISizeType
*ltype
, TyTy::BaseType
*rtype
)
1444 switch (rtype
->get_kind ())
1447 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1449 = r
->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT
;
1452 r
->apply_primitive_type_hint (*ltype
);
1453 return ltype
->clone ();
1459 return rtype
->clone ();
1478 case TyTy::PLACEHOLDER
:
1479 case TyTy::PROJECTION
:
1483 return new TyTy::ErrorType (0);
1485 return new TyTy::ErrorType (0);
1489 UnifyRules::expect_usize (TyTy::USizeType
*ltype
, TyTy::BaseType
*rtype
)
1491 switch (rtype
->get_kind ())
1494 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1496 = r
->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT
;
1499 r
->apply_primitive_type_hint (*ltype
);
1500 return ltype
->clone ();
1506 return rtype
->clone ();
1525 case TyTy::PLACEHOLDER
:
1526 case TyTy::PROJECTION
:
1530 return new TyTy::ErrorType (0);
1532 return new TyTy::ErrorType (0);
1536 UnifyRules::expect_never (TyTy::NeverType
*ltype
, TyTy::BaseType
*rtype
)
1538 switch (rtype
->get_kind ())
1541 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1543 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1545 return ltype
->clone ();
1550 return rtype
->clone ();
1552 return new TyTy::ErrorType (0);
1556 UnifyRules::expect_placeholder (TyTy::PlaceholderType
*ltype
,
1557 TyTy::BaseType
*rtype
)
1559 switch (rtype
->get_kind ())
1562 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1564 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1566 return ltype
->clone ();
1570 case TyTy::PLACEHOLDER
:
1571 return ltype
->clone ();
1573 case TyTy::PROJECTION
:
1595 return rtype
->clone ();
1599 return new TyTy::ErrorType (0);
1601 return new TyTy::ErrorType (0);
1605 UnifyRules::expect_projection (TyTy::ProjectionType
*ltype
,
1606 TyTy::BaseType
*rtype
)
1608 switch (rtype
->get_kind ())
1611 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1613 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1615 return ltype
->clone ();
1620 case TyTy::PROJECTION
:
1621 rust_unreachable ();
1644 case TyTy::PLACEHOLDER
:
1646 return new TyTy::ErrorType (0);
1648 return new TyTy::ErrorType (0);
1652 UnifyRules::expect_dyn (TyTy::DynamicObjectType
*ltype
, TyTy::BaseType
*rtype
)
1654 switch (rtype
->get_kind ())
1657 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1659 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1661 return ltype
->clone ();
1665 case TyTy::DYNAMIC
: {
1666 TyTy::DynamicObjectType
&type
1667 = *static_cast<TyTy::DynamicObjectType
*> (rtype
);
1668 if (ltype
->num_specified_bounds () != type
.num_specified_bounds ())
1670 return new TyTy::ErrorType (0);
1673 if (!ltype
->bounds_compatible (type
, locus
, true))
1675 return new TyTy::ErrorType (0);
1678 return ltype
->clone ();
1701 case TyTy::PLACEHOLDER
:
1702 case TyTy::PROJECTION
:
1704 return new TyTy::ErrorType (0);
1706 return new TyTy::ErrorType (0);
1710 UnifyRules::expect_closure (TyTy::ClosureType
*ltype
, TyTy::BaseType
*rtype
)
1712 switch (rtype
->get_kind ())
1715 TyTy::InferType
*r
= static_cast<TyTy::InferType
*> (rtype
);
1717 = r
->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
;
1719 return ltype
->clone ();
1723 case TyTy::CLOSURE
: {
1724 TyTy::ClosureType
&type
= *static_cast<TyTy::ClosureType
*> (rtype
);
1725 if (ltype
->get_def_id () != type
.get_def_id ())
1727 return new TyTy::ErrorType (0);
1730 TyTy::BaseType
*args_res
= UnifyRules::Resolve (
1731 TyTy::TyWithLocation (<ype
->get_parameters ()),
1732 TyTy::TyWithLocation (&type
.get_parameters ()), locus
, commit_flag
,
1733 false /* emit_error */, infer_flag
, commits
, infers
);
1734 if (args_res
->get_kind () == TyTy::TypeKind::ERROR
)
1736 return new TyTy::ErrorType (0);
1739 TyTy::BaseType
*res
= UnifyRules::Resolve (
1740 TyTy::TyWithLocation (<ype
->get_result_type ()),
1741 TyTy::TyWithLocation (&type
.get_result_type ()), locus
, commit_flag
,
1742 false /* emit_error */, infer_flag
, commits
, infers
);
1743 if (res
== nullptr || res
->get_kind () == TyTy::TypeKind::ERROR
)
1745 return new TyTy::ErrorType (0);
1748 return ltype
->clone ();
1770 case TyTy::PLACEHOLDER
:
1771 case TyTy::PROJECTION
:
1774 return new TyTy::ErrorType (0);
1776 return new TyTy::ErrorType (0);
1779 } // namespace Resolver