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