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