Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
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.
9 :
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.
14 :
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/>.
18 :
19 : #include "rust-unify.h"
20 : #include "fold-const.h"
21 : #include "rust-tyty-util.h"
22 : #include "rust-tyty.h"
23 :
24 : namespace Rust {
25 : namespace Resolver {
26 :
27 : static TyTy::BaseType *
28 1589163 : unify_error_type_node ()
29 : {
30 1589163 : static TyTy::BaseType *error = nullptr;
31 1589163 : if (error == nullptr)
32 1056 : error = new TyTy::ErrorType (0);
33 1589163 : return error;
34 : }
35 :
36 2213200 : UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
37 : location_t locus, bool commit_flag, bool emit_error,
38 : bool check_bounds, bool infer,
39 : std::vector<CommitSite> &commits,
40 2213200 : std::vector<InferenceSite> &infers)
41 2213200 : : lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
42 2213200 : emit_error (emit_error), infer_flag (infer),
43 2213200 : check_bounds_flag (check_bounds), commits (commits), infers (infers),
44 2213200 : mappings (Analysis::Mappings::get ()), context (*TypeCheckContext::get ())
45 2213200 : {}
46 :
47 : TyTy::BaseType *
48 2213200 : UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
49 : location_t locus, bool commit_flag, bool emit_error,
50 : bool check_bounds, bool infer,
51 : std::vector<CommitSite> &commits,
52 : std::vector<InferenceSite> &infers)
53 : {
54 2213200 : UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, check_bounds,
55 2213200 : commits, infers);
56 :
57 2213200 : TyTy::BaseType *result = r.go ();
58 2213200 : bool failed = result->get_kind () == TyTy::TypeKind::ERROR;
59 :
60 2213200 : commits.emplace_back (lhs.get_ty (), rhs.get_ty (), result);
61 2213200 : if (r.commit_flag && !failed)
62 : {
63 47091 : result = result->clone ();
64 47091 : UnifyRules::commit (lhs.get_ty (), rhs.get_ty (), result);
65 : }
66 :
67 2213200 : if (failed && r.emit_error)
68 68 : r.emit_type_mismatch ();
69 :
70 2213200 : return result;
71 : }
72 :
73 : TyTy::BaseType *
74 175351 : UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs)
75 : {
76 175351 : TyTy::BaseType *result
77 350702 : = UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, infer_flag,
78 175351 : check_bounds_flag, commits, infers);
79 :
80 : // If the recursive call resulted in an error and would have emitted an error
81 : // message, disable error emission for the current level to avoid duplicate
82 : // errors
83 175351 : if (result->get_kind () == TyTy::TypeKind::ERROR && emit_error)
84 13 : emit_error = false;
85 :
86 175351 : return result;
87 : }
88 :
89 : TyTy::BaseType *
90 0 : UnifyRules::get_base ()
91 : {
92 0 : return lhs.get_ty ()->destructure ();
93 : }
94 :
95 : TyTy::BaseType *
96 0 : UnifyRules::get_other ()
97 : {
98 0 : return rhs.get_ty ()->destructure ();
99 : }
100 :
101 : void
102 162594 : UnifyRules::commit (TyTy::BaseType *base, TyTy::BaseType *other,
103 : TyTy::BaseType *resolved)
104 : {
105 162594 : TypeCheckContext &context = *TypeCheckContext::get ();
106 :
107 162594 : TyTy::BaseType *b = base->destructure ();
108 162594 : TyTy::BaseType *o = other->destructure ();
109 :
110 162594 : resolved->append_reference (b->get_ref ());
111 162594 : resolved->append_reference (o->get_ref ());
112 1187143 : for (auto ref : b->get_combined_refs ())
113 1024549 : resolved->append_reference (ref);
114 1150181 : for (auto ref : o->get_combined_refs ())
115 987587 : resolved->append_reference (ref);
116 :
117 162594 : o->append_reference (resolved->get_ref ());
118 162594 : o->append_reference (b->get_ref ());
119 162594 : b->append_reference (resolved->get_ref ());
120 162594 : b->append_reference (o->get_ref ());
121 :
122 162594 : if (resolved->get_kind () != TyTy::TypeKind::CONST)
123 : {
124 161040 : bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
125 161040 : bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
126 161040 : bool results_is_non_general_infer_var
127 : = (result_is_infer_var
128 161040 : && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
129 316743 : != TyTy::InferType::GENERAL);
130 155883 : if (result_resolved || results_is_non_general_infer_var)
131 : {
132 1492228 : for (auto &ref : resolved->get_combined_refs ())
133 : {
134 1331368 : TyTy::BaseType *ref_tyty = nullptr;
135 1331368 : bool ok = context.lookup_type (ref, &ref_tyty);
136 1331368 : if (!ok)
137 3446 : continue;
138 :
139 : // if any of the types are inference variables lets fix them
140 1327922 : if (ref_tyty->is<TyTy::InferType> ())
141 75335 : context.insert_implicit_type (ref, resolved);
142 160860 : }
143 : }
144 : }
145 : else
146 : {
147 1554 : auto base_const = resolved->as_const_type ();
148 1554 : if (base_const->const_kind () == TyTy::BaseConstType::ConstKind::Value)
149 : {
150 1533 : rust_debug ("UnifyRules::commit const value, resolved_ref=%u "
151 : "resolved_ty_ref=%u combined_refs.size=%zu",
152 : resolved->get_ref (), resolved->get_ty_ref (),
153 : resolved->get_combined_refs ().size ());
154 :
155 4524 : for (auto &ref : resolved->get_combined_refs ())
156 : {
157 2991 : TyTy::BaseType *ref_tyty = nullptr;
158 2991 : bool ok = context.lookup_type (ref, &ref_tyty);
159 2991 : if (!ok)
160 0 : continue;
161 2991 : if (ref_tyty->get_kind () != TyTy::TypeKind::CONST)
162 0 : continue;
163 :
164 2991 : auto ref_base_const = ref_tyty->as_const_type ();
165 2991 : if (ref_base_const->const_kind ()
166 : == TyTy::BaseConstType::ConstKind::Infer
167 2991 : || ref_base_const->const_kind ()
168 : == TyTy::BaseConstType::ConstKind::Decl)
169 : {
170 56 : rust_debug (" committing to ref=%u kind=%d", ref,
171 : (int) ref_base_const->const_kind ());
172 56 : context.insert_implicit_type (ref, resolved);
173 : }
174 1533 : }
175 : }
176 : }
177 162594 : }
178 :
179 : void
180 68 : UnifyRules::emit_type_mismatch () const
181 : {
182 68 : TyTy::BaseType *expected = lhs.get_ty ();
183 68 : TyTy::BaseType *expr = rhs.get_ty ();
184 :
185 68 : rich_location r (line_table, locus);
186 68 : r.add_range (lhs.get_locus ());
187 68 : r.add_range (rhs.get_locus ());
188 68 : rust_error_at (r, ErrorCode::E0308,
189 : "mismatched types, expected %qs but got %qs",
190 136 : expected->get_name ().c_str (), expr->get_name ().c_str ());
191 68 : }
192 :
193 : void
194 0 : UnifyRules::emit_abi_mismatch (const TyTy::FnType &expected,
195 : const TyTy::FnType &got) const
196 : {
197 0 : rich_location r (line_table, locus);
198 0 : r.add_range (lhs.get_locus ());
199 0 : r.add_range (rhs.get_locus ());
200 0 : rust_error_at (r, "mistached abi %qs got %qs",
201 0 : get_string_from_abi (expected.get_abi ()).c_str (),
202 0 : get_string_from_abi (got.get_abi ()).c_str ());
203 0 : }
204 :
205 : TyTy::BaseType *
206 2213200 : UnifyRules::go ()
207 : {
208 2213200 : TyTy::BaseType *ltype = lhs.get_ty ()->destructure ();
209 2213200 : TyTy::BaseType *rtype = rhs.get_ty ()->destructure ();
210 :
211 2213200 : rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
212 : rtype->debug_str ().c_str ());
213 :
214 2213200 : if (check_bounds_flag)
215 : {
216 318631 : bool ltype_is_placeholder
217 318631 : = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
218 318631 : bool rtype_is_placeholder
219 318631 : = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
220 318631 : bool types_equal = ltype->is_equal (*rtype);
221 2655228 : bool should_check_bounds
222 318631 : = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
223 130226 : if (should_check_bounds)
224 : {
225 130226 : if (ltype->num_specified_bounds () > 0)
226 : {
227 31266 : if (!ltype->bounds_compatible (*rtype, locus, emit_error))
228 : {
229 : // already emitted an error
230 2811 : emit_error = false;
231 2811 : return unify_error_type_node ();
232 : }
233 : }
234 98960 : else if (rtype->num_specified_bounds () > 0)
235 : {
236 23561 : if (!rtype->bounds_compatible (*ltype, locus, emit_error))
237 : {
238 : // already emitted an error
239 4018 : emit_error = false;
240 4018 : return unify_error_type_node ();
241 : }
242 : }
243 : }
244 : }
245 :
246 2206371 : if (infer_flag)
247 : {
248 2099077 : bool rgot_param = rtype->get_kind () == TyTy::TypeKind::PARAM;
249 2099077 : bool lhs_is_infer_var = ltype->get_kind () == TyTy::TypeKind::INFER;
250 2099077 : bool lhs_is_general_infer_var
251 : = lhs_is_infer_var
252 2099077 : && static_cast<TyTy::InferType *> (ltype)->get_infer_kind ()
253 2099077 : == TyTy::InferType::GENERAL;
254 2099077 : bool expected_is_concrete
255 2099077 : = ltype->is_concrete () && !lhs_is_general_infer_var;
256 2099077 : bool rneeds_infer = expected_is_concrete && (rgot_param);
257 :
258 2099077 : bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM;
259 2099077 : bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER;
260 2099077 : bool rhs_is_general_infer_var
261 : = rhs_is_infer_var
262 2099077 : && static_cast<TyTy::InferType *> (rtype)->get_infer_kind ()
263 2099077 : == TyTy::InferType::GENERAL;
264 2099077 : bool receiver_is_concrete
265 2099077 : = rtype->is_concrete () && !rhs_is_general_infer_var;
266 2099077 : bool lneeds_infer = receiver_is_concrete && (lgot_param);
267 :
268 2099077 : if (rneeds_infer)
269 : {
270 72462 : TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype);
271 72462 : TyTy::TyVar iv
272 72462 : = TyTy::TyVar::get_implicit_infer_var (rhs.get_locus ());
273 72462 : rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
274 72462 : TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
275 :
276 72462 : infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
277 :
278 : // FIXME
279 : // this is hacky to set the implicit param lets make this a function
280 72462 : p->set_ty_ref (i->get_ref ());
281 :
282 : // set the rtype now to the new inference var
283 72462 : rtype = i;
284 : }
285 2026615 : else if (lneeds_infer)
286 : {
287 12447 : TyTy::ParamType *p = static_cast<TyTy::ParamType *> (ltype);
288 12447 : TyTy::TyVar iv
289 12447 : = TyTy::TyVar::get_implicit_infer_var (lhs.get_locus ());
290 12447 : rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
291 12447 : TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
292 :
293 12447 : infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
294 :
295 : // FIXME
296 : // this is hacky to set the implicit param lets make this a function
297 12447 : p->set_ty_ref (i->get_ref ());
298 :
299 : // set the rtype now to the new inference var
300 12447 : ltype = i;
301 : }
302 2014168 : else if (ltype->get_kind () == TyTy::TypeKind::CONST
303 2014168 : && rtype->get_kind () == TyTy::TypeKind::CONST)
304 : {
305 1007 : auto lhs = ltype->as_const_type ();
306 1007 : auto rhs = rtype->as_const_type ();
307 :
308 1007 : bool both_are_decls
309 1007 : = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
310 1007 : && rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
311 1007 : bool have_decls
312 1007 : = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
313 1007 : || rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
314 :
315 1007 : if (have_decls && !both_are_decls)
316 : {
317 49 : if (lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
318 : {
319 7 : auto l = lhs->as_base_type ()->get_locus ();
320 7 : auto p = static_cast<TyTy::ConstParamType *> (lhs);
321 7 : auto it = TyTy::TyVar::get_implicit_infer_var (l);
322 7 : auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
323 7 : auto ivt = iv.get_tyty ();
324 :
325 7 : infers.emplace_back (0, 0, nullptr, it.get_tyty ());
326 7 : infers.emplace_back (ltype->get_ref (), ltype->get_ty_ref (),
327 : p, ivt);
328 :
329 7 : ltype = ivt;
330 7 : p->set_ty_ref (ltype->get_ref ());
331 : }
332 42 : else if (rhs->const_kind ()
333 : == TyTy::BaseConstType::ConstKind::Decl)
334 : {
335 42 : auto l = rhs->as_base_type ()->get_locus ();
336 42 : auto p = static_cast<TyTy::ConstParamType *> (rhs);
337 42 : auto it = TyTy::TyVar::get_implicit_infer_var (l);
338 42 : auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
339 42 : auto ivt = iv.get_tyty ();
340 :
341 42 : infers.emplace_back (0, 0, nullptr, it.get_tyty ());
342 42 : infers.emplace_back (rtype->get_ref (), rtype->get_ty_ref (),
343 : p, ivt);
344 :
345 42 : rtype = ivt;
346 42 : p->set_ty_ref (rtype->get_ref ());
347 : }
348 : }
349 : }
350 : }
351 :
352 2206371 : if (ltype->get_kind () != TyTy::TypeKind::CONST
353 2206371 : && rtype->get_kind () == TyTy::TypeKind::CONST)
354 : {
355 28 : auto *rc = rtype->as_const_type ();
356 28 : rtype = rc->get_specified_type ();
357 : }
358 :
359 2206371 : if (ltype->get_kind () == TyTy::TypeKind::CONST
360 2206371 : && rtype->get_kind () != TyTy::TypeKind::CONST)
361 : {
362 0 : auto *lc = ltype->as_const_type ();
363 0 : ltype = lc->get_specified_type ();
364 : }
365 :
366 2206371 : switch (ltype->get_kind ())
367 : {
368 46940 : case TyTy::INFER:
369 46940 : return expect_inference_variable (static_cast<TyTy::InferType *> (ltype),
370 46940 : rtype);
371 :
372 232494 : case TyTy::ADT:
373 232494 : return expect_adt (static_cast<TyTy::ADTType *> (ltype), rtype);
374 :
375 6982 : case TyTy::STR:
376 6982 : return expect_str (static_cast<TyTy::StrType *> (ltype), rtype);
377 :
378 64719 : case TyTy::REF:
379 64719 : return expect_reference (static_cast<TyTy::ReferenceType *> (ltype),
380 64719 : rtype);
381 :
382 20403 : case TyTy::POINTER:
383 20403 : return expect_pointer (static_cast<TyTy::PointerType *> (ltype), rtype);
384 :
385 19824 : case TyTy::PARAM:
386 19824 : return expect_param (static_cast<TyTy::ParamType *> (ltype), rtype);
387 :
388 13438 : case TyTy::ARRAY:
389 13438 : return expect_array (static_cast<TyTy::ArrayType *> (ltype), rtype);
390 :
391 4314 : case TyTy::SLICE:
392 4314 : return expect_slice (static_cast<TyTy::SliceType *> (ltype), rtype);
393 :
394 4331 : case TyTy::FNDEF:
395 4331 : return expect_fndef (static_cast<TyTy::FnType *> (ltype), rtype);
396 :
397 336 : case TyTy::FNPTR:
398 336 : return expect_fnptr (static_cast<TyTy::FnPtr *> (ltype), rtype);
399 :
400 12072 : case TyTy::TUPLE:
401 12072 : return expect_tuple (static_cast<TyTy::TupleType *> (ltype), rtype);
402 :
403 19958 : case TyTy::BOOL:
404 19958 : return expect_bool (static_cast<TyTy::BoolType *> (ltype), rtype);
405 :
406 9791 : case TyTy::CHAR:
407 9791 : return expect_char (static_cast<TyTy::CharType *> (ltype), rtype);
408 :
409 305498 : case TyTy::INT:
410 305498 : return expect_int (static_cast<TyTy::IntType *> (ltype), rtype);
411 :
412 885026 : case TyTy::UINT:
413 885026 : return expect_uint (static_cast<TyTy::UintType *> (ltype), rtype);
414 :
415 65144 : case TyTy::FLOAT:
416 65144 : return expect_float (static_cast<TyTy::FloatType *> (ltype), rtype);
417 :
418 391491 : case TyTy::USIZE:
419 391491 : return expect_usize (static_cast<TyTy::USizeType *> (ltype), rtype);
420 :
421 69048 : case TyTy::ISIZE:
422 69048 : return expect_isize (static_cast<TyTy::ISizeType *> (ltype), rtype);
423 :
424 4844 : case TyTy::NEVER:
425 4844 : return expect_never (static_cast<TyTy::NeverType *> (ltype), rtype);
426 :
427 14788 : case TyTy::PLACEHOLDER:
428 14788 : return expect_placeholder (static_cast<TyTy::PlaceholderType *> (ltype),
429 14788 : rtype);
430 :
431 0 : case TyTy::PROJECTION:
432 0 : return expect_projection (static_cast<TyTy::ProjectionType *> (ltype),
433 0 : rtype);
434 :
435 12916 : case TyTy::DYNAMIC:
436 12916 : return expect_dyn (static_cast<TyTy::DynamicObjectType *> (ltype), rtype);
437 :
438 168 : case TyTy::CLOSURE:
439 168 : return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype);
440 :
441 56 : case TyTy::OPAQUE:
442 56 : return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
443 :
444 1786 : case TyTy::CONST:
445 1786 : return expect_const (ltype->as_const_type (), rtype);
446 :
447 4 : case TyTy::ERROR:
448 4 : return unify_error_type_node ();
449 : }
450 :
451 0 : return unify_error_type_node ();
452 : }
453 :
454 : TyTy::BaseType *
455 46940 : UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
456 : TyTy::BaseType *rtype)
457 : {
458 46940 : switch (rtype->get_kind ())
459 : {
460 6425 : case TyTy::INFER:
461 6425 : {
462 6425 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
463 6425 : switch (ltype->get_infer_kind ())
464 : {
465 : case TyTy::InferType::InferTypeKind::GENERAL:
466 : return rtype;
467 :
468 4542 : case TyTy::InferType::InferTypeKind::INTEGRAL:
469 4542 : {
470 4542 : bool is_valid = r->get_infer_kind ()
471 : == TyTy::InferType::InferTypeKind::INTEGRAL
472 4542 : || r->get_infer_kind ()
473 4964 : == TyTy::InferType::InferTypeKind::GENERAL;
474 4540 : if (is_valid)
475 4540 : return rtype;
476 : }
477 : break;
478 :
479 31 : case TyTy::InferType::InferTypeKind::FLOAT:
480 31 : {
481 31 : bool is_valid
482 31 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
483 31 : || r->get_infer_kind ()
484 455 : == TyTy::InferType::InferTypeKind::GENERAL;
485 31 : if (is_valid)
486 31 : return rtype;
487 : }
488 : break;
489 : }
490 : }
491 : break;
492 :
493 23435 : case TyTy::INT:
494 23435 : case TyTy::UINT:
495 23435 : case TyTy::USIZE:
496 23435 : case TyTy::ISIZE:
497 23435 : {
498 23435 : bool is_valid = (ltype->get_infer_kind ()
499 : == TyTy::InferType::InferTypeKind::GENERAL)
500 23435 : || (ltype->get_infer_kind ()
501 23859 : == TyTy::InferType::InferTypeKind::INTEGRAL);
502 23435 : if (is_valid)
503 : {
504 23435 : if (commit_flag)
505 2492 : ltype->apply_primitive_type_hint (*rtype);
506 23435 : return rtype;
507 : }
508 : }
509 : break;
510 :
511 4268 : case TyTy::FLOAT:
512 4268 : {
513 4268 : bool is_valid = (ltype->get_infer_kind ()
514 : == TyTy::InferType::InferTypeKind::GENERAL)
515 4268 : || (ltype->get_infer_kind ()
516 4564 : == TyTy::InferType::InferTypeKind::FLOAT);
517 4140 : if (is_valid)
518 : {
519 4140 : if (commit_flag)
520 81 : ltype->apply_primitive_type_hint (*rtype);
521 4140 : return rtype;
522 : }
523 : }
524 : break;
525 :
526 12812 : case TyTy::ADT:
527 12812 : case TyTy::STR:
528 12812 : case TyTy::REF:
529 12812 : case TyTy::POINTER:
530 12812 : case TyTy::PARAM:
531 12812 : case TyTy::ARRAY:
532 12812 : case TyTy::SLICE:
533 12812 : case TyTy::FNDEF:
534 12812 : case TyTy::FNPTR:
535 12812 : case TyTy::TUPLE:
536 12812 : case TyTy::BOOL:
537 12812 : case TyTy::CHAR:
538 12812 : case TyTy::NEVER:
539 12812 : case TyTy::PLACEHOLDER:
540 12812 : case TyTy::PROJECTION:
541 12812 : case TyTy::DYNAMIC:
542 12812 : case TyTy::CLOSURE:
543 12812 : case TyTy::CONST:
544 12812 : case TyTy::OPAQUE:
545 12812 : {
546 12812 : bool is_valid = (ltype->get_infer_kind ()
547 12812 : == TyTy::InferType::InferTypeKind::GENERAL);
548 12812 : if (is_valid)
549 : return rtype;
550 : }
551 : break;
552 :
553 0 : case TyTy::ERROR:
554 0 : return unify_error_type_node ();
555 : }
556 :
557 424 : return unify_error_type_node ();
558 : }
559 :
560 : TyTy::BaseType *
561 232494 : UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
562 : {
563 232494 : switch (rtype->get_kind ())
564 : {
565 2982 : case TyTy::INFER:
566 2982 : {
567 2982 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
568 2982 : bool is_valid
569 2982 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
570 2982 : if (is_valid)
571 : return ltype;
572 : }
573 : break;
574 :
575 109116 : case TyTy::ADT:
576 109116 : {
577 109116 : TyTy::ADTType &type = *static_cast<TyTy::ADTType *> (rtype);
578 109116 : if (ltype->get_adt_kind () != type.get_adt_kind ())
579 : {
580 22350 : return unify_error_type_node ();
581 : }
582 :
583 260298 : if (ltype->get_identifier ().compare (type.get_identifier ()) != 0)
584 : {
585 16701 : return unify_error_type_node ();
586 : }
587 :
588 70065 : if (ltype->number_of_variants () != type.number_of_variants ())
589 : {
590 0 : return unify_error_type_node ();
591 : }
592 :
593 162346 : for (size_t i = 0; i < type.number_of_variants (); ++i)
594 : {
595 92442 : TyTy::VariantDef *a = ltype->get_variants ().at (i);
596 92442 : TyTy::VariantDef *b = type.get_variants ().at (i);
597 :
598 92442 : if (a->num_fields () != b->num_fields ())
599 : {
600 0 : return unify_error_type_node ();
601 : }
602 :
603 196866 : for (size_t j = 0; j < a->num_fields (); j++)
604 : {
605 104585 : TyTy::StructFieldType *base_field = a->get_field_at_index (j);
606 104585 : TyTy::StructFieldType *other_field = b->get_field_at_index (j);
607 :
608 104585 : TyTy::BaseType *this_field_ty = base_field->get_field_type ();
609 104585 : TyTy::BaseType *other_field_ty = other_field->get_field_type ();
610 :
611 104585 : TyTy::BaseType *unified_ty
612 104585 : = resolve_subtype (TyTy::TyWithLocation (this_field_ty),
613 104585 : TyTy::TyWithLocation (other_field_ty));
614 104585 : if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
615 : {
616 161 : return unify_error_type_node ();
617 : }
618 : }
619 : }
620 :
621 : // generic args for the unit-struct case
622 69904 : if (type.is_unit () && ltype->is_unit ())
623 : {
624 8982 : rust_assert (type.get_num_substitutions ()
625 : == ltype->get_num_substitutions ());
626 :
627 11107 : for (size_t i = 0; i < type.get_num_substitutions (); i++)
628 : {
629 2181 : auto &a = ltype->get_substs ().at (i);
630 2181 : auto &b = type.get_substs ().at (i);
631 :
632 2181 : auto pa = a.get_param_ty ();
633 2181 : auto pb = b.get_param_ty ();
634 :
635 2181 : auto res = resolve_subtype (TyTy::TyWithLocation (pa),
636 2181 : TyTy::TyWithLocation (pb));
637 2181 : if (res->get_kind () == TyTy::TypeKind::ERROR)
638 : {
639 56 : return unify_error_type_node ();
640 : }
641 : }
642 : }
643 :
644 : return ltype;
645 : }
646 120396 : break;
647 :
648 120396 : case TyTy::STR:
649 120396 : case TyTy::REF:
650 120396 : case TyTy::POINTER:
651 120396 : case TyTy::PARAM:
652 120396 : case TyTy::ARRAY:
653 120396 : case TyTy::SLICE:
654 120396 : case TyTy::FNDEF:
655 120396 : case TyTy::FNPTR:
656 120396 : case TyTy::TUPLE:
657 120396 : case TyTy::BOOL:
658 120396 : case TyTy::CHAR:
659 120396 : case TyTy::INT:
660 120396 : case TyTy::UINT:
661 120396 : case TyTy::FLOAT:
662 120396 : case TyTy::USIZE:
663 120396 : case TyTy::ISIZE:
664 120396 : case TyTy::NEVER:
665 120396 : case TyTy::PLACEHOLDER:
666 120396 : case TyTy::PROJECTION:
667 120396 : case TyTy::DYNAMIC:
668 120396 : case TyTy::CLOSURE:
669 120396 : case TyTy::OPAQUE:
670 120396 : case TyTy::CONST:
671 120396 : case TyTy::ERROR:
672 120396 : return unify_error_type_node ();
673 : }
674 0 : return unify_error_type_node ();
675 : }
676 :
677 : TyTy::BaseType *
678 6982 : UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
679 : {
680 6982 : switch (rtype->get_kind ())
681 : {
682 0 : case TyTy::INFER:
683 0 : {
684 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
685 0 : bool is_valid
686 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
687 0 : if (is_valid)
688 : return ltype;
689 : }
690 : break;
691 :
692 : case TyTy::STR:
693 : return rtype;
694 :
695 28 : case TyTy::ADT:
696 28 : case TyTy::REF:
697 28 : case TyTy::POINTER:
698 28 : case TyTy::PARAM:
699 28 : case TyTy::ARRAY:
700 28 : case TyTy::SLICE:
701 28 : case TyTy::FNDEF:
702 28 : case TyTy::FNPTR:
703 28 : case TyTy::TUPLE:
704 28 : case TyTy::BOOL:
705 28 : case TyTy::CHAR:
706 28 : case TyTy::INT:
707 28 : case TyTy::UINT:
708 28 : case TyTy::FLOAT:
709 28 : case TyTy::USIZE:
710 28 : case TyTy::ISIZE:
711 28 : case TyTy::NEVER:
712 28 : case TyTy::PLACEHOLDER:
713 28 : case TyTy::PROJECTION:
714 28 : case TyTy::DYNAMIC:
715 28 : case TyTy::CLOSURE:
716 28 : case TyTy::OPAQUE:
717 28 : case TyTy::CONST:
718 28 : case TyTy::ERROR:
719 28 : return unify_error_type_node ();
720 : }
721 0 : return unify_error_type_node ();
722 : }
723 :
724 : TyTy::BaseType *
725 64719 : UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
726 : {
727 64719 : switch (rtype->get_kind ())
728 : {
729 259 : case TyTy::INFER:
730 259 : {
731 259 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
732 259 : bool is_valid
733 259 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
734 259 : if (is_valid)
735 : return ltype;
736 : }
737 : break;
738 :
739 32219 : case TyTy::REF:
740 32219 : {
741 32219 : TyTy::ReferenceType &type = *static_cast<TyTy::ReferenceType *> (rtype);
742 32219 : auto base_type = ltype->get_base ();
743 32219 : auto other_base_type = type.get_base ();
744 :
745 32219 : TyTy::BaseType *base_resolved
746 32219 : = resolve_subtype (TyTy::TyWithLocation (base_type),
747 32219 : TyTy::TyWithLocation (other_base_type));
748 32219 : if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
749 : {
750 10154 : return unify_error_type_node ();
751 : }
752 :
753 : // rust is permissive about mutablity here you can always go from
754 : // mutable to immutable but not the otherway round
755 22065 : bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
756 1240 : if (!mutability_ok)
757 : {
758 83 : return unify_error_type_node ();
759 : }
760 :
761 : return ltype;
762 : }
763 32241 : break;
764 :
765 32241 : case TyTy::STR:
766 32241 : case TyTy::ADT:
767 32241 : case TyTy::POINTER:
768 32241 : case TyTy::PARAM:
769 32241 : case TyTy::ARRAY:
770 32241 : case TyTy::SLICE:
771 32241 : case TyTy::FNDEF:
772 32241 : case TyTy::FNPTR:
773 32241 : case TyTy::TUPLE:
774 32241 : case TyTy::BOOL:
775 32241 : case TyTy::CHAR:
776 32241 : case TyTy::INT:
777 32241 : case TyTy::UINT:
778 32241 : case TyTy::FLOAT:
779 32241 : case TyTy::USIZE:
780 32241 : case TyTy::ISIZE:
781 32241 : case TyTy::NEVER:
782 32241 : case TyTy::PLACEHOLDER:
783 32241 : case TyTy::PROJECTION:
784 32241 : case TyTy::DYNAMIC:
785 32241 : case TyTy::CLOSURE:
786 32241 : case TyTy::OPAQUE:
787 32241 : case TyTy::CONST:
788 32241 : case TyTy::ERROR:
789 32241 : return unify_error_type_node ();
790 : }
791 7 : return unify_error_type_node ();
792 : }
793 :
794 : TyTy::BaseType *
795 20403 : UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
796 : {
797 20403 : switch (rtype->get_kind ())
798 : {
799 0 : case TyTy::INFER:
800 0 : {
801 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
802 0 : bool is_valid
803 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
804 0 : if (is_valid)
805 : return ltype;
806 : }
807 : break;
808 :
809 15249 : case TyTy::POINTER:
810 15249 : {
811 15249 : TyTy::PointerType &type = *static_cast<TyTy::PointerType *> (rtype);
812 15249 : auto base_type = ltype->get_base ();
813 15249 : auto other_base_type = type.get_base ();
814 :
815 15249 : TyTy::BaseType *base_resolved
816 15249 : = resolve_subtype (TyTy::TyWithLocation (base_type),
817 15249 : TyTy::TyWithLocation (other_base_type));
818 15249 : if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
819 : {
820 161 : return unify_error_type_node ();
821 : }
822 :
823 : // rust is permissive about mutablity here you can always go from
824 : // mutable to immutable but not the otherway round
825 15088 : bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
826 1785 : if (!mutability_ok)
827 : {
828 28 : return unify_error_type_node ();
829 : }
830 :
831 : return ltype;
832 : }
833 5154 : break;
834 :
835 5154 : case TyTy::STR:
836 5154 : case TyTy::ADT:
837 5154 : case TyTy::REF:
838 5154 : case TyTy::PARAM:
839 5154 : case TyTy::ARRAY:
840 5154 : case TyTy::SLICE:
841 5154 : case TyTy::FNDEF:
842 5154 : case TyTy::FNPTR:
843 5154 : case TyTy::TUPLE:
844 5154 : case TyTy::BOOL:
845 5154 : case TyTy::CHAR:
846 5154 : case TyTy::INT:
847 5154 : case TyTy::UINT:
848 5154 : case TyTy::FLOAT:
849 5154 : case TyTy::USIZE:
850 5154 : case TyTy::ISIZE:
851 5154 : case TyTy::NEVER:
852 5154 : case TyTy::PLACEHOLDER:
853 5154 : case TyTy::PROJECTION:
854 5154 : case TyTy::DYNAMIC:
855 5154 : case TyTy::CLOSURE:
856 5154 : case TyTy::OPAQUE:
857 5154 : case TyTy::CONST:
858 5154 : case TyTy::ERROR:
859 5154 : return unify_error_type_node ();
860 : }
861 0 : return unify_error_type_node ();
862 : }
863 :
864 : TyTy::BaseType *
865 19824 : UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
866 : {
867 19824 : switch (rtype->get_kind ())
868 : {
869 400 : case TyTy::INFER:
870 400 : {
871 400 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
872 400 : bool is_valid
873 400 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
874 400 : if (is_valid)
875 : return ltype;
876 : }
877 : break;
878 :
879 19043 : case TyTy::PARAM:
880 19043 : {
881 19043 : TyTy::ParamType &type = *static_cast<TyTy::ParamType *> (rtype);
882 : // bool symbol_matches
883 : // = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
884 : // // TODO
885 : // // I think rustc checks a debruinj index
886 : // if (symbol_matches)
887 : // {
888 : // return type.clone ();
889 : // }
890 :
891 : // matching symbol is not going to work when we mix symbol's and have
892 : // nested generics
893 :
894 : // bounds match? FIXME
895 :
896 19043 : return type.clone ();
897 : }
898 381 : break;
899 :
900 381 : case TyTy::POINTER:
901 381 : case TyTy::STR:
902 381 : case TyTy::ADT:
903 381 : case TyTy::REF:
904 381 : case TyTy::ARRAY:
905 381 : case TyTy::SLICE:
906 381 : case TyTy::FNDEF:
907 381 : case TyTy::FNPTR:
908 381 : case TyTy::TUPLE:
909 381 : case TyTy::BOOL:
910 381 : case TyTy::CHAR:
911 381 : case TyTy::INT:
912 381 : case TyTy::UINT:
913 381 : case TyTy::FLOAT:
914 381 : case TyTy::USIZE:
915 381 : case TyTy::ISIZE:
916 381 : case TyTy::NEVER:
917 381 : case TyTy::PLACEHOLDER:
918 381 : case TyTy::PROJECTION:
919 381 : case TyTy::DYNAMIC:
920 381 : case TyTy::CLOSURE:
921 381 : case TyTy::OPAQUE:
922 381 : case TyTy::CONST:
923 381 : case TyTy::ERROR:
924 381 : return unify_error_type_node ();
925 : }
926 0 : return unify_error_type_node ();
927 : }
928 :
929 : TyTy::BaseType *
930 13438 : UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
931 : {
932 13438 : switch (rtype->get_kind ())
933 : {
934 736 : case TyTy::INFER:
935 736 : {
936 736 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
937 736 : bool is_valid
938 736 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
939 736 : if (is_valid)
940 : return ltype;
941 : }
942 : break;
943 :
944 1599 : case TyTy::ARRAY:
945 1599 : {
946 1599 : TyTy::ArrayType &type = *static_cast<TyTy::ArrayType *> (rtype);
947 1599 : TyTy::BaseType *element_unify
948 1599 : = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
949 1599 : TyTy::TyWithLocation (type.get_element_type ()));
950 :
951 1599 : if (element_unify->get_kind () == TyTy::TypeKind::ERROR)
952 0 : return unify_error_type_node ();
953 :
954 1599 : auto ltype_cap = ltype->get_capacity ();
955 1599 : auto rtype_cap = type.get_capacity ();
956 :
957 : // If either capacity is not a const type, return error
958 1599 : if (ltype_cap->get_kind () != TyTy::TypeKind::CONST
959 1599 : || rtype_cap->get_kind () != TyTy::TypeKind::CONST)
960 1 : return unify_error_type_node ();
961 :
962 1598 : bool save_emit_error = emit_error;
963 1598 : emit_error = false;
964 1598 : TyTy::BaseType *capacity_unify
965 1598 : = resolve_subtype (TyTy::TyWithLocation (ltype_cap),
966 1598 : TyTy::TyWithLocation (rtype_cap));
967 1598 : emit_error = save_emit_error;
968 :
969 1598 : if (capacity_unify->get_kind () != TyTy::TypeKind::CONST)
970 12 : return unify_error_type_node ();
971 :
972 1586 : auto capacity_type_unify = capacity_unify->as_const_type ();
973 1586 : if (capacity_type_unify->const_kind ()
974 : == TyTy::BaseConstType::ConstKind::Error)
975 0 : return unify_error_type_node ();
976 :
977 1586 : return new TyTy::ArrayType (
978 1586 : type.get_ref (), type.get_ty_ref (), type.get_ident ().locus,
979 1586 : TyTy::TyVar (capacity_type_unify->as_base_type ()->get_ref ()),
980 3172 : TyTy::TyVar (element_unify->get_ref ()));
981 : }
982 11103 : break;
983 :
984 11103 : case TyTy::PARAM:
985 11103 : case TyTy::POINTER:
986 11103 : case TyTy::STR:
987 11103 : case TyTy::ADT:
988 11103 : case TyTy::REF:
989 11103 : case TyTy::SLICE:
990 11103 : case TyTy::FNDEF:
991 11103 : case TyTy::FNPTR:
992 11103 : case TyTy::TUPLE:
993 11103 : case TyTy::BOOL:
994 11103 : case TyTy::CHAR:
995 11103 : case TyTy::INT:
996 11103 : case TyTy::UINT:
997 11103 : case TyTy::FLOAT:
998 11103 : case TyTy::USIZE:
999 11103 : case TyTy::ISIZE:
1000 11103 : case TyTy::NEVER:
1001 11103 : case TyTy::PLACEHOLDER:
1002 11103 : case TyTy::PROJECTION:
1003 11103 : case TyTy::DYNAMIC:
1004 11103 : case TyTy::CLOSURE:
1005 11103 : case TyTy::OPAQUE:
1006 11103 : case TyTy::CONST:
1007 11103 : case TyTy::ERROR:
1008 11103 : return unify_error_type_node ();
1009 : }
1010 0 : return unify_error_type_node ();
1011 : }
1012 :
1013 : TyTy::BaseType *
1014 4314 : UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
1015 : {
1016 4314 : switch (rtype->get_kind ())
1017 : {
1018 0 : case TyTy::INFER:
1019 0 : {
1020 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1021 0 : bool is_valid
1022 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1023 0 : if (is_valid)
1024 : return ltype;
1025 : }
1026 : break;
1027 :
1028 2769 : case TyTy::SLICE:
1029 2769 : {
1030 2769 : TyTy::SliceType &type = *static_cast<TyTy::SliceType *> (rtype);
1031 2769 : TyTy::BaseType *element_unify
1032 2769 : = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
1033 2769 : TyTy::TyWithLocation (type.get_element_type ()));
1034 :
1035 2769 : if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
1036 : return ltype;
1037 : }
1038 : break;
1039 :
1040 1545 : case TyTy::PARAM:
1041 1545 : case TyTy::POINTER:
1042 1545 : case TyTy::STR:
1043 1545 : case TyTy::ADT:
1044 1545 : case TyTy::REF:
1045 1545 : case TyTy::ARRAY:
1046 1545 : case TyTy::FNDEF:
1047 1545 : case TyTy::FNPTR:
1048 1545 : case TyTy::TUPLE:
1049 1545 : case TyTy::BOOL:
1050 1545 : case TyTy::CHAR:
1051 1545 : case TyTy::INT:
1052 1545 : case TyTy::UINT:
1053 1545 : case TyTy::FLOAT:
1054 1545 : case TyTy::USIZE:
1055 1545 : case TyTy::ISIZE:
1056 1545 : case TyTy::NEVER:
1057 1545 : case TyTy::PLACEHOLDER:
1058 1545 : case TyTy::PROJECTION:
1059 1545 : case TyTy::DYNAMIC:
1060 1545 : case TyTy::CLOSURE:
1061 1545 : case TyTy::OPAQUE:
1062 1545 : case TyTy::CONST:
1063 1545 : case TyTy::ERROR:
1064 1545 : return unify_error_type_node ();
1065 : }
1066 0 : return unify_error_type_node ();
1067 : }
1068 :
1069 : TyTy::BaseType *
1070 4331 : UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
1071 : {
1072 4331 : switch (rtype->get_kind ())
1073 : {
1074 0 : case TyTy::INFER:
1075 0 : {
1076 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1077 0 : bool is_valid
1078 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1079 0 : if (is_valid)
1080 : return ltype;
1081 : }
1082 : break;
1083 :
1084 4331 : case TyTy::FNDEF:
1085 4331 : {
1086 4331 : TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
1087 4331 : if (ltype->num_params () != type.num_params ())
1088 : {
1089 0 : return unify_error_type_node ();
1090 : }
1091 :
1092 10831 : for (size_t i = 0; i < ltype->num_params (); i++)
1093 : {
1094 6505 : auto a = ltype->param_at (i).get_type ();
1095 6505 : auto b = type.param_at (i).get_type ();
1096 :
1097 6505 : auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
1098 6505 : TyTy::TyWithLocation (b));
1099 6505 : if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
1100 : {
1101 5 : return unify_error_type_node ();
1102 : }
1103 : }
1104 :
1105 4326 : auto unified_return
1106 4326 : = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
1107 4326 : TyTy::TyWithLocation (type.get_return_type ()));
1108 4326 : if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
1109 : {
1110 1 : return unify_error_type_node ();
1111 : }
1112 :
1113 : // ABI match? see
1114 : // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/extern.20blocks/near/346416045
1115 4325 : if (ltype->get_abi () != type.get_abi ())
1116 : {
1117 0 : if (emit_error)
1118 : {
1119 0 : emit_abi_mismatch (*ltype, type);
1120 : }
1121 0 : return unify_error_type_node ();
1122 : }
1123 :
1124 : // DEF Id match? see https://github.com/Rust-GCC/gccrs/issues/2053
1125 :
1126 : return ltype;
1127 : }
1128 0 : break;
1129 :
1130 0 : case TyTy::TUPLE:
1131 0 : case TyTy::BOOL:
1132 0 : case TyTy::CHAR:
1133 0 : case TyTy::INT:
1134 0 : case TyTy::FLOAT:
1135 0 : case TyTy::ISIZE:
1136 0 : case TyTy::ADT:
1137 0 : case TyTy::STR:
1138 0 : case TyTy::REF:
1139 0 : case TyTy::POINTER:
1140 0 : case TyTy::PARAM:
1141 0 : case TyTy::ARRAY:
1142 0 : case TyTy::SLICE:
1143 0 : case TyTy::FNPTR:
1144 0 : case TyTy::UINT:
1145 0 : case TyTy::USIZE:
1146 0 : case TyTy::NEVER:
1147 0 : case TyTy::PLACEHOLDER:
1148 0 : case TyTy::PROJECTION:
1149 0 : case TyTy::DYNAMIC:
1150 0 : case TyTy::CLOSURE:
1151 0 : case TyTy::OPAQUE:
1152 0 : case TyTy::CONST:
1153 0 : case TyTy::ERROR:
1154 0 : return unify_error_type_node ();
1155 : }
1156 0 : return unify_error_type_node ();
1157 : }
1158 :
1159 : TyTy::BaseType *
1160 336 : UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
1161 : {
1162 336 : switch (rtype->get_kind ())
1163 : {
1164 0 : case TyTy::INFER:
1165 0 : {
1166 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1167 0 : bool is_valid
1168 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1169 0 : if (is_valid)
1170 : return ltype;
1171 : }
1172 : break;
1173 :
1174 206 : case TyTy::FNPTR:
1175 206 : {
1176 206 : TyTy::FnPtr &type = *static_cast<TyTy::FnPtr *> (rtype);
1177 206 : if (ltype->num_params () != type.num_params ())
1178 : {
1179 0 : return unify_error_type_node ();
1180 : }
1181 :
1182 248 : for (size_t i = 0; i < ltype->num_params (); i++)
1183 : {
1184 42 : auto a = ltype->get_param_type_at (i);
1185 42 : auto b = type.get_param_type_at (i);
1186 :
1187 42 : auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
1188 42 : TyTy::TyWithLocation (b));
1189 42 : if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
1190 : {
1191 0 : return unify_error_type_node ();
1192 : }
1193 : }
1194 :
1195 206 : auto unified_return
1196 206 : = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
1197 206 : TyTy::TyWithLocation (type.get_return_type ()));
1198 206 : if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
1199 : {
1200 0 : return unify_error_type_node ();
1201 : }
1202 :
1203 206 : if (ltype->get_abi () != type.get_abi ())
1204 : {
1205 58 : return unify_error_type_node ();
1206 : }
1207 :
1208 148 : if (ltype->get_unsafety () != type.get_unsafety ())
1209 : {
1210 29 : return unify_error_type_node ();
1211 : }
1212 :
1213 : return ltype;
1214 : }
1215 36 : break;
1216 :
1217 36 : case TyTy::FNDEF:
1218 36 : {
1219 36 : TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
1220 36 : auto this_ret_type = ltype->get_return_type ();
1221 36 : auto other_ret_type = type.get_return_type ();
1222 :
1223 36 : auto unified_result
1224 36 : = resolve_subtype (TyTy::TyWithLocation (this_ret_type),
1225 36 : TyTy::TyWithLocation (other_ret_type));
1226 36 : if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
1227 : {
1228 0 : return unify_error_type_node ();
1229 : }
1230 :
1231 36 : if (ltype->num_params () != type.num_params ())
1232 : {
1233 0 : return unify_error_type_node ();
1234 : }
1235 :
1236 78 : for (size_t i = 0; i < ltype->num_params (); i++)
1237 : {
1238 42 : auto this_param = ltype->get_param_type_at (i);
1239 42 : auto other_param = type.param_at (i).get_type ();
1240 :
1241 42 : auto unified_param
1242 42 : = resolve_subtype (TyTy::TyWithLocation (this_param),
1243 42 : TyTy::TyWithLocation (other_param));
1244 42 : if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
1245 : {
1246 0 : return unify_error_type_node ();
1247 : }
1248 : }
1249 :
1250 : // FIXME
1251 : //
1252 : // there is a bug in:
1253 : // testsuite/rust/compile/try-catch-unwind-{new,old}.rs I think the test
1254 : //
1255 : // case is wrong because it should be taking an FnOnce which probably
1256 : // didnt exist at the time in gccrs
1257 : //
1258 : // if (ltype->get_abi () != type.get_abi ())
1259 : // {
1260 : // return unify_error_type_node ();
1261 : // }
1262 :
1263 : // FIXME fntype needs to track unsafe or not
1264 : // if (ltype->get_unsafety () != type.get_unsafety ())
1265 : // {
1266 : // return unify_error_type_node ();
1267 : // }
1268 :
1269 : return ltype;
1270 : }
1271 0 : break;
1272 :
1273 0 : case TyTy::CLOSURE:
1274 0 : {
1275 0 : TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
1276 0 : auto this_ret_type = ltype->get_return_type ();
1277 0 : auto other_ret_type = type.get_return_type ();
1278 :
1279 0 : auto unified_result
1280 0 : = resolve_subtype (TyTy::TyWithLocation (this_ret_type),
1281 0 : TyTy::TyWithLocation (other_ret_type));
1282 0 : if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
1283 : {
1284 0 : return unify_error_type_node ();
1285 : }
1286 :
1287 0 : if (ltype->num_params () != type.get_num_params ())
1288 : {
1289 0 : return unify_error_type_node ();
1290 : }
1291 :
1292 0 : for (size_t i = 0; i < ltype->num_params (); i++)
1293 : {
1294 0 : auto this_param = ltype->get_param_type_at (i);
1295 0 : auto other_param = type.get_param_type_at (i);
1296 :
1297 0 : auto unified_param
1298 0 : = resolve_subtype (TyTy::TyWithLocation (this_param),
1299 0 : TyTy::TyWithLocation (other_param));
1300 0 : if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
1301 : {
1302 0 : return unify_error_type_node ();
1303 : }
1304 : }
1305 :
1306 : return ltype;
1307 : }
1308 94 : break;
1309 :
1310 94 : case TyTy::TUPLE:
1311 94 : case TyTy::BOOL:
1312 94 : case TyTy::CHAR:
1313 94 : case TyTy::INT:
1314 94 : case TyTy::FLOAT:
1315 94 : case TyTy::ISIZE:
1316 94 : case TyTy::ADT:
1317 94 : case TyTy::STR:
1318 94 : case TyTy::REF:
1319 94 : case TyTy::POINTER:
1320 94 : case TyTy::PARAM:
1321 94 : case TyTy::ARRAY:
1322 94 : case TyTy::SLICE:
1323 94 : case TyTy::UINT:
1324 94 : case TyTy::USIZE:
1325 94 : case TyTy::NEVER:
1326 94 : case TyTy::PLACEHOLDER:
1327 94 : case TyTy::PROJECTION:
1328 94 : case TyTy::DYNAMIC:
1329 94 : case TyTy::OPAQUE:
1330 94 : case TyTy::CONST:
1331 94 : case TyTy::ERROR:
1332 94 : return unify_error_type_node ();
1333 : }
1334 0 : return unify_error_type_node ();
1335 : }
1336 :
1337 : TyTy::BaseType *
1338 12072 : UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
1339 : {
1340 12072 : switch (rtype->get_kind ())
1341 : {
1342 59 : case TyTy::INFER:
1343 59 : {
1344 59 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1345 59 : bool is_valid
1346 59 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1347 59 : if (is_valid)
1348 : return ltype;
1349 : }
1350 : break;
1351 :
1352 11723 : case TyTy::TUPLE:
1353 11723 : {
1354 11723 : TyTy::TupleType &type = *static_cast<TyTy::TupleType *> (rtype);
1355 11723 : if (ltype->num_fields () != type.num_fields ())
1356 : {
1357 2 : return unify_error_type_node ();
1358 : }
1359 :
1360 11721 : std::vector<TyTy::TyVar> fields;
1361 13573 : for (size_t i = 0; i < ltype->num_fields (); i++)
1362 : {
1363 1858 : TyTy::BaseType *bo = ltype->get_field (i);
1364 1858 : TyTy::BaseType *fo = type.get_field (i);
1365 :
1366 1858 : TyTy::BaseType *unified_ty
1367 1858 : = resolve_subtype (TyTy::TyWithLocation (bo),
1368 1858 : TyTy::TyWithLocation (fo));
1369 1858 : if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
1370 6 : return unify_error_type_node ();
1371 :
1372 1852 : fields.emplace_back (unified_ty->get_ref ());
1373 : }
1374 :
1375 : return ltype;
1376 11721 : }
1377 290 : break;
1378 :
1379 290 : case TyTy::BOOL:
1380 290 : case TyTy::CHAR:
1381 290 : case TyTy::INT:
1382 290 : case TyTy::FLOAT:
1383 290 : case TyTy::ISIZE:
1384 290 : case TyTy::ADT:
1385 290 : case TyTy::STR:
1386 290 : case TyTy::REF:
1387 290 : case TyTy::POINTER:
1388 290 : case TyTy::PARAM:
1389 290 : case TyTy::ARRAY:
1390 290 : case TyTy::SLICE:
1391 290 : case TyTy::FNDEF:
1392 290 : case TyTy::FNPTR:
1393 290 : case TyTy::UINT:
1394 290 : case TyTy::USIZE:
1395 290 : case TyTy::NEVER:
1396 290 : case TyTy::PLACEHOLDER:
1397 290 : case TyTy::PROJECTION:
1398 290 : case TyTy::DYNAMIC:
1399 290 : case TyTy::CLOSURE:
1400 290 : case TyTy::OPAQUE:
1401 290 : case TyTy::CONST:
1402 290 : case TyTy::ERROR:
1403 290 : return unify_error_type_node ();
1404 : }
1405 6 : return unify_error_type_node ();
1406 : }
1407 :
1408 : TyTy::BaseType *
1409 19958 : UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
1410 : {
1411 19958 : switch (rtype->get_kind ())
1412 : {
1413 391 : case TyTy::INFER:
1414 391 : {
1415 391 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1416 391 : bool is_valid
1417 391 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1418 391 : if (is_valid)
1419 : {
1420 361 : if (commit_flag)
1421 0 : r->apply_primitive_type_hint (*ltype);
1422 361 : return ltype;
1423 : }
1424 : }
1425 : break;
1426 :
1427 : case TyTy::BOOL:
1428 : return rtype;
1429 :
1430 8850 : case TyTy::CHAR:
1431 8850 : case TyTy::INT:
1432 8850 : case TyTy::FLOAT:
1433 8850 : case TyTy::ISIZE:
1434 8850 : case TyTy::ADT:
1435 8850 : case TyTy::STR:
1436 8850 : case TyTy::REF:
1437 8850 : case TyTy::POINTER:
1438 8850 : case TyTy::PARAM:
1439 8850 : case TyTy::ARRAY:
1440 8850 : case TyTy::SLICE:
1441 8850 : case TyTy::FNDEF:
1442 8850 : case TyTy::FNPTR:
1443 8850 : case TyTy::TUPLE:
1444 8850 : case TyTy::UINT:
1445 8850 : case TyTy::USIZE:
1446 8850 : case TyTy::NEVER:
1447 8850 : case TyTy::PLACEHOLDER:
1448 8850 : case TyTy::PROJECTION:
1449 8850 : case TyTy::DYNAMIC:
1450 8850 : case TyTy::CLOSURE:
1451 8850 : case TyTy::OPAQUE:
1452 8850 : case TyTy::CONST:
1453 8850 : case TyTy::ERROR:
1454 8850 : return unify_error_type_node ();
1455 : }
1456 30 : return unify_error_type_node ();
1457 : }
1458 :
1459 : TyTy::BaseType *
1460 9791 : UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
1461 : {
1462 9791 : switch (rtype->get_kind ())
1463 : {
1464 316 : case TyTy::INFER:
1465 316 : {
1466 316 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1467 316 : bool is_valid
1468 316 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1469 316 : if (is_valid)
1470 : {
1471 312 : if (commit_flag)
1472 0 : r->apply_primitive_type_hint (*ltype);
1473 312 : return ltype;
1474 : }
1475 : }
1476 : break;
1477 :
1478 : case TyTy::CHAR:
1479 : return rtype;
1480 :
1481 8020 : case TyTy::INT:
1482 8020 : case TyTy::FLOAT:
1483 8020 : case TyTy::ISIZE:
1484 8020 : case TyTy::ADT:
1485 8020 : case TyTy::STR:
1486 8020 : case TyTy::REF:
1487 8020 : case TyTy::POINTER:
1488 8020 : case TyTy::PARAM:
1489 8020 : case TyTy::ARRAY:
1490 8020 : case TyTy::SLICE:
1491 8020 : case TyTy::FNDEF:
1492 8020 : case TyTy::FNPTR:
1493 8020 : case TyTy::TUPLE:
1494 8020 : case TyTy::BOOL:
1495 8020 : case TyTy::UINT:
1496 8020 : case TyTy::USIZE:
1497 8020 : case TyTy::NEVER:
1498 8020 : case TyTy::PLACEHOLDER:
1499 8020 : case TyTy::PROJECTION:
1500 8020 : case TyTy::DYNAMIC:
1501 8020 : case TyTy::CLOSURE:
1502 8020 : case TyTy::OPAQUE:
1503 8020 : case TyTy::CONST:
1504 8020 : case TyTy::ERROR:
1505 8020 : return unify_error_type_node ();
1506 : }
1507 4 : return unify_error_type_node ();
1508 : }
1509 :
1510 : TyTy::BaseType *
1511 305498 : UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
1512 : {
1513 305498 : switch (rtype->get_kind ())
1514 : {
1515 9766 : case TyTy::INFER:
1516 9766 : {
1517 9766 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1518 9766 : bool is_valid
1519 9766 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1520 9766 : || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
1521 9762 : if (is_valid)
1522 : {
1523 9762 : if (commit_flag)
1524 1369 : r->apply_primitive_type_hint (*ltype);
1525 9762 : return ltype;
1526 : }
1527 : }
1528 : break;
1529 :
1530 131633 : case TyTy::INT:
1531 131633 : {
1532 131633 : TyTy::IntType &type = *static_cast<TyTy::IntType *> (rtype);
1533 131633 : bool is_valid = ltype->get_int_kind () == type.get_int_kind ();
1534 131633 : if (is_valid)
1535 : return ltype;
1536 : }
1537 : break;
1538 :
1539 164099 : case TyTy::FLOAT:
1540 164099 : case TyTy::ISIZE:
1541 164099 : case TyTy::ADT:
1542 164099 : case TyTy::STR:
1543 164099 : case TyTy::REF:
1544 164099 : case TyTy::POINTER:
1545 164099 : case TyTy::PARAM:
1546 164099 : case TyTy::ARRAY:
1547 164099 : case TyTy::SLICE:
1548 164099 : case TyTy::FNDEF:
1549 164099 : case TyTy::FNPTR:
1550 164099 : case TyTy::TUPLE:
1551 164099 : case TyTy::BOOL:
1552 164099 : case TyTy::CHAR:
1553 164099 : case TyTy::UINT:
1554 164099 : case TyTy::USIZE:
1555 164099 : case TyTy::NEVER:
1556 164099 : case TyTy::PLACEHOLDER:
1557 164099 : case TyTy::PROJECTION:
1558 164099 : case TyTy::DYNAMIC:
1559 164099 : case TyTy::CLOSURE:
1560 164099 : case TyTy::OPAQUE:
1561 164099 : case TyTy::CONST:
1562 164099 : case TyTy::ERROR:
1563 164099 : return unify_error_type_node ();
1564 : }
1565 13262 : return unify_error_type_node ();
1566 : }
1567 :
1568 : TyTy::BaseType *
1569 885026 : UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
1570 : {
1571 885026 : switch (rtype->get_kind ())
1572 : {
1573 45895 : case TyTy::INFER:
1574 45895 : {
1575 45895 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1576 45895 : bool is_valid
1577 45895 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1578 45895 : || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
1579 45895 : if (is_valid)
1580 : {
1581 45895 : if (commit_flag)
1582 325 : r->apply_primitive_type_hint (*ltype);
1583 45895 : return ltype;
1584 : }
1585 : }
1586 : break;
1587 :
1588 320712 : case TyTy::UINT:
1589 320712 : {
1590 320712 : TyTy::UintType &type = *static_cast<TyTy::UintType *> (rtype);
1591 320712 : bool is_valid = ltype->get_uint_kind () == type.get_uint_kind ();
1592 320712 : if (is_valid)
1593 : return ltype;
1594 : }
1595 : break;
1596 :
1597 518419 : case TyTy::FLOAT:
1598 518419 : case TyTy::ISIZE:
1599 518419 : case TyTy::ADT:
1600 518419 : case TyTy::STR:
1601 518419 : case TyTy::REF:
1602 518419 : case TyTy::POINTER:
1603 518419 : case TyTy::PARAM:
1604 518419 : case TyTy::ARRAY:
1605 518419 : case TyTy::SLICE:
1606 518419 : case TyTy::FNDEF:
1607 518419 : case TyTy::FNPTR:
1608 518419 : case TyTy::TUPLE:
1609 518419 : case TyTy::BOOL:
1610 518419 : case TyTy::CHAR:
1611 518419 : case TyTy::INT:
1612 518419 : case TyTy::USIZE:
1613 518419 : case TyTy::NEVER:
1614 518419 : case TyTy::PLACEHOLDER:
1615 518419 : case TyTy::PROJECTION:
1616 518419 : case TyTy::DYNAMIC:
1617 518419 : case TyTy::CLOSURE:
1618 518419 : case TyTy::OPAQUE:
1619 518419 : case TyTy::CONST:
1620 518419 : case TyTy::ERROR:
1621 518419 : return unify_error_type_node ();
1622 : }
1623 213919 : return unify_error_type_node ();
1624 : }
1625 :
1626 : TyTy::BaseType *
1627 65144 : UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
1628 : {
1629 65144 : switch (rtype->get_kind ())
1630 : {
1631 1286 : case TyTy::INFER:
1632 1286 : {
1633 1286 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1634 1286 : bool is_valid
1635 1286 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
1636 1286 : || r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT;
1637 1254 : if (is_valid)
1638 : {
1639 1254 : if (commit_flag)
1640 40 : r->apply_primitive_type_hint (*ltype);
1641 1254 : return ltype;
1642 : }
1643 : }
1644 : break;
1645 :
1646 13982 : case TyTy::FLOAT:
1647 13982 : {
1648 13982 : TyTy::FloatType &type = *static_cast<TyTy::FloatType *> (rtype);
1649 13982 : bool is_valid = ltype->get_float_kind () == type.get_float_kind ();
1650 13982 : if (is_valid)
1651 : return ltype;
1652 : }
1653 : break;
1654 :
1655 49876 : case TyTy::ISIZE:
1656 49876 : case TyTy::ADT:
1657 49876 : case TyTy::STR:
1658 49876 : case TyTy::REF:
1659 49876 : case TyTy::POINTER:
1660 49876 : case TyTy::PARAM:
1661 49876 : case TyTy::ARRAY:
1662 49876 : case TyTy::SLICE:
1663 49876 : case TyTy::FNDEF:
1664 49876 : case TyTy::FNPTR:
1665 49876 : case TyTy::TUPLE:
1666 49876 : case TyTy::BOOL:
1667 49876 : case TyTy::CHAR:
1668 49876 : case TyTy::INT:
1669 49876 : case TyTy::UINT:
1670 49876 : case TyTy::USIZE:
1671 49876 : case TyTy::NEVER:
1672 49876 : case TyTy::PLACEHOLDER:
1673 49876 : case TyTy::PROJECTION:
1674 49876 : case TyTy::DYNAMIC:
1675 49876 : case TyTy::CLOSURE:
1676 49876 : case TyTy::OPAQUE:
1677 49876 : case TyTy::CONST:
1678 49876 : case TyTy::ERROR:
1679 49876 : return unify_error_type_node ();
1680 : }
1681 3558 : return unify_error_type_node ();
1682 : }
1683 :
1684 : TyTy::BaseType *
1685 69048 : UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
1686 : {
1687 69048 : switch (rtype->get_kind ())
1688 : {
1689 817 : case TyTy::INFER:
1690 817 : {
1691 817 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1692 817 : bool is_valid
1693 817 : = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
1694 817 : if (is_valid)
1695 : {
1696 817 : if (commit_flag)
1697 332 : r->apply_primitive_type_hint (*ltype);
1698 817 : return ltype;
1699 : }
1700 : }
1701 : break;
1702 :
1703 : case TyTy::ISIZE:
1704 : return rtype;
1705 :
1706 57114 : case TyTy::ADT:
1707 57114 : case TyTy::STR:
1708 57114 : case TyTy::REF:
1709 57114 : case TyTy::POINTER:
1710 57114 : case TyTy::PARAM:
1711 57114 : case TyTy::ARRAY:
1712 57114 : case TyTy::SLICE:
1713 57114 : case TyTy::FNDEF:
1714 57114 : case TyTy::FNPTR:
1715 57114 : case TyTy::TUPLE:
1716 57114 : case TyTy::BOOL:
1717 57114 : case TyTy::CHAR:
1718 57114 : case TyTy::INT:
1719 57114 : case TyTy::UINT:
1720 57114 : case TyTy::FLOAT:
1721 57114 : case TyTy::USIZE:
1722 57114 : case TyTy::NEVER:
1723 57114 : case TyTy::PLACEHOLDER:
1724 57114 : case TyTy::PROJECTION:
1725 57114 : case TyTy::DYNAMIC:
1726 57114 : case TyTy::CLOSURE:
1727 57114 : case TyTy::OPAQUE:
1728 57114 : case TyTy::CONST:
1729 57114 : case TyTy::ERROR:
1730 57114 : return unify_error_type_node ();
1731 : }
1732 0 : return unify_error_type_node ();
1733 : }
1734 :
1735 : TyTy::BaseType *
1736 391491 : UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
1737 : {
1738 391491 : switch (rtype->get_kind ())
1739 : {
1740 20921 : case TyTy::INFER:
1741 20921 : {
1742 20921 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1743 20921 : bool is_valid
1744 20921 : = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
1745 20921 : if (is_valid)
1746 : {
1747 20921 : if (commit_flag)
1748 837 : r->apply_primitive_type_hint (*ltype);
1749 20921 : return ltype;
1750 : }
1751 : }
1752 : break;
1753 :
1754 : case TyTy::USIZE:
1755 : return rtype;
1756 :
1757 311449 : case TyTy::ADT:
1758 311449 : case TyTy::STR:
1759 311449 : case TyTy::REF:
1760 311449 : case TyTy::POINTER:
1761 311449 : case TyTy::PARAM:
1762 311449 : case TyTy::ARRAY:
1763 311449 : case TyTy::SLICE:
1764 311449 : case TyTy::FNDEF:
1765 311449 : case TyTy::FNPTR:
1766 311449 : case TyTy::TUPLE:
1767 311449 : case TyTy::BOOL:
1768 311449 : case TyTy::CHAR:
1769 311449 : case TyTy::INT:
1770 311449 : case TyTy::UINT:
1771 311449 : case TyTy::FLOAT:
1772 311449 : case TyTy::ISIZE:
1773 311449 : case TyTy::NEVER:
1774 311449 : case TyTy::PLACEHOLDER:
1775 311449 : case TyTy::PROJECTION:
1776 311449 : case TyTy::DYNAMIC:
1777 311449 : case TyTy::CLOSURE:
1778 311449 : case TyTy::OPAQUE:
1779 311449 : case TyTy::CONST:
1780 311449 : case TyTy::ERROR:
1781 311449 : return unify_error_type_node ();
1782 : }
1783 0 : return unify_error_type_node ();
1784 : }
1785 :
1786 : TyTy::BaseType *
1787 4844 : UnifyRules::expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype)
1788 : {
1789 4844 : switch (rtype->get_kind ())
1790 : {
1791 342 : case TyTy::INFER:
1792 342 : {
1793 342 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1794 342 : bool is_valid
1795 342 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1796 342 : if (is_valid)
1797 : return ltype;
1798 : }
1799 0 : break;
1800 :
1801 : default:
1802 : return rtype;
1803 : }
1804 0 : return unify_error_type_node ();
1805 : }
1806 :
1807 : TyTy::BaseType *
1808 14788 : UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
1809 : TyTy::BaseType *rtype)
1810 : {
1811 14788 : switch (rtype->get_kind ())
1812 : {
1813 1123 : case TyTy::INFER:
1814 1123 : {
1815 1123 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1816 1123 : bool is_valid
1817 1123 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1818 1123 : if (is_valid)
1819 : return ltype;
1820 : }
1821 : break;
1822 :
1823 : case TyTy::PLACEHOLDER:
1824 : return ltype;
1825 :
1826 13212 : case TyTy::PROJECTION:
1827 13212 : case TyTy::DYNAMIC:
1828 13212 : case TyTy::CLOSURE:
1829 13212 : case TyTy::SLICE:
1830 13212 : case TyTy::PARAM:
1831 13212 : case TyTy::POINTER:
1832 13212 : case TyTy::STR:
1833 13212 : case TyTy::ADT:
1834 13212 : case TyTy::REF:
1835 13212 : case TyTy::ARRAY:
1836 13212 : case TyTy::FNDEF:
1837 13212 : case TyTy::FNPTR:
1838 13212 : case TyTy::TUPLE:
1839 13212 : case TyTy::BOOL:
1840 13212 : case TyTy::CHAR:
1841 13212 : case TyTy::INT:
1842 13212 : case TyTy::UINT:
1843 13212 : case TyTy::FLOAT:
1844 13212 : case TyTy::USIZE:
1845 13212 : case TyTy::ISIZE:
1846 13212 : case TyTy::NEVER:
1847 13212 : case TyTy::OPAQUE:
1848 13212 : if (infer_flag)
1849 : return rtype;
1850 8 : gcc_fallthrough ();
1851 :
1852 8 : case TyTy::CONST:
1853 8 : case TyTy::ERROR:
1854 8 : return unify_error_type_node ();
1855 : }
1856 0 : return unify_error_type_node ();
1857 : }
1858 :
1859 : TyTy::BaseType *
1860 0 : UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
1861 : TyTy::BaseType *rtype)
1862 : {
1863 0 : switch (rtype->get_kind ())
1864 : {
1865 0 : case TyTy::INFER:
1866 0 : {
1867 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1868 0 : bool is_valid
1869 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1870 0 : if (is_valid)
1871 : return ltype;
1872 : }
1873 : break;
1874 :
1875 : // FIXME
1876 0 : case TyTy::PROJECTION:
1877 0 : rust_unreachable ();
1878 0 : break;
1879 :
1880 0 : case TyTy::DYNAMIC:
1881 0 : case TyTy::CLOSURE:
1882 0 : case TyTy::SLICE:
1883 0 : case TyTy::PARAM:
1884 0 : case TyTy::POINTER:
1885 0 : case TyTy::STR:
1886 0 : case TyTy::ADT:
1887 0 : case TyTy::REF:
1888 0 : case TyTy::ARRAY:
1889 0 : case TyTy::FNDEF:
1890 0 : case TyTy::FNPTR:
1891 0 : case TyTy::TUPLE:
1892 0 : case TyTy::BOOL:
1893 0 : case TyTy::CHAR:
1894 0 : case TyTy::INT:
1895 0 : case TyTy::UINT:
1896 0 : case TyTy::FLOAT:
1897 0 : case TyTy::USIZE:
1898 0 : case TyTy::ISIZE:
1899 0 : case TyTy::NEVER:
1900 0 : case TyTy::PLACEHOLDER:
1901 0 : case TyTy::OPAQUE:
1902 0 : case TyTy::CONST:
1903 0 : case TyTy::ERROR:
1904 0 : return unify_error_type_node ();
1905 : }
1906 0 : return unify_error_type_node ();
1907 : }
1908 :
1909 : TyTy::BaseType *
1910 12916 : UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
1911 : {
1912 12916 : switch (rtype->get_kind ())
1913 : {
1914 201 : case TyTy::INFER:
1915 201 : {
1916 201 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1917 201 : bool is_valid
1918 201 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1919 201 : if (is_valid)
1920 : return ltype;
1921 : }
1922 : break;
1923 :
1924 545 : case TyTy::DYNAMIC:
1925 545 : {
1926 545 : TyTy::DynamicObjectType &type
1927 : = *static_cast<TyTy::DynamicObjectType *> (rtype);
1928 545 : if (ltype->num_specified_bounds () != type.num_specified_bounds ())
1929 : {
1930 0 : return unify_error_type_node ();
1931 : }
1932 :
1933 545 : if (!ltype->bounds_compatible (type, locus, true))
1934 : {
1935 0 : return unify_error_type_node ();
1936 : }
1937 :
1938 : return ltype;
1939 : }
1940 12170 : break;
1941 :
1942 12170 : case TyTy::CLOSURE:
1943 12170 : case TyTy::SLICE:
1944 12170 : case TyTy::PARAM:
1945 12170 : case TyTy::POINTER:
1946 12170 : case TyTy::STR:
1947 12170 : case TyTy::ADT:
1948 12170 : case TyTy::REF:
1949 12170 : case TyTy::ARRAY:
1950 12170 : case TyTy::FNDEF:
1951 12170 : case TyTy::FNPTR:
1952 12170 : case TyTy::TUPLE:
1953 12170 : case TyTy::BOOL:
1954 12170 : case TyTy::CHAR:
1955 12170 : case TyTy::INT:
1956 12170 : case TyTy::UINT:
1957 12170 : case TyTy::FLOAT:
1958 12170 : case TyTy::USIZE:
1959 12170 : case TyTy::ISIZE:
1960 12170 : case TyTy::NEVER:
1961 12170 : case TyTy::PLACEHOLDER:
1962 12170 : case TyTy::PROJECTION:
1963 12170 : case TyTy::OPAQUE:
1964 12170 : case TyTy::CONST:
1965 12170 : case TyTy::ERROR:
1966 12170 : return unify_error_type_node ();
1967 : }
1968 0 : return unify_error_type_node ();
1969 : }
1970 :
1971 : TyTy::BaseType *
1972 168 : UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
1973 : {
1974 168 : switch (rtype->get_kind ())
1975 : {
1976 0 : case TyTy::INFER:
1977 0 : {
1978 0 : TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
1979 0 : bool is_valid
1980 0 : = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
1981 0 : if (is_valid)
1982 : return ltype;
1983 : }
1984 : break;
1985 :
1986 168 : case TyTy::CLOSURE:
1987 168 : {
1988 168 : TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
1989 168 : if (ltype->get_def_id () != type.get_def_id ())
1990 : {
1991 7 : return unify_error_type_node ();
1992 : }
1993 :
1994 161 : TyTy::BaseType *args_res
1995 161 : = resolve_subtype (TyTy::TyWithLocation (<ype->get_parameters ()),
1996 161 : TyTy::TyWithLocation (&type.get_parameters ()));
1997 161 : if (args_res->get_kind () == TyTy::TypeKind::ERROR)
1998 : {
1999 0 : return unify_error_type_node ();
2000 : }
2001 :
2002 161 : TyTy::BaseType *res
2003 161 : = resolve_subtype (TyTy::TyWithLocation (<ype->get_result_type ()),
2004 161 : TyTy::TyWithLocation (&type.get_result_type ()));
2005 161 : if (res == nullptr || res->get_kind () == TyTy::TypeKind::ERROR)
2006 : {
2007 0 : return unify_error_type_node ();
2008 : }
2009 :
2010 : return ltype;
2011 : }
2012 0 : break;
2013 :
2014 0 : case TyTy::SLICE:
2015 0 : case TyTy::PARAM:
2016 0 : case TyTy::POINTER:
2017 0 : case TyTy::STR:
2018 0 : case TyTy::ADT:
2019 0 : case TyTy::REF:
2020 0 : case TyTy::ARRAY:
2021 0 : case TyTy::FNDEF:
2022 0 : case TyTy::FNPTR:
2023 0 : case TyTy::TUPLE:
2024 0 : case TyTy::BOOL:
2025 0 : case TyTy::CHAR:
2026 0 : case TyTy::INT:
2027 0 : case TyTy::UINT:
2028 0 : case TyTy::FLOAT:
2029 0 : case TyTy::USIZE:
2030 0 : case TyTy::ISIZE:
2031 0 : case TyTy::NEVER:
2032 0 : case TyTy::PLACEHOLDER:
2033 0 : case TyTy::PROJECTION:
2034 0 : case TyTy::DYNAMIC:
2035 0 : case TyTy::OPAQUE:
2036 0 : case TyTy::CONST:
2037 0 : case TyTy::ERROR:
2038 0 : return unify_error_type_node ();
2039 : }
2040 0 : return unify_error_type_node ();
2041 : }
2042 :
2043 : TyTy::BaseType *
2044 56 : UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
2045 : {
2046 56 : if (rtype->is<TyTy::OpaqueType> ())
2047 : {
2048 28 : TyTy::OpaqueType *ro = rtype->as<TyTy::OpaqueType> ();
2049 28 : if (!ltype->is_equal (*ro))
2050 0 : return unify_error_type_node ();
2051 :
2052 28 : if (ltype->can_resolve () && ro->can_resolve ())
2053 : {
2054 28 : auto lr = ltype->resolve ();
2055 28 : auto rr = ro->resolve ();
2056 :
2057 28 : auto res = resolve_subtype (TyTy::TyWithLocation (lr),
2058 28 : TyTy::TyWithLocation (rr));
2059 28 : if (res->get_kind () == TyTy::TypeKind::ERROR)
2060 0 : return unify_error_type_node ();
2061 : }
2062 0 : else if (ltype->can_resolve ())
2063 : {
2064 0 : auto lr = ltype->resolve ();
2065 0 : ro->set_ty_ref (lr->get_ref ());
2066 : }
2067 0 : else if (ro->can_resolve ())
2068 : {
2069 0 : auto rr = ro->resolve ();
2070 0 : ltype->set_ty_ref (rr->get_ref ());
2071 : }
2072 : }
2073 28 : else if (ltype->can_resolve ())
2074 : {
2075 0 : auto underly = ltype->resolve ();
2076 0 : auto res = resolve_subtype (TyTy::TyWithLocation (underly),
2077 0 : TyTy::TyWithLocation (rtype));
2078 0 : if (res->get_kind () == TyTy::TypeKind::ERROR)
2079 0 : return unify_error_type_node ();
2080 : }
2081 : else
2082 : {
2083 28 : ltype->set_ty_ref (rtype->get_ref ());
2084 : }
2085 :
2086 : return ltype;
2087 : }
2088 :
2089 : TyTy::BaseType *
2090 1786 : UnifyRules::expect_const (TyTy::BaseConstType *ltype, TyTy::BaseType *rtype)
2091 : {
2092 1786 : if (rtype->get_kind () != TyTy::TypeKind::CONST)
2093 0 : return unify_error_type_node ();
2094 :
2095 1786 : auto &lhs = *ltype;
2096 1786 : auto &rhs = *rtype->as_const_type ();
2097 :
2098 : // Handle error types early
2099 1786 : if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Error
2100 1786 : || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Error)
2101 : {
2102 0 : auto lhs_base = ltype->as_base_type ();
2103 0 : return new TyTy::ConstErrorType (lhs.get_specified_type (),
2104 : lhs_base->get_ref (),
2105 : lhs_base->get_ty_ref (),
2106 0 : lhs_base->get_combined_refs ());
2107 : }
2108 :
2109 : // Try to resolve Decl types (ConstParamType)
2110 1786 : TyTy::BaseConstType *resolved_lhs = &lhs;
2111 1786 : TyTy::BaseConstType *resolved_rhs = &rhs;
2112 :
2113 1786 : if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
2114 : {
2115 28 : auto *param = static_cast<TyTy::ConstParamType *> (&lhs);
2116 28 : if (param->can_resolve ())
2117 : {
2118 0 : auto *resolved = param->resolve ();
2119 0 : if (resolved->get_kind () == TyTy::TypeKind::CONST)
2120 0 : resolved_lhs = resolved->as_const_type ();
2121 : }
2122 : }
2123 :
2124 1786 : if (rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
2125 : {
2126 28 : auto *param = static_cast<TyTy::ConstParamType *> (&rhs);
2127 28 : if (param->can_resolve ())
2128 : {
2129 0 : auto *resolved = param->resolve ();
2130 0 : if (resolved->get_kind () == TyTy::TypeKind::CONST)
2131 0 : resolved_rhs = resolved->as_const_type ();
2132 : }
2133 : }
2134 :
2135 3572 : auto res = resolve_subtype (
2136 1786 : TyTy::TyWithLocation (resolved_lhs->get_specified_type ()),
2137 1786 : TyTy::TyWithLocation (resolved_rhs->get_specified_type ()));
2138 1786 : if (res->get_kind () == TyTy::TypeKind::ERROR)
2139 0 : return unify_error_type_node ();
2140 :
2141 1786 : if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Value
2142 1786 : && resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Value)
2143 : {
2144 1653 : auto vlhs = static_cast<TyTy::ConstValueType &> (*resolved_lhs);
2145 1653 : auto vrhs = static_cast<TyTy::ConstValueType &> (*resolved_rhs);
2146 1653 : tree lv = vlhs.get_value ();
2147 1653 : tree rv = vrhs.get_value ();
2148 :
2149 1653 : bool ok = operand_equal_p (lv, rv, 0);
2150 1653 : if (!ok)
2151 68 : return unify_error_type_node ();
2152 : else
2153 : {
2154 1585 : auto lhs_base = resolved_lhs->as_base_type ();
2155 1585 : return new TyTy::ConstValueType (lv, res, lhs_base->get_ref (),
2156 : lhs_base->get_ty_ref (),
2157 1585 : lhs_base->get_combined_refs ());
2158 : }
2159 1653 : }
2160 133 : else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
2161 133 : && resolved_rhs->const_kind ()
2162 : == TyTy::BaseConstType::ConstKind::Value)
2163 39 : return resolved_rhs->as_base_type ();
2164 94 : else if (resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
2165 94 : && resolved_lhs->const_kind ()
2166 : == TyTy::BaseConstType::ConstKind::Value)
2167 66 : return resolved_lhs->as_base_type ();
2168 28 : else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
2169 28 : && resolved_rhs->const_kind ()
2170 : == TyTy::BaseConstType::ConstKind::Infer)
2171 0 : return resolved_lhs->as_base_type ();
2172 28 : else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
2173 28 : || resolved_rhs->const_kind ()
2174 : == TyTy::BaseConstType::ConstKind::Decl)
2175 : {
2176 : // If we still have unresolved Decl after trying to resolve, unify with it
2177 : // This allows const inference to work
2178 28 : if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
2179 28 : && resolved_rhs->const_kind ()
2180 : != TyTy::BaseConstType::ConstKind::Decl)
2181 0 : return resolved_rhs->as_base_type ();
2182 28 : else if (resolved_rhs->const_kind ()
2183 : == TyTy::BaseConstType::ConstKind::Decl
2184 28 : && resolved_lhs->const_kind ()
2185 : != TyTy::BaseConstType::ConstKind::Decl)
2186 0 : return resolved_lhs->as_base_type ();
2187 : // Both are Decl - return lhs
2188 28 : return resolved_lhs->as_base_type ();
2189 : }
2190 :
2191 0 : return unify_error_type_node ();
2192 : }
2193 :
2194 : } // namespace Resolver
2195 : } // namespace Rust
|