Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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-hir-type-check-base.h"
20 : : #include "rust-compile-base.h"
21 : : #include "rust-hir-item.h"
22 : : #include "rust-hir-type-check-expr.h"
23 : : #include "rust-hir-type-check-type.h"
24 : : #include "rust-hir-trait-resolve.h"
25 : : #include "rust-type-util.h"
26 : : #include "rust-attribute-values.h"
27 : : #include "rust-tyty.h"
28 : : #include "tree.h"
29 : :
30 : : namespace Rust {
31 : : namespace Resolver {
32 : :
33 : 1364199 : TypeCheckBase::TypeCheckBase ()
34 : 1364199 : : mappings (Analysis::Mappings::get ()), context (TypeCheckContext::get ())
35 : 1364199 : {}
36 : :
37 : : void
38 : 43 : TypeCheckBase::ResolveGenericParams (
39 : : const HIR::Item::ItemKind item_kind, location_t item_locus,
40 : : const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
41 : : std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
42 : : ABI abi)
43 : : {
44 : 43 : TypeCheckBase ctx;
45 : 43 : ctx.resolve_generic_params (item_kind, item_locus, generic_params,
46 : : substitutions, is_foreign, abi);
47 : 43 : }
48 : :
49 : : static void
50 : 11408 : walk_types_to_constrain (std::set<HirId> &constrained_symbols,
51 : : const TyTy::SubstitutionArgumentMappings &constraints)
52 : : {
53 : 18184 : for (const auto &c : constraints.get_mappings ())
54 : : {
55 : 6776 : auto arg = c.get_tyty ();
56 : 6776 : if (arg != nullptr)
57 : : {
58 : 6776 : const auto p = arg->get_root ();
59 : 6776 : constrained_symbols.insert (p->get_ty_ref ());
60 : 6776 : if (p->has_substitutions_defined ())
61 : : {
62 : 246 : walk_types_to_constrain (constrained_symbols,
63 : : p->get_subst_argument_mappings ());
64 : : }
65 : : }
66 : : }
67 : 11408 : }
68 : :
69 : : bool
70 : 41822 : TypeCheckBase::check_for_unconstrained (
71 : : const std::vector<TyTy::SubstitutionParamMapping> ¶ms_to_constrain,
72 : : const TyTy::SubstitutionArgumentMappings &constraint_a,
73 : : const TyTy::SubstitutionArgumentMappings &constraint_b,
74 : : TyTy::BaseType *reference)
75 : : {
76 : 41822 : bool check_result = false;
77 : 41822 : bool check_completed
78 : 41822 : = context->have_checked_for_unconstrained (reference->get_ref (),
79 : : &check_result);
80 : 41822 : if (check_completed)
81 : 36241 : return check_result;
82 : :
83 : 5581 : std::set<HirId> symbols_to_constrain;
84 : 5581 : std::map<HirId, location_t> symbol_to_location;
85 : 6535 : for (const auto &p : params_to_constrain)
86 : : {
87 : 954 : HirId ref = p.get_param_ty ()->get_ref ();
88 : 954 : symbols_to_constrain.insert (ref);
89 : 954 : symbol_to_location.insert ({ref, p.get_param_locus ()});
90 : :
91 : 954 : rust_debug_loc (p.get_param_locus (), "XX constrain THIS");
92 : : }
93 : :
94 : : // set up the set of constrained symbols
95 : 5581 : std::set<HirId> constrained_symbols;
96 : 5581 : walk_types_to_constrain (constrained_symbols, constraint_a);
97 : 5581 : walk_types_to_constrain (constrained_symbols, constraint_b);
98 : :
99 : 5581 : const auto root = reference->get_root ();
100 : 5581 : if (root->get_kind () == TyTy::TypeKind::PARAM)
101 : : {
102 : 504 : const TyTy::ParamType *p = static_cast<const TyTy::ParamType *> (root);
103 : 504 : constrained_symbols.insert (p->get_ty_ref ());
104 : : }
105 : :
106 : : // check for unconstrained
107 : 5581 : bool unconstrained = false;
108 : 6535 : for (auto &sym : symbols_to_constrain)
109 : : {
110 : 954 : bool used = constrained_symbols.find (sym) != constrained_symbols.end ();
111 : 954 : if (!used)
112 : : {
113 : 3 : location_t locus = symbol_to_location.at (sym);
114 : 3 : rust_error_at (locus, "unconstrained type parameter");
115 : 3 : unconstrained = true;
116 : : }
117 : : }
118 : :
119 : 5581 : context->insert_unconstrained_check_marker (reference->get_ref (),
120 : : unconstrained);
121 : :
122 : 5581 : return unconstrained;
123 : 5581 : }
124 : :
125 : : TyTy::BaseType *
126 : 18018 : TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
127 : : HIR::Literal &literal, location_t locus)
128 : : {
129 : 18018 : TyTy::BaseType *infered = nullptr;
130 : 18018 : switch (literal.get_lit_type ())
131 : : {
132 : 13492 : case HIR::Literal::LitType::INT:
133 : 13492 : {
134 : 13492 : bool ok = false;
135 : :
136 : 13492 : switch (literal.get_type_hint ())
137 : : {
138 : 22 : case CORETYPE_I8:
139 : 22 : ok = context->lookup_builtin ("i8", &infered);
140 : 22 : break;
141 : 14 : case CORETYPE_I16:
142 : 14 : ok = context->lookup_builtin ("i16", &infered);
143 : 14 : break;
144 : 174 : case CORETYPE_I32:
145 : 174 : ok = context->lookup_builtin ("i32", &infered);
146 : 174 : break;
147 : 14 : case CORETYPE_I64:
148 : 14 : ok = context->lookup_builtin ("i64", &infered);
149 : 14 : break;
150 : 14 : case CORETYPE_I128:
151 : 14 : ok = context->lookup_builtin ("i128", &infered);
152 : 14 : break;
153 : :
154 : 29 : case CORETYPE_U8:
155 : 29 : ok = context->lookup_builtin ("u8", &infered);
156 : 29 : break;
157 : 24 : case CORETYPE_U16:
158 : 24 : ok = context->lookup_builtin ("u16", &infered);
159 : 24 : break;
160 : 101 : case CORETYPE_U32:
161 : 101 : ok = context->lookup_builtin ("u32", &infered);
162 : 101 : break;
163 : 15 : case CORETYPE_U64:
164 : 15 : ok = context->lookup_builtin ("u64", &infered);
165 : 15 : break;
166 : 14 : case CORETYPE_U128:
167 : 14 : ok = context->lookup_builtin ("u128", &infered);
168 : 14 : break;
169 : :
170 : 466 : case CORETYPE_F32:
171 : 466 : literal.set_lit_type (HIR::Literal::LitType::FLOAT);
172 : 466 : ok = context->lookup_builtin ("f32", &infered);
173 : 466 : break;
174 : 205 : case CORETYPE_F64:
175 : 205 : literal.set_lit_type (HIR::Literal::LitType::FLOAT);
176 : 205 : ok = context->lookup_builtin ("f64", &infered);
177 : 205 : break;
178 : :
179 : 2 : case CORETYPE_ISIZE:
180 : 2 : ok = context->lookup_builtin ("isize", &infered);
181 : 2 : break;
182 : :
183 : 34 : case CORETYPE_USIZE:
184 : 34 : ok = context->lookup_builtin ("usize", &infered);
185 : 34 : break;
186 : :
187 : 12364 : default:
188 : 12364 : ok = true;
189 : 12364 : infered
190 : 12364 : = new TyTy::InferType (expr_mappings.get_hirid (),
191 : : TyTy::InferType::InferTypeKind::INTEGRAL,
192 : : TyTy::InferType::TypeHint::Default (),
193 : 12364 : locus);
194 : 12364 : break;
195 : : }
196 : 13492 : rust_assert (ok);
197 : : }
198 : : break;
199 : :
200 : 323 : case HIR::Literal::LitType::FLOAT:
201 : 323 : {
202 : 323 : bool ok = false;
203 : :
204 : 323 : switch (literal.get_type_hint ())
205 : : {
206 : 27 : case CORETYPE_F32:
207 : 27 : ok = context->lookup_builtin ("f32", &infered);
208 : 27 : break;
209 : 16 : case CORETYPE_F64:
210 : 16 : ok = context->lookup_builtin ("f64", &infered);
211 : 16 : break;
212 : :
213 : 280 : default:
214 : 280 : ok = true;
215 : 280 : infered
216 : 280 : = new TyTy::InferType (expr_mappings.get_hirid (),
217 : : TyTy::InferType::InferTypeKind::FLOAT,
218 : : TyTy::InferType::TypeHint::Default (),
219 : 280 : locus);
220 : 280 : break;
221 : : }
222 : 323 : rust_assert (ok);
223 : : }
224 : : break;
225 : :
226 : 1290 : case HIR::Literal::LitType::BOOL:
227 : 1290 : {
228 : 1290 : auto ok = context->lookup_builtin ("bool", &infered);
229 : 1290 : rust_assert (ok);
230 : : }
231 : : break;
232 : :
233 : 186 : case HIR::Literal::LitType::CHAR:
234 : 186 : {
235 : 186 : auto ok = context->lookup_builtin ("char", &infered);
236 : 186 : rust_assert (ok);
237 : : }
238 : : break;
239 : :
240 : 408 : case HIR::Literal::LitType::BYTE:
241 : 408 : {
242 : 408 : auto ok = context->lookup_builtin ("u8", &infered);
243 : 408 : rust_assert (ok);
244 : : }
245 : : break;
246 : :
247 : 2284 : case HIR::Literal::LitType::STRING:
248 : 2284 : {
249 : 2284 : TyTy::BaseType *base = nullptr;
250 : 2284 : auto ok = context->lookup_builtin ("str", &base);
251 : 2284 : rust_assert (ok);
252 : :
253 : 4568 : infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
254 : 2284 : TyTy::TyVar (base->get_ref ()),
255 : : Mutability::Imm,
256 : 4568 : TyTy::Region::make_static ());
257 : : }
258 : 2284 : break;
259 : :
260 : 35 : case HIR::Literal::LitType::BYTE_STRING:
261 : 35 : {
262 : : /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
263 : : UTF-8, but really just a byte array. Code to construct the array
264 : : reference copied from ArrayElemsValues and ArrayType. */
265 : 35 : TyTy::BaseType *u8;
266 : 35 : auto ok = context->lookup_builtin ("u8", &u8);
267 : 35 : rust_assert (ok);
268 : :
269 : 35 : auto crate_num = mappings.get_current_crate ();
270 : 35 : Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
271 : 35 : mappings.get_next_hir_id (
272 : : crate_num),
273 : 35 : UNKNOWN_LOCAL_DEFID);
274 : :
275 : : /* Capacity is the size of the string (number of chars).
276 : : It is a constant, but for fold it to get a tree. */
277 : 35 : std::string capacity_str
278 : 35 : = std::to_string (literal.as_string ().size ());
279 : 35 : HIR::LiteralExpr *literal_capacity
280 : : = new HIR::LiteralExpr (capacity_mapping, capacity_str,
281 : : HIR::Literal::LitType::INT,
282 : 70 : PrimitiveCoreType::CORETYPE_USIZE, locus, {});
283 : :
284 : : // mark the type for this implicit node
285 : 35 : TyTy::BaseType *expected_ty = nullptr;
286 : 35 : ok = context->lookup_builtin ("usize", &expected_ty);
287 : 35 : rust_assert (ok);
288 : 35 : context->insert_type (capacity_mapping, expected_ty);
289 : :
290 : 35 : Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
291 : 35 : mappings.get_next_hir_id (
292 : : crate_num),
293 : 35 : UNKNOWN_LOCAL_DEFID);
294 : :
295 : 35 : auto ctx = Compile::Context::get ();
296 : 35 : tree capacity = Compile::HIRCompileBase::query_compile_const_expr (
297 : : ctx, expected_ty, *literal_capacity);
298 : :
299 : 35 : TyTy::ConstType *capacity_expr
300 : 35 : = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
301 : : expected_ty, capacity, {},
302 : : literal_capacity->get_locus (),
303 : 35 : literal_capacity->get_mappings ().get_hirid (),
304 : 35 : literal_capacity->get_mappings ().get_hirid (),
305 : 35 : {});
306 : :
307 : 35 : TyTy::ArrayType *array
308 : : = new TyTy::ArrayType (array_mapping.get_hirid (), locus,
309 : 35 : capacity_expr, TyTy::TyVar (u8->get_ref ()));
310 : 35 : context->insert_type (array_mapping, array);
311 : :
312 : 70 : infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
313 : 35 : TyTy::TyVar (array->get_ref ()),
314 : : Mutability::Imm,
315 : 70 : TyTy::Region::make_static ());
316 : 35 : }
317 : 35 : break;
318 : :
319 : 0 : default:
320 : 0 : rust_unreachable ();
321 : 18018 : break;
322 : : }
323 : :
324 : 18018 : return infered;
325 : : }
326 : :
327 : : TyTy::ADTType::ReprOptions
328 : 2877 : TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
329 : : {
330 : 2877 : TyTy::ADTType::ReprOptions repr;
331 : 2877 : repr.pack = 0;
332 : 2877 : repr.align = 0;
333 : :
334 : : // Default repr for enums is isize, but we now check for other repr in the
335 : : // attributes.
336 : 2877 : bool ok = context->lookup_builtin ("isize", &repr.repr);
337 : 2877 : rust_assert (ok);
338 : :
339 : 3292 : for (const auto &attr : attrs)
340 : : {
341 : 441 : bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
342 : 441 : if (is_repr && !attr.has_attr_input ())
343 : : {
344 : 1 : rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr");
345 : 1 : continue;
346 : : }
347 : :
348 : 440 : if (is_repr)
349 : : {
350 : 27 : const AST::AttrInput &input = attr.get_attr_input ();
351 : 27 : bool is_token_tree = input.get_attr_input_type ()
352 : 27 : == AST::AttrInput::AttrInputType::TOKEN_TREE;
353 : 27 : rust_assert (is_token_tree);
354 : 27 : const auto &option = static_cast<const AST::DelimTokenTree &> (input);
355 : 27 : AST::AttrInputMetaItemContainer *meta_items
356 : 27 : = option.parse_to_meta_item ();
357 : :
358 : 27 : if (meta_items == nullptr)
359 : : {
360 : 0 : rust_error_at (attr.get_locus (), "malformed %qs attribute",
361 : : "repr");
362 : 1 : continue;
363 : : }
364 : :
365 : 27 : auto &items = meta_items->get_items ();
366 : 27 : if (items.size () == 0)
367 : : {
368 : : // nothing to do with this its empty
369 : 1 : delete meta_items;
370 : 1 : continue;
371 : : }
372 : :
373 : 26 : const std::string inline_option = items.at (0)->as_string ();
374 : :
375 : : // TODO: it would probably be better to make the MetaItems more aware
376 : : // of constructs with nesting like #[repr(packed(2))] rather than
377 : : // manually parsing the string "packed(2)" here.
378 : :
379 : 26 : size_t oparen = inline_option.find ('(', 0);
380 : 26 : bool is_pack = false;
381 : 26 : bool is_align = false;
382 : 26 : bool is_c = false;
383 : 26 : bool is_integer = false;
384 : 26 : unsigned char value = 1;
385 : :
386 : 26 : if (oparen == std::string::npos)
387 : : {
388 : 20 : is_pack = inline_option.compare ("packed") == 0;
389 : 20 : is_align = inline_option.compare ("align") == 0;
390 : 20 : is_c = inline_option.compare ("C") == 0;
391 : 20 : is_integer = (inline_option.compare ("isize") == 0
392 : 20 : || inline_option.compare ("i8") == 0
393 : 20 : || inline_option.compare ("i16") == 0
394 : 20 : || inline_option.compare ("i32") == 0
395 : 19 : || inline_option.compare ("i64") == 0
396 : 19 : || inline_option.compare ("i128") == 0
397 : 19 : || inline_option.compare ("usize") == 0
398 : 19 : || inline_option.compare ("u8") == 0
399 : 19 : || inline_option.compare ("u16") == 0
400 : 19 : || inline_option.compare ("u32") == 0
401 : 19 : || inline_option.compare ("u64") == 0
402 : 39 : || inline_option.compare ("u128") == 0);
403 : : }
404 : :
405 : : else
406 : : {
407 : 6 : std::string rep = inline_option.substr (0, oparen);
408 : 6 : is_pack = rep.compare ("packed") == 0;
409 : 6 : is_align = rep.compare ("align") == 0;
410 : :
411 : 6 : size_t cparen = inline_option.find (')', oparen);
412 : 6 : if (cparen == std::string::npos)
413 : : {
414 : 0 : rust_error_at (locus, "malformed attribute");
415 : : }
416 : :
417 : 6 : std::string value_str = inline_option.substr (oparen, cparen);
418 : 6 : value = strtoul (value_str.c_str () + 1, NULL, 10);
419 : 6 : }
420 : :
421 : 26 : if (is_pack)
422 : : {
423 : 4 : repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
424 : 4 : repr.pack = value;
425 : : }
426 : 22 : else if (is_align)
427 : : {
428 : 4 : repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
429 : 4 : repr.align = value;
430 : : }
431 : 18 : else if (is_c)
432 : : {
433 : 15 : repr.repr_kind = TyTy::ADTType::ReprKind::C;
434 : : }
435 : 3 : else if (is_integer)
436 : : {
437 : 1 : repr.repr_kind = TyTy::ADTType::ReprKind::INT;
438 : 2 : bool ok = context->lookup_builtin (inline_option, &repr.repr);
439 : 1 : if (!ok)
440 : : {
441 : 0 : rust_error_at (attr.get_locus (), "Invalid repr type");
442 : : }
443 : : }
444 : :
445 : 26 : delete meta_items;
446 : :
447 : : // Multiple repr options must be specified with e.g. #[repr(C,
448 : : // packed(2))].
449 : 26 : break;
450 : 26 : }
451 : : }
452 : :
453 : 2877 : return repr;
454 : : }
455 : :
456 : : void
457 : 8470 : TypeCheckBase::resolve_generic_params (
458 : : const HIR::Item::ItemKind item_kind, location_t item_locus,
459 : : const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
460 : : std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
461 : : ABI abi)
462 : : {
463 : 17998 : for (auto &generic_param : generic_params)
464 : : {
465 : 9528 : switch (generic_param->get_kind ())
466 : : {
467 : 879 : case HIR::GenericParam::GenericKind::LIFETIME:
468 : 879 : {
469 : 879 : auto lifetime_param
470 : 879 : = static_cast<HIR::LifetimeParam &> (*generic_param);
471 : 879 : auto lifetime = lifetime_param.get_lifetime ();
472 : 879 : context->get_lifetime_resolver ().insert_mapping (
473 : : context->intern_lifetime (lifetime));
474 : 879 : }
475 : 879 : break;
476 : :
477 : 32 : case HIR::GenericParam::GenericKind::CONST:
478 : 32 : {
479 : 32 : if (is_foreign && abi != Rust::ABI::INTRINSIC)
480 : : {
481 : 0 : rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
482 : : "foreign items may not have const parameters");
483 : : }
484 : :
485 : 32 : auto ¶m
486 : 32 : = static_cast<HIR::ConstGenericParam &> (*generic_param);
487 : 32 : auto specified_type = TypeCheckType::Resolve (param.get_type ());
488 : :
489 : 32 : if (param.has_default_expression ())
490 : : {
491 : 13 : switch (item_kind)
492 : : {
493 : : case HIR::Item::ItemKind::Struct:
494 : : case HIR::Item::ItemKind::Enum:
495 : : case HIR::Item::ItemKind::TypeAlias:
496 : : case HIR::Item::ItemKind::Trait:
497 : : case HIR::Item::ItemKind::Union:
498 : : break;
499 : :
500 : 2 : default:
501 : 2 : {
502 : 2 : rich_location r (line_table, item_locus);
503 : 2 : r.add_fixit_remove (param.get_locus ());
504 : 2 : rust_error_at (
505 : : r,
506 : : "default values for const generic parameters are not "
507 : : "allowed here");
508 : 2 : }
509 : 2 : break;
510 : : }
511 : :
512 : 13 : auto expr_type
513 : 13 : = TypeCheckExpr::Resolve (param.get_default_expression ());
514 : :
515 : 26 : coercion_site (param.get_mappings ().get_hirid (),
516 : 13 : TyTy::TyWithLocation (specified_type),
517 : : TyTy::TyWithLocation (
518 : : expr_type,
519 : 13 : param.get_default_expression ().get_locus ()),
520 : : param.get_locus ());
521 : :
522 : : // fold the default value
523 : 13 : auto ctx = Compile::Context::get ();
524 : 13 : auto &expr = param.get_default_expression ();
525 : 13 : tree default_value
526 : 13 : = Compile::HIRCompileBase::query_compile_const_expr (
527 : : ctx, specified_type, expr);
528 : :
529 : 13 : TyTy::ConstType *default_const_decl
530 : : = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
531 : 26 : param.get_name (), specified_type,
532 : : default_value, {}, param.get_locus (),
533 : 13 : expr.get_mappings ().get_hirid (),
534 : 26 : expr.get_mappings ().get_hirid (), {});
535 : :
536 : 13 : context->insert_type (expr.get_mappings (), default_const_decl);
537 : : }
538 : :
539 : 32 : TyTy::ConstType *const_decl
540 : : = new TyTy::ConstType (TyTy::ConstType::ConstKind::Decl,
541 : 64 : param.get_name (), specified_type,
542 : : error_mark_node, {}, param.get_locus (),
543 : 32 : param.get_mappings ().get_hirid (),
544 : 64 : param.get_mappings ().get_hirid (), {});
545 : :
546 : 32 : context->insert_type (generic_param->get_mappings (), const_decl);
547 : 32 : TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
548 : 32 : substitutions.push_back (p);
549 : : }
550 : 32 : break;
551 : :
552 : 8617 : case HIR::GenericParam::GenericKind::TYPE:
553 : 8617 : {
554 : 8617 : if (is_foreign && abi != Rust::ABI::INTRINSIC)
555 : : {
556 : 1 : rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
557 : : "foreign items may not have type parameters");
558 : : }
559 : :
560 : 8617 : auto param_type = TypeResolveGenericParam::Resolve (
561 : 8617 : *generic_param, false /*resolve_trait_bounds*/);
562 : 8617 : context->insert_type (generic_param->get_mappings (), param_type);
563 : :
564 : 8617 : TyTy::SubstitutionParamMapping p (*generic_param, param_type);
565 : 8617 : substitutions.push_back (p);
566 : : }
567 : 8617 : break;
568 : : }
569 : : }
570 : :
571 : : // now walk them to setup any specified type param bounds
572 : 17205 : for (auto &subst : substitutions)
573 : : {
574 : 8736 : auto &generic = subst.get_generic_param ();
575 : 8736 : if (generic.get_kind () != HIR::GenericParam::GenericKind::TYPE)
576 : 32 : continue;
577 : :
578 : 8704 : auto &type_param = static_cast<HIR::TypeParam &> (generic);
579 : 8704 : auto bpty = subst.get_param_ty ();
580 : 8704 : rust_assert (bpty->get_kind () == TyTy::TypeKind::PARAM);
581 : 8704 : auto pty = static_cast<TyTy::ParamType *> (bpty);
582 : :
583 : 8704 : TypeResolveGenericParam::ApplyAnyTraitBounds (type_param, pty);
584 : : }
585 : 8469 : }
586 : :
587 : : TyTy::TypeBoundPredicate
588 : 9340 : TypeCheckBase::get_marker_predicate (LangItem::Kind item_type, location_t locus)
589 : : {
590 : 9340 : DefId item_id = mappings.get_lang_item (item_type, locus);
591 : 9339 : HIR::Item *item = mappings.lookup_defid (item_id).value ();
592 : 9339 : rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
593 : :
594 : 9339 : HIR::Trait &trait = *static_cast<HIR::Trait *> (item);
595 : 9339 : TraitReference *ref = TraitResolver::Resolve (trait);
596 : 9339 : rust_assert (ref != nullptr);
597 : :
598 : 9339 : return TyTy::TypeBoundPredicate (*ref, BoundPolarity::RegularBound, locus);
599 : : }
600 : :
601 : : } // namespace Resolver
602 : : } // namespace Rust
|