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