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 : 2757644 : TypeCheckBase::TypeCheckBase ()
34 : 2757644 : : mappings (Analysis::Mappings::get ()), context (TypeCheckContext::get ())
35 : 2757644 : {}
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 : 11517 : walk_types_to_constrain (std::set<HirId> &constrained_symbols,
51 : : const TyTy::SubstitutionArgumentMappings &constraints)
52 : : {
53 : 18364 : 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 : 253 : walk_types_to_constrain (constrained_symbols,
65 : : p->get_subst_argument_mappings ());
66 : : }
67 : : }
68 : : }
69 : 11517 : }
70 : :
71 : : static void
72 : 5632 : walk_type_to_constrain (std::set<HirId> &constrained_symbols, TyTy::BaseType &r)
73 : : {
74 : 6112 : 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 : 5632 : }
147 : :
148 : : bool
149 : 41254 : 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 : 41254 : bool check_result = false;
156 : 41254 : bool check_completed
157 : 41254 : = context->have_checked_for_unconstrained (reference->get_ref (),
158 : : &check_result);
159 : 41254 : if (check_completed)
160 : 35622 : return check_result;
161 : :
162 : 5632 : std::set<HirId> symbols_to_constrain;
163 : 5632 : std::map<HirId, location_t> symbol_to_location;
164 : 6625 : 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 : 11264 : std::set<HirId> constrained_symbols;
173 : 5632 : walk_types_to_constrain (constrained_symbols, constraint_a);
174 : 5632 : walk_types_to_constrain (constrained_symbols, constraint_b);
175 : 5632 : walk_type_to_constrain (constrained_symbols, *reference);
176 : :
177 : : // check for unconstrained
178 : 5632 : bool unconstrained = false;
179 : 6625 : 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 : 5632 : context->insert_unconstrained_check_marker (reference->get_ref (),
191 : : unconstrained);
192 : :
193 : 5632 : return unconstrained;
194 : 5632 : }
195 : :
196 : : TyTy::BaseType *
197 : 18884 : TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
198 : : HIR::Literal &literal, location_t locus)
199 : : {
200 : 18884 : TyTy::BaseType *infered = nullptr;
201 : 18884 : switch (literal.get_lit_type ())
202 : : {
203 : 14260 : case HIR::Literal::LitType::INT:
204 : 14260 : {
205 : 14260 : bool ok = false;
206 : :
207 : 14260 : 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 : 13122 : default:
259 : 13122 : ok = true;
260 : 13122 : infered
261 : 13122 : = new TyTy::InferType (expr_mappings.get_hirid (),
262 : : TyTy::InferType::InferTypeKind::INTEGRAL,
263 : : TyTy::InferType::TypeHint::Default (),
264 : 13122 : locus);
265 : 13122 : break;
266 : : }
267 : 14260 : rust_assert (ok);
268 : : }
269 : : break;
270 : :
271 : 324 : case HIR::Literal::LitType::FLOAT:
272 : 324 : {
273 : 324 : bool ok = false;
274 : :
275 : 324 : switch (literal.get_type_hint ())
276 : : {
277 : 27 : case CORETYPE_F32:
278 : 27 : ok = context->lookup_builtin ("f32", &infered);
279 : 27 : break;
280 : 16 : case CORETYPE_F64:
281 : 16 : ok = context->lookup_builtin ("f64", &infered);
282 : 16 : break;
283 : :
284 : 281 : default:
285 : 281 : ok = true;
286 : 281 : infered
287 : 281 : = new TyTy::InferType (expr_mappings.get_hirid (),
288 : : TyTy::InferType::InferTypeKind::FLOAT,
289 : : TyTy::InferType::TypeHint::Default (),
290 : 281 : locus);
291 : 281 : break;
292 : : }
293 : 324 : rust_assert (ok);
294 : : }
295 : : break;
296 : :
297 : 1294 : case HIR::Literal::LitType::BOOL:
298 : 1294 : {
299 : 1294 : auto ok = context->lookup_builtin ("bool", &infered);
300 : 1294 : 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 : 2377 : case HIR::Literal::LitType::STRING:
319 : 2377 : {
320 : 2377 : TyTy::BaseType *base = nullptr;
321 : 2377 : auto ok = context->lookup_builtin ("str", &base);
322 : 2377 : rust_assert (ok);
323 : :
324 : 4754 : infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
325 : 2377 : TyTy::TyVar (base->get_ref ()),
326 : : Mutability::Imm,
327 : 4754 : TyTy::Region::make_static ());
328 : : }
329 : 2377 : 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 : 18884 : break;
393 : : }
394 : :
395 : 18884 : return infered;
396 : : }
397 : :
398 : : TyTy::ADTType::ReprOptions
399 : 2948 : TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
400 : : {
401 : 2948 : TyTy::ADTType::ReprOptions repr;
402 : 2948 : repr.pack = 0;
403 : 2948 : repr.align = 0;
404 : :
405 : : // Default repr for enums is isize, but we now check for other repr in the
406 : : // attributes.
407 : 2948 : bool ok = context->lookup_builtin ("isize", &repr.repr);
408 : 2948 : rust_assert (ok);
409 : :
410 : 3368 : 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 : 2948 : return repr;
529 : : }
530 : :
531 : : void
532 : 8569 : 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 : 18134 : for (auto &generic_param : generic_params)
539 : : {
540 : 9565 : switch (generic_param->get_kind ())
541 : : {
542 : 886 : case HIR::GenericParam::GenericKind::LIFETIME:
543 : 886 : {
544 : 886 : auto lifetime_param
545 : 886 : = static_cast<HIR::LifetimeParam &> (*generic_param);
546 : 886 : auto lifetime = lifetime_param.get_lifetime ();
547 : 886 : context->get_lifetime_resolver ().insert_mapping (
548 : : context->intern_lifetime (lifetime));
549 : 886 : }
550 : 886 : 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 : 8554 : case HIR::GenericParam::GenericKind::TYPE:
627 : 8554 : {
628 : 8554 : 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 : 8554 : auto param_type = TypeResolveGenericParam::Resolve (
635 : 8554 : *generic_param, false /*resolve_trait_bounds*/);
636 : 8554 : context->insert_type (generic_param->get_mappings (), param_type);
637 : :
638 : 8554 : TyTy::SubstitutionParamMapping p (*generic_param, param_type);
639 : 8554 : substitutions.push_back (p);
640 : : }
641 : 8554 : break;
642 : : }
643 : : }
644 : :
645 : : // now walk them to setup any specified type param bounds
646 : 17334 : for (auto &subst : substitutions)
647 : : {
648 : 8766 : auto &generic = subst.get_generic_param ();
649 : 8766 : if (generic.get_kind () != HIR::GenericParam::GenericKind::TYPE)
650 : 125 : continue;
651 : :
652 : 8641 : auto &type_param = static_cast<HIR::TypeParam &> (generic);
653 : 8641 : auto bpty = subst.get_param_ty ();
654 : 8641 : rust_assert (bpty->get_kind () == TyTy::TypeKind::PARAM);
655 : 8641 : auto pty = static_cast<TyTy::ParamType *> (bpty);
656 : :
657 : 8641 : TypeResolveGenericParam::ApplyAnyTraitBounds (type_param, pty);
658 : : }
659 : 8568 : }
660 : :
661 : : TyTy::TypeBoundPredicate
662 : 9282 : TypeCheckBase::get_marker_predicate (LangItem::Kind item_type, location_t locus)
663 : : {
664 : 9282 : DefId item_id = mappings.get_lang_item (item_type, locus);
665 : 9281 : HIR::Item *item = mappings.lookup_defid (item_id).value ();
666 : 9281 : rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
667 : :
668 : 9281 : HIR::Trait &trait = *static_cast<HIR::Trait *> (item);
669 : 9281 : TraitReference *ref = TraitResolver::Resolve (trait);
670 : 9281 : rust_assert (ref != nullptr);
671 : :
672 : 9281 : return TyTy::TypeBoundPredicate (*ref, BoundPolarity::RegularBound, locus);
673 : : }
674 : :
675 : : } // namespace Resolver
676 : : } // namespace Rust
|