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 2773345 : TypeCheckBase::TypeCheckBase ()
34 2773345 : : mappings (Analysis::Mappings::get ()), context (TypeCheckContext::get ())
35 2773345 : {}
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 11531 : walk_types_to_constrain (std::set<HirId> &constrained_symbols,
51 : const TyTy::SubstitutionArgumentMappings &constraints)
52 : {
53 18380 : for (const auto &c : constraints.get_mappings ())
54 : {
55 6849 : auto arg = c.get_tyty ();
56 6849 : if (arg != nullptr)
57 : {
58 6849 : const auto p = arg->get_root ();
59 6849 : constrained_symbols.insert (p->get_ref ());
60 6849 : constrained_symbols.insert (p->get_ty_ref ());
61 :
62 6849 : if (p->has_substitutions_defined ())
63 : {
64 245 : walk_types_to_constrain (constrained_symbols,
65 : p->get_subst_argument_mappings ());
66 : }
67 : }
68 : }
69 11531 : }
70 :
71 : static void
72 5643 : walk_type_to_constrain (std::set<HirId> &constrained_symbols, TyTy::BaseType &r)
73 : {
74 6124 : 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 1 : case TyTy::TypeKind::ARRAY:
89 1 : {
90 1 : auto &arr = static_cast<TyTy::ArrayType &> (r);
91 1 : walk_type_to_constrain (constrained_symbols, *arr.get_element_type ());
92 : }
93 1 : 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 3 : case TyTy::TUPLE:
124 3 : {
125 3 : auto &tuple = static_cast<TyTy::TupleType &> (r);
126 3 : 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 5643 : }
147 :
148 : bool
149 41266 : 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 41266 : bool check_result = false;
156 41266 : bool check_completed
157 41266 : = context->have_checked_for_unconstrained (reference->get_ref (),
158 : &check_result);
159 41266 : if (check_completed)
160 35623 : return check_result;
161 :
162 5643 : std::set<HirId> symbols_to_constrain;
163 5643 : std::map<HirId, location_t> symbol_to_location;
164 6638 : for (const auto &p : params_to_constrain)
165 : {
166 995 : HirId ref = p.get_param_ty ()->get_ref ();
167 995 : symbols_to_constrain.insert (ref);
168 995 : symbol_to_location.insert ({ref, p.get_param_locus ()});
169 : }
170 :
171 : // set up the set of constrained symbols
172 11286 : std::set<HirId> constrained_symbols;
173 5643 : walk_types_to_constrain (constrained_symbols, constraint_a);
174 5643 : walk_types_to_constrain (constrained_symbols, constraint_b);
175 5643 : walk_type_to_constrain (constrained_symbols, *reference);
176 :
177 : // check for unconstrained
178 5643 : bool unconstrained = false;
179 6638 : for (auto &sym : symbols_to_constrain)
180 : {
181 995 : bool used = constrained_symbols.find (sym) != constrained_symbols.end ();
182 995 : if (!used)
183 : {
184 4 : location_t locus = symbol_to_location.at (sym);
185 4 : rust_error_at (locus, "unconstrained type parameter");
186 4 : unconstrained = true;
187 : }
188 : }
189 :
190 5643 : context->insert_unconstrained_check_marker (reference->get_ref (),
191 : unconstrained);
192 :
193 5643 : return unconstrained;
194 5643 : }
195 :
196 : TyTy::BaseType *
197 20725 : TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
198 : HIR::Literal &literal, location_t locus)
199 : {
200 20725 : TyTy::BaseType *infered = nullptr;
201 20725 : switch (literal.get_lit_type ())
202 : {
203 16083 : case HIR::Literal::LitType::INT:
204 16083 : {
205 16083 : bool ok = false;
206 :
207 16083 : switch (literal.get_type_hint ())
208 : {
209 92 : case CORETYPE_I8:
210 92 : ok = context->lookup_builtin ("i8", &infered);
211 92 : break;
212 86 : case CORETYPE_I16:
213 86 : ok = context->lookup_builtin ("i16", &infered);
214 86 : break;
215 247 : case CORETYPE_I32:
216 247 : ok = context->lookup_builtin ("i32", &infered);
217 247 : break;
218 84 : case CORETYPE_I64:
219 84 : ok = context->lookup_builtin ("i64", &infered);
220 84 : break;
221 14 : case CORETYPE_I128:
222 14 : ok = context->lookup_builtin ("i128", &infered);
223 14 : break;
224 :
225 134 : case CORETYPE_U8:
226 134 : ok = context->lookup_builtin ("u8", &infered);
227 134 : break;
228 131 : case CORETYPE_U16:
229 131 : ok = context->lookup_builtin ("u16", &infered);
230 131 : break;
231 216 : case CORETYPE_U32:
232 216 : ok = context->lookup_builtin ("u32", &infered);
233 216 : break;
234 120 : case CORETYPE_U64:
235 120 : ok = context->lookup_builtin ("u64", &infered);
236 120 : break;
237 17 : case CORETYPE_U128:
238 17 : ok = context->lookup_builtin ("u128", &infered);
239 17 : 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 14234 : default:
259 14234 : ok = true;
260 14234 : infered
261 14234 : = new TyTy::InferType (expr_mappings.get_hirid (),
262 : TyTy::InferType::InferTypeKind::INTEGRAL,
263 : TyTy::InferType::TypeHint::Default (),
264 14234 : locus);
265 14234 : break;
266 : }
267 16083 : 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 1303 : case HIR::Literal::LitType::BOOL:
298 1303 : {
299 1303 : auto ok = context->lookup_builtin ("bool", &infered);
300 1303 : 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 20725 : break;
393 : }
394 :
395 20725 : return infered;
396 : }
397 :
398 : TyTy::ADTType::ReprOptions
399 2983 : TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
400 : {
401 2983 : TyTy::ADTType::ReprOptions repr;
402 2983 : repr.pack = 0;
403 2983 : repr.align = 0;
404 :
405 : // Default repr for enums is isize, but we now check for other repr in the
406 : // attributes.
407 2983 : bool ok = context->lookup_builtin ("isize", &repr.repr);
408 2983 : rust_assert (ok);
409 :
410 3396 : for (const auto &attr : attrs)
411 : {
412 440 : bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
413 440 : 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 439 : if (is_repr)
420 : {
421 29 : const AST::AttrInput &input = attr.get_attr_input ();
422 29 : bool is_token_tree = input.get_attr_input_type ()
423 29 : == AST::AttrInput::AttrInputType::TOKEN_TREE;
424 29 : bool is_meta_item = input.get_attr_input_type ()
425 29 : == AST::AttrInput::AttrInputType::META_ITEM;
426 29 : if (!is_token_tree && !is_meta_item)
427 : {
428 1 : rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
429 2 : continue;
430 : }
431 :
432 28 : const AST::AttrInputMetaItemContainer *meta_items = nullptr;
433 28 : if (is_token_tree)
434 : {
435 27 : const auto &option
436 : = static_cast<const AST::DelimTokenTree &> (input);
437 27 : meta_items = option.parse_to_meta_item ();
438 : }
439 : else
440 : { // is_meta_item is true
441 1 : const auto &option
442 : = static_cast<const AST::AttrInputMetaItemContainer &> (input);
443 1 : meta_items = new AST::AttrInputMetaItemContainer (option);
444 : }
445 :
446 28 : if (meta_items == nullptr)
447 : {
448 0 : rust_error_at (attr.get_locus (), "malformed %qs attribute",
449 : "repr");
450 0 : continue;
451 : }
452 :
453 28 : auto &items = meta_items->get_items ();
454 28 : if (items.size () == 0)
455 : {
456 : // nothing to do with this its empty
457 1 : delete meta_items;
458 1 : continue;
459 : }
460 :
461 27 : const std::string inline_option = items.at (0)->as_string ();
462 :
463 : // TODO: it would probably be better to make the MetaItems more aware
464 : // of constructs with nesting like #[repr(packed(2))] rather than
465 : // manually parsing the string "packed(2)" here.
466 :
467 27 : size_t oparen = inline_option.find ('(', 0);
468 27 : bool is_pack = false;
469 27 : bool is_align = false;
470 27 : bool is_c = false;
471 27 : bool is_integer = false;
472 27 : unsigned char value = 1;
473 :
474 27 : if (oparen == std::string::npos)
475 : {
476 21 : is_pack = inline_option.compare ("packed") == 0;
477 21 : is_align = inline_option.compare ("align") == 0;
478 21 : is_c = inline_option.compare ("C") == 0;
479 21 : is_integer = (inline_option.compare ("isize") == 0
480 21 : || inline_option.compare ("i8") == 0
481 21 : || inline_option.compare ("i16") == 0
482 21 : || inline_option.compare ("i32") == 0
483 19 : || inline_option.compare ("i64") == 0
484 19 : || inline_option.compare ("i128") == 0
485 19 : || inline_option.compare ("usize") == 0
486 19 : || inline_option.compare ("u8") == 0
487 19 : || inline_option.compare ("u16") == 0
488 19 : || inline_option.compare ("u32") == 0
489 19 : || inline_option.compare ("u64") == 0
490 40 : || inline_option.compare ("u128") == 0);
491 : }
492 :
493 : else
494 : {
495 6 : std::string rep = inline_option.substr (0, oparen);
496 6 : is_pack = rep.compare ("packed") == 0;
497 6 : is_align = rep.compare ("align") == 0;
498 :
499 6 : size_t cparen = inline_option.find (')', oparen);
500 6 : if (cparen == std::string::npos)
501 : {
502 0 : rust_error_at (locus, "malformed attribute");
503 : }
504 :
505 6 : std::string value_str = inline_option.substr (oparen, cparen);
506 6 : value = strtoul (value_str.c_str () + 1, NULL, 10);
507 6 : }
508 :
509 27 : if (is_pack)
510 : {
511 4 : repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
512 4 : repr.pack = value;
513 : }
514 23 : else if (is_align)
515 : {
516 4 : repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
517 4 : repr.align = value;
518 : }
519 19 : else if (is_c)
520 : {
521 15 : repr.repr_kind = TyTy::ADTType::ReprKind::C;
522 : }
523 4 : else if (is_integer)
524 : {
525 2 : repr.repr_kind = TyTy::ADTType::ReprKind::INT;
526 4 : bool ok = context->lookup_builtin (inline_option, &repr.repr);
527 2 : if (!ok)
528 : {
529 0 : rust_error_at (attr.get_locus (), "Invalid repr type");
530 : }
531 : }
532 :
533 27 : delete meta_items;
534 :
535 : // Multiple repr options must be specified with e.g. #[repr(C,
536 : // packed(2))].
537 27 : break;
538 27 : }
539 : }
540 :
541 2983 : return repr;
542 : }
543 :
544 : void
545 8735 : TypeCheckBase::resolve_generic_params (
546 : const HIR::Item::ItemKind item_kind, location_t item_locus,
547 : const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
548 : std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
549 : ABI abi)
550 : {
551 18466 : for (auto &generic_param : generic_params)
552 : {
553 9731 : switch (generic_param->get_kind ())
554 : {
555 887 : case HIR::GenericParam::GenericKind::LIFETIME:
556 887 : {
557 887 : auto lifetime_param
558 887 : = static_cast<HIR::LifetimeParam &> (*generic_param);
559 887 : auto lifetime = lifetime_param.get_lifetime ();
560 887 : context->get_lifetime_resolver ().insert_mapping (
561 : context->intern_lifetime (lifetime));
562 887 : }
563 887 : break;
564 :
565 128 : case HIR::GenericParam::GenericKind::CONST:
566 128 : {
567 128 : if (is_foreign && abi != Rust::ABI::INTRINSIC)
568 : {
569 0 : rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
570 : "foreign items may not have const parameters");
571 : }
572 :
573 128 : auto ¶m
574 128 : = static_cast<HIR::ConstGenericParam &> (*generic_param);
575 128 : auto specified_type = TypeCheckType::Resolve (param.get_type ());
576 :
577 128 : if (param.has_default_expression ())
578 : {
579 13 : switch (item_kind)
580 : {
581 : case HIR::Item::ItemKind::Struct:
582 : case HIR::Item::ItemKind::Enum:
583 : case HIR::Item::ItemKind::TypeAlias:
584 : case HIR::Item::ItemKind::Trait:
585 : case HIR::Item::ItemKind::Union:
586 : break;
587 :
588 2 : default:
589 2 : {
590 2 : rich_location r (line_table, item_locus);
591 2 : r.add_fixit_remove (param.get_locus ());
592 2 : rust_error_at (
593 : r,
594 : "default values for const generic parameters are not "
595 : "allowed here");
596 2 : }
597 2 : break;
598 : }
599 :
600 13 : auto expr_type
601 13 : = TypeCheckExpr::Resolve (param.get_default_expression ());
602 :
603 26 : coercion_site (param.get_mappings ().get_hirid (),
604 13 : TyTy::TyWithLocation (specified_type),
605 : TyTy::TyWithLocation (
606 : expr_type,
607 13 : param.get_default_expression ().get_locus ()),
608 : param.get_locus ());
609 :
610 : // fold the default value
611 13 : auto ctx = Compile::Context::get ();
612 13 : auto &expr = param.get_default_expression ();
613 13 : tree default_value
614 13 : = Compile::HIRCompileBase::query_compile_const_expr (
615 : ctx, specified_type, expr);
616 :
617 13 : auto default_const_decl
618 : = new TyTy::ConstValueType (default_value, specified_type,
619 13 : expr.get_mappings ().get_hirid (),
620 13 : expr.get_mappings ().get_hirid (),
621 13 : {});
622 :
623 13 : context->insert_type (expr.get_mappings (), default_const_decl);
624 : }
625 :
626 128 : TyTy::BaseGeneric *const_decl
627 256 : = new TyTy::ConstParamType (param.get_name (), param.get_locus (),
628 : specified_type,
629 128 : param.get_mappings ().get_hirid (),
630 256 : param.get_mappings ().get_hirid (),
631 256 : {});
632 :
633 128 : context->insert_type (generic_param->get_mappings (), const_decl);
634 128 : TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
635 128 : substitutions.push_back (p);
636 : }
637 128 : break;
638 :
639 8716 : case HIR::GenericParam::GenericKind::TYPE:
640 8716 : {
641 8716 : if (is_foreign && abi != Rust::ABI::INTRINSIC)
642 : {
643 1 : rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
644 : "foreign items may not have type parameters");
645 : }
646 :
647 8716 : auto param_type = TypeResolveGenericParam::Resolve (
648 8716 : *generic_param, false /*resolve_trait_bounds*/);
649 8716 : context->insert_type (generic_param->get_mappings (), param_type);
650 :
651 8716 : TyTy::SubstitutionParamMapping p (*generic_param, param_type);
652 8716 : substitutions.push_back (p);
653 : }
654 8716 : break;
655 : }
656 : }
657 :
658 : // now walk them to setup any specified type param bounds
659 17665 : for (auto &subst : substitutions)
660 : {
661 8931 : auto &generic = subst.get_generic_param ();
662 8931 : if (generic.get_kind () != HIR::GenericParam::GenericKind::TYPE)
663 128 : continue;
664 :
665 8803 : auto &type_param = static_cast<HIR::TypeParam &> (generic);
666 8803 : auto bpty = subst.get_param_ty ();
667 8803 : rust_assert (bpty->get_kind () == TyTy::TypeKind::PARAM);
668 8803 : auto pty = static_cast<TyTy::ParamType *> (bpty);
669 :
670 8803 : TypeResolveGenericParam::ApplyAnyTraitBounds (type_param, pty);
671 : }
672 8734 : }
673 :
674 : TyTy::TypeBoundPredicate
675 9444 : TypeCheckBase::get_marker_predicate (LangItem::Kind item_type, location_t locus)
676 : {
677 9444 : DefId item_id = mappings.get_lang_item (item_type, locus);
678 9443 : HIR::Item *item = mappings.lookup_defid (item_id).value ();
679 9443 : rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
680 :
681 9443 : HIR::Trait &trait = *static_cast<HIR::Trait *> (item);
682 9443 : TraitReference *ref = TraitResolver::Resolve (trait);
683 9443 : rust_assert (ref != nullptr);
684 :
685 9443 : return TyTy::TypeBoundPredicate (*ref, BoundPolarity::RegularBound, locus);
686 : }
687 :
688 : } // namespace Resolver
689 : } // namespace Rust
|