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