[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / rust / typecheck / rust-unify.cc
blob91b3148d7fa05032e7187bfebd80022c427f9a96
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
8 // version.
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
13 // for more details.
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"
22 namespace Rust {
23 namespace Resolver {
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 ())
35 TyTy::BaseType *
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,
42 infers);
44 TyTy::BaseType *result = r.go ();
45 commits.push_back ({lhs.get_ty (), rhs.get_ty (), result});
46 if (r.commit_flag)
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 ();
53 return result;
56 TyTy::BaseType *
57 UnifyRules::get_base ()
59 return lhs.get_ty ()->destructure ();
62 TyTy::BaseType *
63 UnifyRules::get_other ()
65 return rhs.get_ty ()->destructure ();
68 void
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);
102 if (!ok)
103 continue;
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 (),
109 UNKNOWN_NODEID, ref,
110 UNKNOWN_LOCAL_DEFID);
111 context.insert_type (node, resolved->clone ());
117 void
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 ());
131 void
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 ());
143 TyTy::BaseType *
144 UnifyRules::go ()
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 ());
155 // check bounds
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
168 emit_error = false;
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
177 emit_error = false;
178 return new TyTy::ErrorType (0);
183 if (infer_flag)
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
188 = lhs_is_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
198 = rhs_is_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;
205 if (rneeds_infer)
207 TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype);
208 TyTy::TyVar iv
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});
215 // FIXME
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
220 rtype = i;
222 else if (lneeds_infer)
224 TyTy::ParamType *p = static_cast<TyTy::ParamType *> (ltype);
225 TyTy::TyVar iv
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});
232 // FIXME
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
237 ltype = i;
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?
246 // references?
247 if (rtype->get_kind () == TyTy::NEVER && ltype->get_kind () != TyTy::INFER)
248 return ltype->clone ();
250 switch (ltype->get_kind ())
252 case TyTy::INFER:
253 return expect_inference_variable (static_cast<TyTy::InferType *> (ltype),
254 rtype);
256 case TyTy::ADT:
257 return expect_adt (static_cast<TyTy::ADTType *> (ltype), rtype);
259 case TyTy::STR:
260 return expect_str (static_cast<TyTy::StrType *> (ltype), rtype);
262 case TyTy::REF:
263 return expect_reference (static_cast<TyTy::ReferenceType *> (ltype),
264 rtype);
266 case TyTy::POINTER:
267 return expect_pointer (static_cast<TyTy::PointerType *> (ltype), rtype);
269 case TyTy::PARAM:
270 return expect_param (static_cast<TyTy::ParamType *> (ltype), rtype);
272 case TyTy::ARRAY:
273 return expect_array (static_cast<TyTy::ArrayType *> (ltype), rtype);
275 case TyTy::SLICE:
276 return expect_slice (static_cast<TyTy::SliceType *> (ltype), rtype);
278 case TyTy::FNDEF:
279 return expect_fndef (static_cast<TyTy::FnType *> (ltype), rtype);
281 case TyTy::FNPTR:
282 return expect_fnptr (static_cast<TyTy::FnPtr *> (ltype), rtype);
284 case TyTy::TUPLE:
285 return expect_tuple (static_cast<TyTy::TupleType *> (ltype), rtype);
287 case TyTy::BOOL:
288 return expect_bool (static_cast<TyTy::BoolType *> (ltype), rtype);
290 case TyTy::CHAR:
291 return expect_char (static_cast<TyTy::CharType *> (ltype), rtype);
293 case TyTy::INT:
294 return expect_int (static_cast<TyTy::IntType *> (ltype), rtype);
296 case TyTy::UINT:
297 return expect_uint (static_cast<TyTy::UintType *> (ltype), rtype);
299 case TyTy::FLOAT:
300 return expect_float (static_cast<TyTy::FloatType *> (ltype), rtype);
302 case TyTy::USIZE:
303 return expect_usize (static_cast<TyTy::USizeType *> (ltype), rtype);
305 case TyTy::ISIZE:
306 return expect_isize (static_cast<TyTy::ISizeType *> (ltype), rtype);
308 case TyTy::NEVER:
309 return expect_never (static_cast<TyTy::NeverType *> (ltype), rtype);
311 case TyTy::PLACEHOLDER:
312 return expect_placeholder (static_cast<TyTy::PlaceholderType *> (ltype),
313 rtype);
315 case TyTy::PROJECTION:
316 return expect_projection (static_cast<TyTy::ProjectionType *> (ltype),
317 rtype);
319 case TyTy::DYNAMIC:
320 return expect_dyn (static_cast<TyTy::DynamicObjectType *> (ltype), rtype);
322 case TyTy::CLOSURE:
323 return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype);
325 case TyTy::ERROR:
326 return new TyTy::ErrorType (0);
329 return new TyTy::ErrorType (0);
332 TyTy::BaseType *
333 UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
334 TyTy::BaseType *rtype)
336 switch (rtype->get_kind ())
338 case TyTy::INFER: {
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;
350 if (is_valid)
351 return rtype->clone ();
353 break;
355 case TyTy::InferType::InferTypeKind::FLOAT: {
356 bool is_valid
357 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
358 || r->get_infer_kind ()
359 == TyTy::InferType::InferTypeKind::GENERAL;
360 if (is_valid)
361 return rtype->clone ();
363 break;
366 break;
368 case TyTy::INT:
369 case TyTy::UINT:
370 case TyTy::USIZE:
371 case TyTy::ISIZE: {
372 bool is_valid = (ltype->get_infer_kind ()
373 == TyTy::InferType::InferTypeKind::GENERAL)
374 || (ltype->get_infer_kind ()
375 == TyTy::InferType::InferTypeKind::INTEGRAL);
376 if (is_valid)
378 ltype->apply_primitive_type_hint (*rtype);
379 return rtype->clone ();
382 break;
384 case TyTy::FLOAT: {
385 bool is_valid = (ltype->get_infer_kind ()
386 == TyTy::InferType::InferTypeKind::GENERAL)
387 || (ltype->get_infer_kind ()
388 == TyTy::InferType::InferTypeKind::FLOAT);
389 if (is_valid)
391 ltype->apply_primitive_type_hint (*rtype);
392 return rtype->clone ();
395 break;
397 case TyTy::ADT:
398 case TyTy::STR:
399 case TyTy::REF:
400 case TyTy::POINTER:
401 case TyTy::PARAM:
402 case TyTy::ARRAY:
403 case TyTy::SLICE:
404 case TyTy::FNDEF:
405 case TyTy::FNPTR:
406 case TyTy::TUPLE:
407 case TyTy::BOOL:
408 case TyTy::CHAR:
409 case TyTy::NEVER:
410 case TyTy::PLACEHOLDER:
411 case TyTy::PROJECTION:
412 case TyTy::DYNAMIC:
413 case TyTy::CLOSURE: {
414 bool is_valid = (ltype->get_infer_kind ()
415 == TyTy::InferType::InferTypeKind::GENERAL);
416 if (is_valid)
417 return rtype->clone ();
419 break;
421 case TyTy::ERROR:
422 return new TyTy::ErrorType (0);
425 return new TyTy::ErrorType (0);
428 TyTy::BaseType *
429 UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
431 switch (rtype->get_kind ())
433 case TyTy::INFER: {
434 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
435 bool is_valid
436 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
437 if (is_valid)
438 return ltype->clone ();
440 break;
442 case TyTy::ADT: {
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),
480 locus, commit_flag,
481 false /* emit_error */, infer_flag,
482 commits, infers);
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 ();
504 auto res
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 ();
518 break;
520 case TyTy::STR:
521 case TyTy::REF:
522 case TyTy::POINTER:
523 case TyTy::PARAM:
524 case TyTy::ARRAY:
525 case TyTy::SLICE:
526 case TyTy::FNDEF:
527 case TyTy::FNPTR:
528 case TyTy::TUPLE:
529 case TyTy::BOOL:
530 case TyTy::CHAR:
531 case TyTy::INT:
532 case TyTy::UINT:
533 case TyTy::FLOAT:
534 case TyTy::USIZE:
535 case TyTy::ISIZE:
536 case TyTy::NEVER:
537 case TyTy::PLACEHOLDER:
538 case TyTy::PROJECTION:
539 case TyTy::DYNAMIC:
540 case TyTy::CLOSURE:
541 case TyTy::ERROR:
542 return new TyTy::ErrorType (0);
544 return new TyTy::ErrorType (0);
547 TyTy::BaseType *
548 UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
550 switch (rtype->get_kind ())
552 case TyTy::INFER: {
553 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
554 bool is_valid
555 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
556 if (is_valid)
557 return ltype->clone ();
559 break;
561 case TyTy::STR:
562 return rtype->clone ();
564 case TyTy::ADT:
565 case TyTy::REF:
566 case TyTy::POINTER:
567 case TyTy::PARAM:
568 case TyTy::ARRAY:
569 case TyTy::SLICE:
570 case TyTy::FNDEF:
571 case TyTy::FNPTR:
572 case TyTy::TUPLE:
573 case TyTy::BOOL:
574 case TyTy::CHAR:
575 case TyTy::INT:
576 case TyTy::UINT:
577 case TyTy::FLOAT:
578 case TyTy::USIZE:
579 case TyTy::ISIZE:
580 case TyTy::NEVER:
581 case TyTy::PLACEHOLDER:
582 case TyTy::PROJECTION:
583 case TyTy::DYNAMIC:
584 case TyTy::CLOSURE:
585 case TyTy::ERROR:
586 return new TyTy::ErrorType (0);
588 return new TyTy::ErrorType (0);
591 TyTy::BaseType *
592 UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
594 switch (rtype->get_kind ())
596 case TyTy::INFER: {
597 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
598 bool is_valid
599 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
600 if (is_valid)
601 return ltype->clone ();
603 break;
605 case TyTy::REF: {
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;
623 if (!mutability_ok)
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 ());
632 break;
634 case TyTy::STR:
635 case TyTy::ADT:
636 case TyTy::POINTER:
637 case TyTy::PARAM:
638 case TyTy::ARRAY:
639 case TyTy::SLICE:
640 case TyTy::FNDEF:
641 case TyTy::FNPTR:
642 case TyTy::TUPLE:
643 case TyTy::BOOL:
644 case TyTy::CHAR:
645 case TyTy::INT:
646 case TyTy::UINT:
647 case TyTy::FLOAT:
648 case TyTy::USIZE:
649 case TyTy::ISIZE:
650 case TyTy::NEVER:
651 case TyTy::PLACEHOLDER:
652 case TyTy::PROJECTION:
653 case TyTy::DYNAMIC:
654 case TyTy::CLOSURE:
655 case TyTy::ERROR:
656 return new TyTy::ErrorType (0);
658 return new TyTy::ErrorType (0);
661 TyTy::BaseType *
662 UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
664 switch (rtype->get_kind ())
666 case TyTy::INFER: {
667 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
668 bool is_valid
669 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
670 if (is_valid)
671 return ltype->clone ();
673 break;
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;
693 if (!mutability_ok)
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 ());
702 break;
704 case TyTy::STR:
705 case TyTy::ADT:
706 case TyTy::REF:
707 case TyTy::PARAM:
708 case TyTy::ARRAY:
709 case TyTy::SLICE:
710 case TyTy::FNDEF:
711 case TyTy::FNPTR:
712 case TyTy::TUPLE:
713 case TyTy::BOOL:
714 case TyTy::CHAR:
715 case TyTy::INT:
716 case TyTy::UINT:
717 case TyTy::FLOAT:
718 case TyTy::USIZE:
719 case TyTy::ISIZE:
720 case TyTy::NEVER:
721 case TyTy::PLACEHOLDER:
722 case TyTy::PROJECTION:
723 case TyTy::DYNAMIC:
724 case TyTy::CLOSURE:
725 case TyTy::ERROR:
726 return new TyTy::ErrorType (0);
728 return new TyTy::ErrorType (0);
731 TyTy::BaseType *
732 UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
734 switch (rtype->get_kind ())
736 case TyTy::INFER: {
737 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
738 bool is_valid
739 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
740 if (is_valid)
741 return ltype->clone ();
743 break;
745 case TyTy::PARAM: {
746 TyTy::ParamType &type = *static_cast<TyTy::ParamType *> (rtype);
747 // bool symbol_matches
748 // = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
749 // // TODO
750 // // I think rustc checks a debruinj index
751 // if (symbol_matches)
752 // {
753 // return type.clone ();
754 // }
756 // matching symbol is not going to work when we mix symbol's and have
757 // nested generics
759 // bounds match? FIXME
761 return type.clone ();
763 break;
765 case TyTy::POINTER:
766 case TyTy::STR:
767 case TyTy::ADT:
768 case TyTy::REF:
769 case TyTy::ARRAY:
770 case TyTy::SLICE:
771 case TyTy::FNDEF:
772 case TyTy::FNPTR:
773 case TyTy::TUPLE:
774 case TyTy::BOOL:
775 case TyTy::CHAR:
776 case TyTy::INT:
777 case TyTy::UINT:
778 case TyTy::FLOAT:
779 case TyTy::USIZE:
780 case TyTy::ISIZE:
781 case TyTy::NEVER:
782 case TyTy::PLACEHOLDER:
783 case TyTy::PROJECTION:
784 case TyTy::DYNAMIC:
785 case TyTy::CLOSURE:
786 case TyTy::ERROR:
787 return new TyTy::ErrorType (0);
789 return new TyTy::ErrorType (0);
792 TyTy::BaseType *
793 UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
795 switch (rtype->get_kind ())
797 case TyTy::INFER: {
798 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
799 bool is_valid
800 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
801 if (is_valid)
802 return ltype->clone ();
804 break;
806 case TyTy::ARRAY: {
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 (),
818 TyTy::TyVar (
819 element_unify->get_ref ()));
822 break;
824 case TyTy::PARAM:
825 case TyTy::POINTER:
826 case TyTy::STR:
827 case TyTy::ADT:
828 case TyTy::REF:
829 case TyTy::SLICE:
830 case TyTy::FNDEF:
831 case TyTy::FNPTR:
832 case TyTy::TUPLE:
833 case TyTy::BOOL:
834 case TyTy::CHAR:
835 case TyTy::INT:
836 case TyTy::UINT:
837 case TyTy::FLOAT:
838 case TyTy::USIZE:
839 case TyTy::ISIZE:
840 case TyTy::NEVER:
841 case TyTy::PLACEHOLDER:
842 case TyTy::PROJECTION:
843 case TyTy::DYNAMIC:
844 case TyTy::CLOSURE:
845 case TyTy::ERROR:
846 return new TyTy::ErrorType (0);
848 return new TyTy::ErrorType (0);
851 TyTy::BaseType *
852 UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
854 switch (rtype->get_kind ())
856 case TyTy::INFER: {
857 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
858 bool is_valid
859 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
860 if (is_valid)
861 return ltype->clone ();
863 break;
865 case TyTy::SLICE: {
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,
876 TyTy::TyVar (
877 element_unify->get_ref ()));
880 break;
882 case TyTy::PARAM:
883 case TyTy::POINTER:
884 case TyTy::STR:
885 case TyTy::ADT:
886 case TyTy::REF:
887 case TyTy::ARRAY:
888 case TyTy::FNDEF:
889 case TyTy::FNPTR:
890 case TyTy::TUPLE:
891 case TyTy::BOOL:
892 case TyTy::CHAR:
893 case TyTy::INT:
894 case TyTy::UINT:
895 case TyTy::FLOAT:
896 case TyTy::USIZE:
897 case TyTy::ISIZE:
898 case TyTy::NEVER:
899 case TyTy::PLACEHOLDER:
900 case TyTy::PROJECTION:
901 case TyTy::DYNAMIC:
902 case TyTy::CLOSURE:
903 case TyTy::ERROR:
904 return new TyTy::ErrorType (0);
906 return new TyTy::ErrorType (0);
909 TyTy::BaseType *
910 UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
912 switch (rtype->get_kind ())
914 case TyTy::INFER: {
915 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
916 bool is_valid
917 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
918 if (is_valid)
919 return ltype->clone ();
921 break;
923 case TyTy::FNDEF: {
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;
935 auto unified_param
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);
955 // ABI match? see
956 // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/extern.20blocks/near/346416045
957 if (ltype->get_abi () != type.get_abi ())
959 if (emit_error)
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 ();
970 break;
972 case TyTy::TUPLE:
973 case TyTy::BOOL:
974 case TyTy::CHAR:
975 case TyTy::INT:
976 case TyTy::FLOAT:
977 case TyTy::ISIZE:
978 case TyTy::ADT:
979 case TyTy::STR:
980 case TyTy::REF:
981 case TyTy::POINTER:
982 case TyTy::PARAM:
983 case TyTy::ARRAY:
984 case TyTy::SLICE:
985 case TyTy::FNPTR:
986 case TyTy::UINT:
987 case TyTy::USIZE:
988 case TyTy::NEVER:
989 case TyTy::PLACEHOLDER:
990 case TyTy::PROJECTION:
991 case TyTy::DYNAMIC:
992 case TyTy::CLOSURE:
993 case TyTy::ERROR:
994 return new TyTy::ErrorType (0);
996 return new TyTy::ErrorType (0);
999 TyTy::BaseType *
1000 UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
1002 switch (rtype->get_kind ())
1004 case TyTy::INFER: {
1005 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1006 bool is_valid
1007 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1008 if (is_valid)
1009 return ltype->clone ();
1011 break;
1013 case TyTy::FNPTR: {
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);
1025 auto unified_param
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 ();
1047 break;
1049 case TyTy::FNDEF: {
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 ();
1054 auto unified_result
1055 = UnifyRules::Resolve (TyTy::TyWithLocation (this_ret_type),
1056 TyTy::TyWithLocation (other_ret_type), locus,
1057 commit_flag, false /*emit_errors*/, infer_flag,
1058 commits, infers);
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;
1074 auto unified_param
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 ();
1087 break;
1089 case TyTy::TUPLE:
1090 case TyTy::BOOL:
1091 case TyTy::CHAR:
1092 case TyTy::INT:
1093 case TyTy::FLOAT:
1094 case TyTy::ISIZE:
1095 case TyTy::ADT:
1096 case TyTy::STR:
1097 case TyTy::REF:
1098 case TyTy::POINTER:
1099 case TyTy::PARAM:
1100 case TyTy::ARRAY:
1101 case TyTy::SLICE:
1102 case TyTy::UINT:
1103 case TyTy::USIZE:
1104 case TyTy::NEVER:
1105 case TyTy::PLACEHOLDER:
1106 case TyTy::PROJECTION:
1107 case TyTy::DYNAMIC:
1108 case TyTy::CLOSURE:
1109 case TyTy::ERROR:
1110 return new TyTy::ErrorType (0);
1112 return new TyTy::ErrorType (0);
1115 TyTy::BaseType *
1116 UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
1118 switch (rtype->get_kind ())
1120 case TyTy::INFER: {
1121 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1122 bool is_valid
1123 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1124 if (is_valid)
1125 return ltype->clone ();
1127 break;
1129 case TyTy::TUPLE: {
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);
1156 break;
1158 case TyTy::BOOL:
1159 case TyTy::CHAR:
1160 case TyTy::INT:
1161 case TyTy::FLOAT:
1162 case TyTy::ISIZE:
1163 case TyTy::ADT:
1164 case TyTy::STR:
1165 case TyTy::REF:
1166 case TyTy::POINTER:
1167 case TyTy::PARAM:
1168 case TyTy::ARRAY:
1169 case TyTy::SLICE:
1170 case TyTy::FNDEF:
1171 case TyTy::FNPTR:
1172 case TyTy::UINT:
1173 case TyTy::USIZE:
1174 case TyTy::NEVER:
1175 case TyTy::PLACEHOLDER:
1176 case TyTy::PROJECTION:
1177 case TyTy::DYNAMIC:
1178 case TyTy::CLOSURE:
1179 case TyTy::ERROR:
1180 return new TyTy::ErrorType (0);
1182 return new TyTy::ErrorType (0);
1185 TyTy::BaseType *
1186 UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
1188 switch (rtype->get_kind ())
1190 case TyTy::INFER: {
1191 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1192 bool is_valid
1193 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1194 if (is_valid)
1196 r->apply_primitive_type_hint (*ltype);
1197 return ltype->clone ();
1200 break;
1202 case TyTy::BOOL:
1203 return rtype->clone ();
1205 case TyTy::CHAR:
1206 case TyTy::INT:
1207 case TyTy::FLOAT:
1208 case TyTy::ISIZE:
1209 case TyTy::ADT:
1210 case TyTy::STR:
1211 case TyTy::REF:
1212 case TyTy::POINTER:
1213 case TyTy::PARAM:
1214 case TyTy::ARRAY:
1215 case TyTy::SLICE:
1216 case TyTy::FNDEF:
1217 case TyTy::FNPTR:
1218 case TyTy::TUPLE:
1219 case TyTy::UINT:
1220 case TyTy::USIZE:
1221 case TyTy::NEVER:
1222 case TyTy::PLACEHOLDER:
1223 case TyTy::PROJECTION:
1224 case TyTy::DYNAMIC:
1225 case TyTy::CLOSURE:
1226 case TyTy::ERROR:
1227 return new TyTy::ErrorType (0);
1229 return new TyTy::ErrorType (0);
1232 TyTy::BaseType *
1233 UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
1235 switch (rtype->get_kind ())
1237 case TyTy::INFER: {
1238 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1239 bool is_valid
1240 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1241 if (is_valid)
1243 r->apply_primitive_type_hint (*ltype);
1244 return ltype->clone ();
1247 break;
1249 case TyTy::CHAR:
1250 return rtype->clone ();
1252 case TyTy::INT:
1253 case TyTy::FLOAT:
1254 case TyTy::ISIZE:
1255 case TyTy::ADT:
1256 case TyTy::STR:
1257 case TyTy::REF:
1258 case TyTy::POINTER:
1259 case TyTy::PARAM:
1260 case TyTy::ARRAY:
1261 case TyTy::SLICE:
1262 case TyTy::FNDEF:
1263 case TyTy::FNPTR:
1264 case TyTy::TUPLE:
1265 case TyTy::BOOL:
1266 case TyTy::UINT:
1267 case TyTy::USIZE:
1268 case TyTy::NEVER:
1269 case TyTy::PLACEHOLDER:
1270 case TyTy::PROJECTION:
1271 case TyTy::DYNAMIC:
1272 case TyTy::CLOSURE:
1273 case TyTy::ERROR:
1274 return new TyTy::ErrorType (0);
1276 return new TyTy::ErrorType (0);
1279 TyTy::BaseType *
1280 UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
1282 switch (rtype->get_kind ())
1284 case TyTy::INFER: {
1285 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1286 bool is_valid
1287 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1288 || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
1289 if (is_valid)
1291 r->apply_primitive_type_hint (*ltype);
1292 return ltype->clone ();
1295 break;
1297 case TyTy::INT: {
1298 TyTy::IntType &type = *static_cast<TyTy::IntType *> (rtype);
1299 bool is_valid = ltype->get_int_kind () == type.get_int_kind ();
1300 if (is_valid)
1301 return new TyTy::IntType (type.get_ref (), type.get_ty_ref (),
1302 type.get_int_kind ());
1304 break;
1306 case TyTy::FLOAT:
1307 case TyTy::ISIZE:
1308 case TyTy::ADT:
1309 case TyTy::STR:
1310 case TyTy::REF:
1311 case TyTy::POINTER:
1312 case TyTy::PARAM:
1313 case TyTy::ARRAY:
1314 case TyTy::SLICE:
1315 case TyTy::FNDEF:
1316 case TyTy::FNPTR:
1317 case TyTy::TUPLE:
1318 case TyTy::BOOL:
1319 case TyTy::CHAR:
1320 case TyTy::UINT:
1321 case TyTy::USIZE:
1322 case TyTy::NEVER:
1323 case TyTy::PLACEHOLDER:
1324 case TyTy::PROJECTION:
1325 case TyTy::DYNAMIC:
1326 case TyTy::CLOSURE:
1327 case TyTy::ERROR:
1328 return new TyTy::ErrorType (0);
1330 return new TyTy::ErrorType (0);
1333 TyTy::BaseType *
1334 UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
1336 switch (rtype->get_kind ())
1338 case TyTy::INFER: {
1339 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1340 bool is_valid
1341 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1342 || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
1343 if (is_valid)
1345 r->apply_primitive_type_hint (*ltype);
1346 return ltype->clone ();
1349 break;
1351 case TyTy::UINT: {
1352 TyTy::UintType &type = *static_cast<TyTy::UintType *> (rtype);
1353 bool is_valid = ltype->get_uint_kind () == type.get_uint_kind ();
1354 if (is_valid)
1355 return new TyTy::UintType (type.get_ref (), type.get_ty_ref (),
1356 type.get_uint_kind ());
1358 break;
1360 case TyTy::FLOAT:
1361 case TyTy::ISIZE:
1362 case TyTy::ADT:
1363 case TyTy::STR:
1364 case TyTy::REF:
1365 case TyTy::POINTER:
1366 case TyTy::PARAM:
1367 case TyTy::ARRAY:
1368 case TyTy::SLICE:
1369 case TyTy::FNDEF:
1370 case TyTy::FNPTR:
1371 case TyTy::TUPLE:
1372 case TyTy::BOOL:
1373 case TyTy::CHAR:
1374 case TyTy::INT:
1375 case TyTy::USIZE:
1376 case TyTy::NEVER:
1377 case TyTy::PLACEHOLDER:
1378 case TyTy::PROJECTION:
1379 case TyTy::DYNAMIC:
1380 case TyTy::CLOSURE:
1381 case TyTy::ERROR:
1382 return new TyTy::ErrorType (0);
1384 return new TyTy::ErrorType (0);
1387 TyTy::BaseType *
1388 UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
1390 switch (rtype->get_kind ())
1392 case TyTy::INFER: {
1393 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1394 bool is_valid
1395 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1396 || r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT;
1397 if (is_valid)
1399 r->apply_primitive_type_hint (*ltype);
1400 return ltype->clone ();
1403 break;
1405 case TyTy::FLOAT: {
1406 TyTy::FloatType &type = *static_cast<TyTy::FloatType *> (rtype);
1407 bool is_valid = ltype->get_float_kind () == type.get_float_kind ();
1408 if (is_valid)
1409 return new TyTy::FloatType (type.get_ref (), type.get_ty_ref (),
1410 type.get_float_kind ());
1412 break;
1414 case TyTy::ISIZE:
1415 case TyTy::ADT:
1416 case TyTy::STR:
1417 case TyTy::REF:
1418 case TyTy::POINTER:
1419 case TyTy::PARAM:
1420 case TyTy::ARRAY:
1421 case TyTy::SLICE:
1422 case TyTy::FNDEF:
1423 case TyTy::FNPTR:
1424 case TyTy::TUPLE:
1425 case TyTy::BOOL:
1426 case TyTy::CHAR:
1427 case TyTy::INT:
1428 case TyTy::UINT:
1429 case TyTy::USIZE:
1430 case TyTy::NEVER:
1431 case TyTy::PLACEHOLDER:
1432 case TyTy::PROJECTION:
1433 case TyTy::DYNAMIC:
1434 case TyTy::CLOSURE:
1435 case TyTy::ERROR:
1436 return new TyTy::ErrorType (0);
1438 return new TyTy::ErrorType (0);
1441 TyTy::BaseType *
1442 UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
1444 switch (rtype->get_kind ())
1446 case TyTy::INFER: {
1447 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1448 bool is_valid
1449 = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
1450 if (is_valid)
1452 r->apply_primitive_type_hint (*ltype);
1453 return ltype->clone ();
1456 break;
1458 case TyTy::ISIZE:
1459 return rtype->clone ();
1461 case TyTy::ADT:
1462 case TyTy::STR:
1463 case TyTy::REF:
1464 case TyTy::POINTER:
1465 case TyTy::PARAM:
1466 case TyTy::ARRAY:
1467 case TyTy::SLICE:
1468 case TyTy::FNDEF:
1469 case TyTy::FNPTR:
1470 case TyTy::TUPLE:
1471 case TyTy::BOOL:
1472 case TyTy::CHAR:
1473 case TyTy::INT:
1474 case TyTy::UINT:
1475 case TyTy::FLOAT:
1476 case TyTy::USIZE:
1477 case TyTy::NEVER:
1478 case TyTy::PLACEHOLDER:
1479 case TyTy::PROJECTION:
1480 case TyTy::DYNAMIC:
1481 case TyTy::CLOSURE:
1482 case TyTy::ERROR:
1483 return new TyTy::ErrorType (0);
1485 return new TyTy::ErrorType (0);
1488 TyTy::BaseType *
1489 UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
1491 switch (rtype->get_kind ())
1493 case TyTy::INFER: {
1494 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1495 bool is_valid
1496 = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
1497 if (is_valid)
1499 r->apply_primitive_type_hint (*ltype);
1500 return ltype->clone ();
1503 break;
1505 case TyTy::USIZE:
1506 return rtype->clone ();
1508 case TyTy::ADT:
1509 case TyTy::STR:
1510 case TyTy::REF:
1511 case TyTy::POINTER:
1512 case TyTy::PARAM:
1513 case TyTy::ARRAY:
1514 case TyTy::SLICE:
1515 case TyTy::FNDEF:
1516 case TyTy::FNPTR:
1517 case TyTy::TUPLE:
1518 case TyTy::BOOL:
1519 case TyTy::CHAR:
1520 case TyTy::INT:
1521 case TyTy::UINT:
1522 case TyTy::FLOAT:
1523 case TyTy::ISIZE:
1524 case TyTy::NEVER:
1525 case TyTy::PLACEHOLDER:
1526 case TyTy::PROJECTION:
1527 case TyTy::DYNAMIC:
1528 case TyTy::CLOSURE:
1529 case TyTy::ERROR:
1530 return new TyTy::ErrorType (0);
1532 return new TyTy::ErrorType (0);
1535 TyTy::BaseType *
1536 UnifyRules::expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype)
1538 switch (rtype->get_kind ())
1540 case TyTy::INFER: {
1541 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1542 bool is_valid
1543 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1544 if (is_valid)
1545 return ltype->clone ();
1547 break;
1549 default:
1550 return rtype->clone ();
1552 return new TyTy::ErrorType (0);
1555 TyTy::BaseType *
1556 UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
1557 TyTy::BaseType *rtype)
1559 switch (rtype->get_kind ())
1561 case TyTy::INFER: {
1562 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1563 bool is_valid
1564 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1565 if (is_valid)
1566 return ltype->clone ();
1568 break;
1570 case TyTy::PLACEHOLDER:
1571 return ltype->clone ();
1573 case TyTy::PROJECTION:
1574 case TyTy::DYNAMIC:
1575 case TyTy::CLOSURE:
1576 case TyTy::SLICE:
1577 case TyTy::PARAM:
1578 case TyTy::POINTER:
1579 case TyTy::STR:
1580 case TyTy::ADT:
1581 case TyTy::REF:
1582 case TyTy::ARRAY:
1583 case TyTy::FNDEF:
1584 case TyTy::FNPTR:
1585 case TyTy::TUPLE:
1586 case TyTy::BOOL:
1587 case TyTy::CHAR:
1588 case TyTy::INT:
1589 case TyTy::UINT:
1590 case TyTy::FLOAT:
1591 case TyTy::USIZE:
1592 case TyTy::ISIZE:
1593 case TyTy::NEVER:
1594 if (infer_flag)
1595 return rtype->clone ();
1596 gcc_fallthrough ();
1598 case TyTy::ERROR:
1599 return new TyTy::ErrorType (0);
1601 return new TyTy::ErrorType (0);
1604 TyTy::BaseType *
1605 UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
1606 TyTy::BaseType *rtype)
1608 switch (rtype->get_kind ())
1610 case TyTy::INFER: {
1611 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1612 bool is_valid
1613 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1614 if (is_valid)
1615 return ltype->clone ();
1617 break;
1619 // FIXME
1620 case TyTy::PROJECTION:
1621 rust_unreachable ();
1622 break;
1624 case TyTy::DYNAMIC:
1625 case TyTy::CLOSURE:
1626 case TyTy::SLICE:
1627 case TyTy::PARAM:
1628 case TyTy::POINTER:
1629 case TyTy::STR:
1630 case TyTy::ADT:
1631 case TyTy::REF:
1632 case TyTy::ARRAY:
1633 case TyTy::FNDEF:
1634 case TyTy::FNPTR:
1635 case TyTy::TUPLE:
1636 case TyTy::BOOL:
1637 case TyTy::CHAR:
1638 case TyTy::INT:
1639 case TyTy::UINT:
1640 case TyTy::FLOAT:
1641 case TyTy::USIZE:
1642 case TyTy::ISIZE:
1643 case TyTy::NEVER:
1644 case TyTy::PLACEHOLDER:
1645 case TyTy::ERROR:
1646 return new TyTy::ErrorType (0);
1648 return new TyTy::ErrorType (0);
1651 TyTy::BaseType *
1652 UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
1654 switch (rtype->get_kind ())
1656 case TyTy::INFER: {
1657 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1658 bool is_valid
1659 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1660 if (is_valid)
1661 return ltype->clone ();
1663 break;
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 ();
1680 break;
1682 case TyTy::CLOSURE:
1683 case TyTy::SLICE:
1684 case TyTy::PARAM:
1685 case TyTy::POINTER:
1686 case TyTy::STR:
1687 case TyTy::ADT:
1688 case TyTy::REF:
1689 case TyTy::ARRAY:
1690 case TyTy::FNDEF:
1691 case TyTy::FNPTR:
1692 case TyTy::TUPLE:
1693 case TyTy::BOOL:
1694 case TyTy::CHAR:
1695 case TyTy::INT:
1696 case TyTy::UINT:
1697 case TyTy::FLOAT:
1698 case TyTy::USIZE:
1699 case TyTy::ISIZE:
1700 case TyTy::NEVER:
1701 case TyTy::PLACEHOLDER:
1702 case TyTy::PROJECTION:
1703 case TyTy::ERROR:
1704 return new TyTy::ErrorType (0);
1706 return new TyTy::ErrorType (0);
1709 TyTy::BaseType *
1710 UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
1712 switch (rtype->get_kind ())
1714 case TyTy::INFER: {
1715 TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1716 bool is_valid
1717 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1718 if (is_valid)
1719 return ltype->clone ();
1721 break;
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 (&ltype->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 (&ltype->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 ();
1750 break;
1752 case TyTy::SLICE:
1753 case TyTy::PARAM:
1754 case TyTy::POINTER:
1755 case TyTy::STR:
1756 case TyTy::ADT:
1757 case TyTy::REF:
1758 case TyTy::ARRAY:
1759 case TyTy::FNDEF:
1760 case TyTy::FNPTR:
1761 case TyTy::TUPLE:
1762 case TyTy::BOOL:
1763 case TyTy::CHAR:
1764 case TyTy::INT:
1765 case TyTy::UINT:
1766 case TyTy::FLOAT:
1767 case TyTy::USIZE:
1768 case TyTy::ISIZE:
1769 case TyTy::NEVER:
1770 case TyTy::PLACEHOLDER:
1771 case TyTy::PROJECTION:
1772 case TyTy::DYNAMIC:
1773 case TyTy::ERROR:
1774 return new TyTy::ErrorType (0);
1776 return new TyTy::ErrorType (0);
1779 } // namespace Resolver
1780 } // namespace Rust