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-item.h"
20 : #include "optional.h"
21 : #include "rust-canonical-path.h"
22 : #include "rust-diagnostics.h"
23 : #include "rust-hir-item.h"
24 : #include "rust-hir-type-check-enumitem.h"
25 : #include "rust-hir-type-check-implitem.h"
26 : #include "rust-hir-type-check-type.h"
27 : #include "rust-hir-type-check-expr.h"
28 : #include "rust-hir-type-check-pattern.h"
29 : #include "rust-hir-trait-resolve.h"
30 : #include "rust-hir-type-check.h"
31 : #include "rust-identifier.h"
32 : #include "rust-rib.h"
33 : #include "rust-session-manager.h"
34 : #include "rust-finalized-name-resolution-context.h"
35 : #include "rust-substitution-mapper.h"
36 : #include "rust-type-util.h"
37 : #include "rust-tyty-variance-analysis.h"
38 : #include "rust-tyty.h"
39 : #include "options.h"
40 : #include "rust-compile-base.h"
41 : #include "rust-compile-context.h"
42 :
43 : namespace Rust {
44 : namespace Resolver {
45 :
46 : static bool
47 5567 : type_contains_adt_without_indirection (
48 : const TyTy::BaseType *type, DefId target,
49 : std::set<const TyTy::BaseType *> &visited)
50 : {
51 5567 : bool found = visited.find (type) != visited.end ();
52 5567 : if (found)
53 : return false;
54 5567 : visited.insert (type);
55 :
56 5567 : switch (type->get_kind ())
57 : {
58 437 : case TyTy::TypeKind::ADT:
59 437 : {
60 437 : auto *adt = static_cast<const TyTy::ADTType *> (type);
61 437 : if (adt->get_id () == target)
62 5 : return true;
63 :
64 875 : for (auto *variant : adt->get_variants ())
65 : {
66 1160 : for (auto *field : variant->get_fields ())
67 : {
68 717 : if (type_contains_adt_without_indirection (
69 717 : field->get_field_type (), target, visited))
70 5567 : return true;
71 : }
72 : }
73 :
74 : return false;
75 : }
76 :
77 18 : case TyTy::TypeKind::TUPLE:
78 18 : {
79 18 : auto *tuple = static_cast<const TyTy::TupleType *> (type);
80 22 : for (const auto &field : tuple->get_fields ())
81 : {
82 5 : if (type_contains_adt_without_indirection (field.get_tyty (),
83 : target, visited))
84 5567 : return true;
85 : }
86 :
87 : return false;
88 : }
89 :
90 72 : case TyTy::TypeKind::ARRAY:
91 72 : return type_contains_adt_without_indirection (
92 72 : static_cast<const TyTy::ArrayType *> (type)->get_element_type (),
93 72 : target, visited);
94 :
95 15 : case TyTy::TypeKind::SLICE:
96 15 : return type_contains_adt_without_indirection (
97 15 : static_cast<const TyTy::SliceType *> (type)->get_element_type (),
98 15 : target, visited);
99 :
100 : default:
101 : return false;
102 : }
103 : }
104 :
105 : static bool
106 3437 : validate_adt_size (TyTy::ADTType *type)
107 : {
108 7620 : for (auto *variant : type->get_variants ())
109 : {
110 8941 : for (auto *field : variant->get_fields ())
111 : {
112 4758 : std::set<const TyTy::BaseType *> visited;
113 4758 : if (!type_contains_adt_without_indirection (field->get_field_type (),
114 : type->get_id (), visited))
115 4753 : continue;
116 :
117 10 : rust_error_at (field->get_locus (), ErrorCode::E0072,
118 : "recursive type %qs has infinite size",
119 5 : type->get_identifier ().c_str ());
120 5 : return false;
121 4758 : }
122 : }
123 :
124 : return true;
125 : }
126 :
127 : // Const-evaluate the discriminants of a repr(C) enum and warn when a value does
128 : // not fit into a C int/unsigned int. Done here, during type resolution, using
129 : // the compile context (a singleton shared with the backend).
130 : static void
131 3 : check_repr_c_enum_discriminants (Compile::Context *ctx, TyTy::BaseType *type)
132 : {
133 3 : if (type->get_kind () != TyTy::TypeKind::ADT)
134 : return;
135 :
136 3 : auto &adt = static_cast<TyTy::ADTType &> (*type);
137 3 : if (!adt.is_enum ()
138 3 : || adt.get_repr_options ().repr_kind != TyTy::ADTType::ReprKind::C)
139 : return;
140 :
141 4 : for (auto &variant : adt.get_variants ())
142 : {
143 2 : if (!variant->has_discriminant ())
144 0 : continue;
145 :
146 2 : HIR::Expr &discriminant = variant->get_discriminant ();
147 2 : TyTy::BaseType *discrim_ty = nullptr;
148 2 : if (!ctx->get_tyctx ()->lookup_type (
149 2 : discriminant.get_mappings ().get_hirid (), &discrim_ty))
150 0 : continue;
151 :
152 2 : tree folded
153 2 : = Compile::HIRCompileBase::query_compile_const_expr (ctx, discrim_ty,
154 : discriminant);
155 2 : if (folded == error_mark_node || TREE_CODE (folded) != INTEGER_CST)
156 0 : continue;
157 :
158 2 : widest_int value = wi::to_widest (folded);
159 2 : if (wi::lts_p (value, INT32_MIN) || wi::gts_p (value, UINT32_MAX))
160 1 : rust_warning_at (discriminant.get_locus (), OPT_Woverflow,
161 : "%<repr(C)%> enum discriminant does not fit into C "
162 : "%<int%> nor into C %<unsigned int%>");
163 2 : }
164 : }
165 :
166 53933 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
167 :
168 : TyTy::BaseType *
169 29756 : TypeCheckItem::Resolve (HIR::Item &item)
170 : {
171 : // is it already resolved?
172 29756 : auto context = TypeCheckContext::get ();
173 29756 : TyTy::BaseType *resolved = nullptr;
174 29756 : bool already_resolved
175 29756 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
176 29756 : if (already_resolved)
177 : {
178 5215 : bool function_body_pending = false;
179 5215 : if (auto fn = resolved->try_as<TyTy::FnType> ())
180 185 : function_body_pending = context->function_body_pending (fn->get_id ());
181 :
182 185 : if (!function_body_pending)
183 5035 : return resolved;
184 : }
185 :
186 24721 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
187 24721 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
188 :
189 24721 : TypeCheckItem resolver;
190 24721 : vis_item.accept_vis (resolver);
191 24720 : return resolver.infered;
192 24720 : }
193 :
194 : TyTy::FnType *
195 180 : TypeCheckItem::ResolveFunctionSignature (HIR::Function &function)
196 : {
197 180 : TypeCheckItem resolver;
198 180 : auto lifetime_pin = resolver.context->push_clean_lifetime_resolver ();
199 180 : TyTy::FnType *result = resolver.resolve_function_signature (function);
200 180 : if (result != nullptr)
201 180 : resolver.context->mark_function_body_pending (result->get_id ());
202 360 : return result;
203 180 : }
204 :
205 : TyTy::BaseType *
206 409 : TypeCheckItem::ResolveTraitSignature (HIR::Trait &trait)
207 : {
208 409 : TypeCheckItem resolver;
209 409 : return resolver.resolve_trait (trait, false);
210 409 : }
211 :
212 : TyTy::BaseType *
213 1 : TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
214 : {
215 1 : TypeCheckItem resolver;
216 1 : return resolver.resolve_impl_item (impl_block, item);
217 1 : }
218 :
219 : TyTy::BaseType *
220 23363 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
221 : {
222 23363 : TypeCheckItem resolver;
223 23363 : auto lifetime_pin = resolver.context->push_clean_lifetime_resolver (true);
224 :
225 23363 : bool failed_flag = false;
226 23363 : auto result
227 23363 : = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
228 23363 : if (failed_flag)
229 : {
230 0 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
231 : }
232 23363 : std::vector<TyTy::SubstitutionParamMapping> substitutions
233 23363 : = std::move (result.first);
234 23363 : TyTy::RegionConstraints region_constraints = std::move (result.second);
235 :
236 23363 : return resolver.resolve_impl_block_self (impl_block);
237 23363 : }
238 :
239 : TyTy::BaseType *
240 3208 : TypeCheckItem::ResolveImplBlockSelfWithInference (
241 : HIR::ImplBlock &impl, location_t locus,
242 : TyTy::SubstitutionArgumentMappings *infer_arguments)
243 : {
244 3208 : TypeCheckItem resolver;
245 3208 : auto lifetime_pin = resolver.context->push_clean_lifetime_resolver (true);
246 :
247 3208 : bool failed_flag = false;
248 3208 : auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
249 3208 : if (failed_flag)
250 : {
251 1 : return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
252 : }
253 3207 : std::vector<TyTy::SubstitutionParamMapping> substitutions
254 3207 : = std::move (result.first);
255 3207 : TyTy::RegionConstraints region_constraints = std::move (result.second);
256 :
257 : // now that we have the param mappings we need to query the self type
258 3207 : TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
259 :
260 : // nothing to do
261 3207 : if (substitutions.empty () || self->is_concrete ())
262 : return self;
263 :
264 : // generate inference variables for the subst-param-mappings
265 780 : std::vector<TyTy::SubstitutionArg> args;
266 1594 : for (auto &p : substitutions)
267 : {
268 814 : auto param = p.get_param_ty ();
269 814 : if (!p.needs_substitution ())
270 : {
271 0 : auto resolved = param->destructure ();
272 0 : args.emplace_back (&p, resolved);
273 :
274 0 : continue;
275 0 : }
276 :
277 814 : TyTy::BaseType *argument = nullptr;
278 814 : if (param->get_kind () == TyTy::TypeKind::CONST)
279 : {
280 28 : auto i = TyTy::TyVar::get_implicit_const_infer_var (locus);
281 28 : argument = i.get_tyty ();
282 : }
283 : else
284 : {
285 786 : auto i = TyTy::TyVar::get_implicit_infer_var (locus);
286 786 : argument = i.get_tyty ();
287 : }
288 814 : args.emplace_back (&p, argument);
289 : }
290 :
291 : // create argument mappings
292 780 : *infer_arguments = TyTy::SubstitutionArgumentMappings (
293 : std::move (args), {},
294 1560 : TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
295 : infer_arguments),
296 1560 : locus);
297 :
298 780 : TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
299 :
300 : // we only need to apply to the bounds manually on types which dont bind
301 : // generics
302 780 : if (!infer->has_substitutions_defined ())
303 : {
304 693 : for (auto &bound : infer->get_specified_bounds ())
305 185 : bound.handle_substitions (*infer_arguments);
306 : }
307 :
308 780 : return infer;
309 3988 : }
310 :
311 : std::vector<TyTy::SubstitutionParamMapping>
312 2051 : TypeCheckItem::ResolveImplBlockSubstitutions (HIR::ImplBlock &impl_block,
313 : bool &failure_flag)
314 : {
315 2051 : TypeCheckItem resolver;
316 2051 : auto result
317 2051 : = resolver.resolve_impl_block_substitutions (impl_block, failure_flag);
318 2051 : return std::move (result.first);
319 2051 : }
320 :
321 : void
322 5357 : TypeCheckItem::validate_trait_impl_block (
323 : const TyTy::TypeBoundPredicate &specified_bound,
324 : std::vector<const TraitItemReference *> trait_item_refs,
325 : TraitReference *trait_reference, HIR::ImplBlock &impl_block,
326 : TyTy::BaseType *self,
327 : std::vector<TyTy::SubstitutionParamMapping> &substitutions)
328 : {
329 5357 : bool impl_block_missing_trait_items
330 5357 : = !specified_bound.is_error ()
331 5357 : && trait_reference->size () != trait_item_refs.size ();
332 1722 : if (impl_block_missing_trait_items
333 1722 : && impl_block.get_polarity () == BoundPolarity::RegularBound)
334 : {
335 : // filter the missing impl_items
336 1720 : std::vector<std::reference_wrapper<const TraitItemReference>>
337 1720 : missing_trait_items;
338 5435 : for (const auto &trait_item_ref : trait_reference->get_trait_items ())
339 : {
340 3715 : bool found = false;
341 5706 : for (auto implemented_trait_item : trait_item_refs)
342 : {
343 3539 : std::string trait_item_name = trait_item_ref.get_identifier ();
344 3539 : std::string impl_item_name
345 3539 : = implemented_trait_item->get_identifier ();
346 3539 : found = trait_item_name == impl_item_name;
347 3539 : if (found)
348 : break;
349 3539 : }
350 :
351 3715 : bool is_required_trait_item = !trait_item_ref.is_optional ();
352 3715 : if (!found && is_required_trait_item)
353 7 : missing_trait_items.emplace_back (trait_item_ref);
354 : }
355 :
356 1720 : if (!missing_trait_items.empty ())
357 : {
358 5 : std::string missing_items_buf;
359 5 : rich_location r (line_table, impl_block.get_locus ());
360 17 : for (size_t i = 0; i < missing_trait_items.size (); i++)
361 : {
362 7 : bool has_more = (i + 1) < missing_trait_items.size ();
363 7 : const TraitItemReference &missing_trait_item
364 7 : = missing_trait_items.at (i);
365 7 : missing_items_buf += missing_trait_item.get_identifier ()
366 21 : + (has_more ? ", " : "");
367 7 : r.add_range (missing_trait_item.get_locus ());
368 : }
369 :
370 5 : rust_error_at (r, ErrorCode::E0046,
371 : "missing %s in implementation of trait %qs",
372 : missing_items_buf.c_str (),
373 5 : trait_reference->get_name ().c_str ());
374 5 : }
375 1720 : }
376 5357 : }
377 :
378 : void
379 73 : TypeCheckItem::visit (HIR::TypeAlias &alias)
380 : {
381 73 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
382 :
383 73 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
384 73 : if (alias.has_generics ())
385 10 : resolve_generic_params (HIR::Item::ItemKind::TypeAlias, alias.get_locus (),
386 10 : alias.get_generic_params (), substitutions);
387 :
388 73 : TyTy::BaseType *actual_type
389 73 : = TypeCheckType::Resolve (alias.get_type_aliased ());
390 :
391 73 : context->insert_type (alias.get_mappings (), actual_type);
392 :
393 73 : TyTy::RegionConstraints region_constraints;
394 73 : ResolveWhereClauseItem::Resolve (alias.get_where_clause (),
395 : region_constraints);
396 73 : infered = actual_type;
397 73 : }
398 :
399 : void
400 1030 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
401 : {
402 1030 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
403 :
404 1030 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
405 1030 : if (struct_decl.has_generics ())
406 312 : resolve_generic_params (HIR::Item::ItemKind::Struct,
407 : struct_decl.get_locus (),
408 312 : struct_decl.get_generic_params (), substitutions);
409 :
410 1030 : TyTy::RegionConstraints region_constraints;
411 1030 : ResolveWhereClauseItem::Resolve (struct_decl.get_where_clause (),
412 : region_constraints);
413 :
414 : // Process #[repr(X)] attribute, if any
415 1030 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
416 1030 : TyTy::ADTType::ReprOptions repr
417 1030 : = parse_repr_options (attrs, struct_decl.get_locus ());
418 :
419 1030 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
420 1030 : CanonicalPath path
421 1030 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
422 1030 : Resolver2_0::Namespace::Types);
423 1030 : RustIdent ident{path, struct_decl.get_locus ()};
424 :
425 1030 : std::vector<TyTy::VariantDef *> variants;
426 1030 : auto *type = new TyTy::ADTType (
427 1030 : struct_decl.get_mappings ().get_defid (),
428 1030 : struct_decl.get_mappings ().get_hirid (),
429 1030 : struct_decl.get_mappings ().get_hirid (),
430 1030 : struct_decl.get_identifier ().as_string (), ident,
431 : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
432 : std::move (substitutions), repr,
433 2060 : TyTy::SubstitutionArgumentMappings::empty (
434 1030 : context->get_lifetime_resolver ().get_num_bound_regions ()),
435 4120 : region_constraints);
436 1030 : context->insert_type (struct_decl.get_mappings (), type);
437 :
438 1030 : std::vector<TyTy::StructFieldType *> fields;
439 1030 : size_t idx = 0;
440 2844 : for (auto &field : struct_decl.get_fields ())
441 : {
442 1814 : TyTy::BaseType *field_type
443 1814 : = TypeCheckType::Resolve (field.get_field_type ());
444 1814 : auto *ty_field
445 3628 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
446 1814 : std::to_string (idx), field_type,
447 1814 : field.get_locus ());
448 1814 : fields.push_back (ty_field);
449 1814 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
450 1814 : idx++;
451 : }
452 :
453 1030 : if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
454 : {
455 14 : bool is_valid = validate_repr_simd (fields, struct_decl.get_locus ());
456 14 : if (!is_valid)
457 : return;
458 : }
459 :
460 : // its a single variant ADT
461 1027 : auto variant
462 1027 : = new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
463 1027 : struct_decl.get_mappings ().get_defid (),
464 1027 : struct_decl.get_identifier ().as_string (), ident,
465 2054 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
466 2054 : std::move (fields));
467 1027 : type->get_variants ().push_back (variant);
468 1027 : if (!validate_adt_size (type))
469 : {
470 2 : infered = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
471 2 : context->insert_type (struct_decl.get_mappings (), infered);
472 2 : return;
473 : }
474 1025 : infered = type;
475 :
476 1025 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
477 2060 : }
478 :
479 : void
480 1739 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
481 : {
482 1739 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
483 1739 : auto &mappings = Analysis::Mappings::get ();
484 :
485 1739 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
486 1739 : CanonicalPath path
487 1739 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
488 1739 : Resolver2_0::Namespace::Types);
489 1739 : RustIdent ident{path, struct_decl.get_locus ()};
490 :
491 1739 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
492 1739 : if (struct_decl.has_generics ())
493 543 : resolve_generic_params (HIR::Item::ItemKind::Struct,
494 : struct_decl.get_locus (),
495 543 : struct_decl.get_generic_params (), substitutions);
496 :
497 1739 : TyTy::RegionConstraints region_constraints;
498 1739 : ResolveWhereClauseItem::Resolve (struct_decl.get_where_clause (),
499 : region_constraints);
500 :
501 : // Process #[repr(X)] attribute, if any
502 1739 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
503 1739 : TyTy::ADTType::ReprOptions repr
504 1739 : = parse_repr_options (attrs, struct_decl.get_locus ());
505 :
506 1739 : std::vector<TyTy::VariantDef *> variants;
507 1739 : auto *type = new TyTy::ADTType (
508 1739 : struct_decl.get_mappings ().get_defid (),
509 1739 : struct_decl.get_mappings ().get_hirid (),
510 1739 : struct_decl.get_mappings ().get_hirid (),
511 1739 : struct_decl.get_identifier ().as_string (), ident,
512 : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
513 : std::move (substitutions), repr,
514 3478 : TyTy::SubstitutionArgumentMappings::empty (
515 1739 : context->get_lifetime_resolver ().get_num_bound_regions ()),
516 6956 : region_constraints);
517 1739 : context->insert_type (struct_decl.get_mappings (), type);
518 :
519 1739 : std::vector<TyTy::StructFieldType *> fields;
520 3756 : for (auto &field : struct_decl.get_fields ())
521 : {
522 2022 : TyTy::BaseType *field_type
523 2022 : = TypeCheckType::Resolve (field.get_field_type ());
524 2022 : auto infer_type = field_type->contains_infer ();
525 2022 : if (infer_type)
526 : {
527 5 : rust_error_at (mappings.lookup_location (infer_type->get_ref ()),
528 : "the placeholder %<_%> is not allowed within types on "
529 : "item signatures for structs");
530 5 : infered
531 5 : = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
532 5 : context->insert_type (struct_decl.get_mappings (), infered);
533 5 : return;
534 : }
535 2017 : auto *ty_field
536 2017 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
537 2017 : field.get_field_name ().as_string (),
538 4034 : field_type, field.get_locus ());
539 2017 : fields.push_back (ty_field);
540 2017 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
541 : }
542 :
543 1734 : if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
544 : {
545 0 : bool is_valid = validate_repr_simd (fields, struct_decl.get_locus ());
546 0 : if (!is_valid)
547 : return;
548 : }
549 1734 : if (repr.repr_kind == TyTy::ADTType::ReprKind::TRANSPARENT)
550 : {
551 26 : size_t num_non_zst = 0;
552 55 : for (auto &field : fields)
553 : {
554 29 : if (!field->get_field_type ()->is_zero_sized ())
555 26 : num_non_zst++;
556 : }
557 26 : if (num_non_zst > 1)
558 : {
559 1 : rust_error_at (struct_decl.get_locus (), ErrorCode::E0690,
560 : "transparent struct needs at most one field with "
561 : "non-trivial size or alignment, but has %lu",
562 : (unsigned long) num_non_zst);
563 1 : return;
564 : }
565 : }
566 :
567 : // its a single variant ADT
568 1733 : auto variant_type = struct_decl.is_unit_struct ()
569 1733 : ? TyTy::VariantDef::VariantType::UNIT
570 1122 : : TyTy::VariantDef::VariantType::STRUCT;
571 1733 : auto variant
572 1733 : = new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
573 1733 : struct_decl.get_mappings ().get_defid (),
574 1733 : struct_decl.get_identifier ().as_string (), ident,
575 3466 : variant_type, tl::nullopt, std::move (fields));
576 1733 : type->get_variants ().push_back (variant);
577 1733 : if (!validate_adt_size (type))
578 : {
579 3 : infered = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
580 3 : context->insert_type (struct_decl.get_mappings (), infered);
581 3 : return;
582 : }
583 1730 : infered = type;
584 :
585 1730 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
586 3478 : }
587 :
588 : void
589 574 : TypeCheckItem::visit (HIR::Enum &enum_decl)
590 : {
591 574 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
592 574 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
593 574 : if (enum_decl.has_generics ())
594 247 : resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
595 247 : enum_decl.get_generic_params (), substitutions);
596 :
597 574 : TyTy::RegionConstraints region_constraints;
598 574 : ResolveWhereClauseItem::Resolve (enum_decl.get_where_clause (),
599 : region_constraints);
600 :
601 574 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
602 574 : CanonicalPath canonical_path
603 574 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid (),
604 574 : Resolver2_0::Namespace::Types);
605 :
606 574 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
607 :
608 : // Process #[repr(X)] attribute, if any
609 574 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
610 574 : TyTy::ADTType::ReprOptions repr
611 574 : = parse_repr_options (attrs, enum_decl.get_locus ());
612 :
613 574 : std::vector<TyTy::VariantDef *> variants;
614 574 : auto *type = new TyTy::ADTType (
615 574 : enum_decl.get_mappings ().get_defid (),
616 574 : enum_decl.get_mappings ().get_hirid (),
617 574 : enum_decl.get_mappings ().get_hirid (),
618 574 : enum_decl.get_identifier ().as_string (), ident,
619 : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
620 : std::move (substitutions), repr,
621 1148 : TyTy::SubstitutionArgumentMappings::empty (
622 574 : context->get_lifetime_resolver ().get_num_bound_regions ()),
623 2296 : region_constraints);
624 574 : context->insert_type (enum_decl.get_mappings (), type);
625 :
626 574 : int64_t discriminant_value = 0;
627 1898 : for (auto &variant : enum_decl.get_variants ())
628 : {
629 1324 : TyTy::VariantDef *field_type
630 1324 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
631 1324 : if (field_type)
632 : {
633 1323 : discriminant_value++;
634 1323 : type->get_variants ().push_back (field_type);
635 : }
636 : }
637 :
638 : // Check for zero-variant enum compatibility
639 574 : if (enum_decl.is_zero_variant ())
640 : {
641 11 : if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
642 11 : || repr.repr_kind == TyTy::ADTType::ReprKind::C)
643 : {
644 2 : rust_error_at (enum_decl.get_locus (),
645 : "unsupported representation for zero-variant enum");
646 2 : return;
647 : }
648 : }
649 :
650 572 : if (!validate_adt_size (type))
651 : {
652 0 : infered = new TyTy::ErrorType (enum_decl.get_mappings ().get_hirid ());
653 0 : context->insert_type (enum_decl.get_mappings (), infered);
654 0 : return;
655 : }
656 572 : infered = type;
657 :
658 572 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
659 :
660 572 : if (flag_unused_check_2_0)
661 3 : check_repr_c_enum_discriminants (Compile::Context::get (), type);
662 1148 : }
663 :
664 : void
665 105 : TypeCheckItem::visit (HIR::Union &union_decl)
666 : {
667 105 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
668 105 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
669 105 : if (union_decl.has_generics ())
670 75 : resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
671 75 : union_decl.get_generic_params (), substitutions);
672 :
673 105 : TyTy::RegionConstraints region_constraints;
674 105 : ResolveWhereClauseItem::Resolve (union_decl.get_where_clause (),
675 : region_constraints);
676 :
677 105 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
678 105 : CanonicalPath canonical_path
679 105 : = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid (),
680 105 : Resolver2_0::Namespace::Types);
681 :
682 105 : RustIdent ident{canonical_path, union_decl.get_locus ()};
683 :
684 : // Process #[repr(X)] attribute, if any
685 105 : const AST::AttrVec &attrs = union_decl.get_outer_attrs ();
686 105 : TyTy::ADTType::ReprOptions repr
687 105 : = parse_repr_options (attrs, union_decl.get_locus ());
688 :
689 105 : std::vector<TyTy::VariantDef *> variants;
690 105 : auto *type = new TyTy::ADTType (
691 105 : union_decl.get_mappings ().get_defid (),
692 105 : union_decl.get_mappings ().get_hirid (),
693 105 : union_decl.get_mappings ().get_hirid (),
694 105 : union_decl.get_identifier ().as_string (), ident,
695 : TyTy::ADTType::ADTKind::UNION, std::move (variants),
696 : std::move (substitutions), repr,
697 210 : TyTy::SubstitutionArgumentMappings::empty (
698 105 : context->get_lifetime_resolver ().get_num_bound_regions ()),
699 420 : region_constraints);
700 105 : context->insert_type (union_decl.get_mappings (), type);
701 :
702 105 : std::vector<TyTy::StructFieldType *> fields;
703 409 : for (auto &variant : union_decl.get_variants ())
704 : {
705 304 : TyTy::BaseType *variant_type
706 304 : = TypeCheckType::Resolve (variant.get_field_type ());
707 304 : auto *ty_variant
708 304 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
709 304 : variant.get_field_name ().as_string (),
710 608 : variant_type, variant.get_locus ());
711 304 : fields.push_back (ty_variant);
712 304 : context->insert_type (variant.get_mappings (),
713 : ty_variant->get_field_type ());
714 : }
715 :
716 105 : auto variant
717 105 : = new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
718 105 : union_decl.get_mappings ().get_defid (),
719 105 : union_decl.get_identifier ().as_string (), ident,
720 210 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
721 210 : std::move (fields));
722 105 : type->get_variants ().push_back (variant);
723 105 : if (!validate_adt_size (type))
724 : {
725 0 : infered = new TyTy::ErrorType (union_decl.get_mappings ().get_hirid ());
726 0 : context->insert_type (union_decl.get_mappings (), infered);
727 0 : return;
728 : }
729 :
730 105 : infered = type;
731 :
732 105 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
733 210 : }
734 :
735 : void
736 76 : TypeCheckItem::visit (HIR::StaticItem &var)
737 : {
738 76 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
739 76 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
740 :
741 76 : TyTy::BaseType *unified
742 76 : = coercion_site (var.get_mappings ().get_hirid (),
743 76 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
744 : TyTy::TyWithLocation (expr_type,
745 76 : var.get_expr ().get_locus ()),
746 : var.get_locus ());
747 76 : context->insert_type (var.get_mappings (), unified);
748 76 : infered = unified;
749 76 : }
750 :
751 : void
752 446 : TypeCheckItem::visit (HIR::ConstantItem &constant)
753 : {
754 446 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
755 446 : context->push_const_context ();
756 446 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
757 446 : context->pop_const_context ();
758 :
759 892 : TyTy::BaseType *unified = coercion_site (
760 446 : constant.get_mappings ().get_hirid (),
761 446 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
762 446 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
763 : constant.get_locus ());
764 446 : context->insert_type (constant.get_mappings (), unified);
765 446 : infered = unified;
766 446 : }
767 :
768 : void
769 6417 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
770 : {
771 6417 : if (impl_block.has_trait_ref ())
772 5362 : resolve_trait_impl_block (impl_block);
773 : else
774 1055 : resolve_impl_block (impl_block);
775 6416 : }
776 :
777 : void
778 1055 : TypeCheckItem::resolve_impl_block (HIR::ImplBlock &impl_block)
779 : {
780 1055 : auto binder_pin = context->push_clean_lifetime_resolver (true);
781 :
782 1055 : bool failed_flag = false;
783 1055 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
784 1055 : if (failed_flag)
785 : {
786 3 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
787 3 : return;
788 : }
789 1052 : std::vector<TyTy::SubstitutionParamMapping> substitutions
790 1052 : = std::move (result.first);
791 1052 : TyTy::RegionConstraints region_constraints = std::move (result.second);
792 :
793 1052 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
794 :
795 4271 : for (auto &impl_item : impl_block.get_impl_items ())
796 3219 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
797 1055 : }
798 :
799 : void
800 5362 : TypeCheckItem::resolve_trait_impl_block (HIR::ImplBlock &impl_block)
801 : {
802 5362 : auto binder_pin = context->push_clean_lifetime_resolver (true);
803 :
804 5362 : bool failed_flag = false;
805 5362 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
806 5361 : if (failed_flag)
807 : {
808 1 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
809 1 : return;
810 : }
811 5360 : std::vector<TyTy::SubstitutionParamMapping> substitutions
812 5360 : = std::move (result.first);
813 5360 : TyTy::RegionConstraints region_constraints = std::move (result.second);
814 :
815 5360 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
816 5360 : TraitReference *trait_reference = &TraitReference::error_node ();
817 5360 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
818 :
819 5360 : HIR::TypePath &ref = impl_block.get_trait_ref ();
820 5360 : trait_reference = TraitResolver::Resolve (ref);
821 5360 : if (trait_reference->is_error ())
822 3 : return;
823 :
824 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
825 : // for example
826 10714 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
827 5357 : impl_block.get_polarity ());
828 :
829 : // need to check that if this specified bound has super traits does this
830 : // Self implement them?
831 5357 : specified_bound.validate_type_implements_super_traits (
832 5357 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
833 :
834 5357 : std::map<DefId, AssocTypeEntry> assoc_types_by_trait_item;
835 5357 : std::vector<const TraitItemReference *> trait_item_refs;
836 5357 : ResolveImplTraitAssociatedTypes (context, impl_block, specified_bound, self,
837 : substitutions, assoc_types_by_trait_item,
838 : trait_item_refs);
839 :
840 5357 : ImplTraitContextFrame frame{trait_reference, self,
841 5357 : std::move (assoc_types_by_trait_item)};
842 5357 : ImplTraitFrameGuard guard (frame);
843 11557 : for (auto &impl_item : impl_block.get_impl_items ())
844 : {
845 6200 : bool is_type_alias = impl_item->get_impl_item_type ()
846 6200 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
847 6200 : if (is_type_alias)
848 1430 : continue;
849 :
850 4770 : auto trait_item_ref
851 4770 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
852 4770 : specified_bound, substitutions);
853 4770 : if (!trait_item_ref.is_error ())
854 4765 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
855 4770 : }
856 :
857 5357 : validate_trait_impl_block (specified_bound, trait_item_refs, trait_reference,
858 : impl_block, self, substitutions);
859 :
860 5357 : AssociatedImplTrait associated (trait_reference, specified_bound, &impl_block,
861 5357 : self, frame);
862 5357 : context->insert_associated_trait_impl (
863 5357 : impl_block.get_mappings ().get_hirid (), std::move (associated));
864 5357 : context->insert_associated_impl_mapping (
865 5357 : trait_reference->get_mappings ().get_hirid (), self,
866 5357 : impl_block.get_mappings ().get_hirid ());
867 10721 : }
868 :
869 : void
870 6784 : TypeCheckItem::ResolveImplTraitAssociatedTypes (
871 : TypeCheckContext *context, HIR::ImplBlock &impl_block,
872 : TyTy::TypeBoundPredicate &specified_bound, TyTy::BaseType *self,
873 : std::vector<TyTy::SubstitutionParamMapping> &substitutions,
874 : std::map<DefId, AssocTypeEntry> &assoc_types_by_trait_item,
875 : std::vector<const TraitItemReference *> &trait_item_refs)
876 : {
877 16778 : for (auto &impl_item : impl_block.get_impl_items ())
878 : {
879 9994 : bool is_type_alias = impl_item->get_impl_item_type ()
880 9994 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
881 9994 : if (!is_type_alias)
882 7803 : continue;
883 :
884 2191 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 1");
885 2191 : self->debug ();
886 2191 : auto trait_item_ref
887 2191 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
888 2191 : specified_bound, substitutions);
889 2191 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 2");
890 2191 : if (!trait_item_ref.is_error ())
891 : {
892 2191 : const TraitItemReference *tiref = trait_item_ref.get_raw_item ();
893 2191 : trait_item_refs.push_back (tiref);
894 :
895 2191 : DefId impl_item_defid = impl_item->get_impl_mappings ().get_defid ();
896 2191 : DefId trait_item_defid = tiref->get_mappings ().get_defid ();
897 2191 : TyTy::BaseType *impl_item_ty;
898 :
899 2191 : bool ok = context->lookup_type (
900 2191 : impl_item->get_impl_mappings ().get_hirid (), &impl_item_ty);
901 2191 : rust_assert (ok);
902 :
903 2191 : AssocTypeEntry entry
904 2191 : = {trait_item_defid, impl_item_defid, impl_item_ty};
905 2191 : assoc_types_by_trait_item[trait_item_defid] = std::move (entry);
906 : }
907 2191 : }
908 6784 : }
909 :
910 : TyTy::BaseType *
911 1 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
912 : HIR::ImplItem &item)
913 : {
914 1 : bool failed_flag = false;
915 1 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
916 1 : if (failed_flag)
917 : {
918 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
919 : }
920 :
921 0 : std::vector<TyTy::SubstitutionParamMapping> substitutions
922 0 : = std::move (result.first);
923 0 : TyTy::RegionConstraints region_constraints = std::move (result.second);
924 :
925 0 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
926 :
927 0 : return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
928 1 : }
929 :
930 : TyTy::FnType *
931 7069 : TypeCheckItem::resolve_function_signature (HIR::Function &function)
932 : {
933 7069 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
934 7069 : if (function.has_generics ())
935 688 : resolve_generic_params (HIR::Item::ItemKind::Function,
936 : function.get_locus (),
937 688 : function.get_generic_params (), substitutions);
938 :
939 7069 : TyTy::RegionConstraints region_constraints;
940 7069 : ResolveWhereClauseItem::Resolve (function.get_where_clause (),
941 : region_constraints);
942 :
943 7069 : TyTy::BaseType *ret_type = nullptr;
944 7069 : if (!function.has_function_return_type ())
945 3514 : ret_type = TyTy::TupleType::get_unit_type ();
946 : else
947 : {
948 3555 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
949 3555 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
950 : return nullptr;
951 :
952 3551 : ret_type = resolved->clone ();
953 3551 : ret_type->set_ref (
954 3551 : function.get_return_type ().get_mappings ().get_hirid ());
955 : }
956 :
957 7065 : std::vector<TyTy::FnParam> params;
958 9319 : for (auto ¶m : function.get_function_params ())
959 : {
960 : // get the name as well required for later on
961 2254 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
962 2254 : context->insert_type (param.get_mappings (), param_tyty);
963 2254 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
964 2254 : params.emplace_back (param.get_param_name ().clone_pattern (),
965 : param_tyty);
966 : }
967 :
968 7065 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
969 :
970 7065 : CanonicalPath path
971 7065 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
972 7065 : Resolver2_0::Namespace::Values);
973 :
974 7065 : RustIdent ident{path, function.get_locus ()};
975 :
976 7065 : auto fn_type = new TyTy::FnType (
977 7065 : function.get_mappings ().get_hirid (),
978 7065 : function.get_mappings ().get_defid (),
979 7065 : function.get_function_name ().as_string (), ident,
980 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
981 : std::move (substitutions),
982 14130 : TyTy::SubstitutionArgumentMappings::empty (
983 7065 : context->get_lifetime_resolver ().get_num_bound_regions ()),
984 28260 : region_constraints);
985 :
986 7065 : context->insert_type (function.get_mappings (), fn_type);
987 :
988 7065 : return fn_type;
989 14134 : }
990 :
991 : void
992 7069 : TypeCheckItem::visit (HIR::Function &function)
993 : {
994 7069 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
995 :
996 7069 : TyTy::BaseType *resolved = nullptr;
997 7069 : TyTy::FnType *resolved_fn_type = nullptr;
998 7069 : if (context->lookup_type (function.get_mappings ().get_hirid (), &resolved))
999 : {
1000 180 : if (resolved->get_kind () != TyTy::TypeKind::FNDEF)
1001 : return;
1002 180 : resolved_fn_type = static_cast<TyTy::FnType *> (resolved);
1003 : }
1004 : else
1005 6889 : resolved_fn_type = resolve_function_signature (function);
1006 :
1007 7069 : if (resolved_fn_type == nullptr)
1008 : return;
1009 :
1010 : // Mark the body as claimed before resolving it. Recursive queries from the
1011 : // body must reuse the cached signature rather than re-entering this body.
1012 7065 : context->clear_function_body_pending (resolved_fn_type->get_id ());
1013 :
1014 : // need to get the return type from this
1015 7065 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
1016 7065 : context->push_return_type (TypeCheckContextItem (&function),
1017 : expected_ret_tyty);
1018 :
1019 7065 : context->switch_to_fn_body ();
1020 7065 : auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
1021 :
1022 : // emit check for
1023 : // error[E0121]: the type placeholder `_` is not allowed within types on item
1024 7065 : const auto placeholder = expected_ret_tyty->contains_infer ();
1025 7065 : if (placeholder != nullptr && function.has_return_type ())
1026 : {
1027 : // FIXME
1028 : // this will be a great place for the Default Hir Visitor we want to
1029 : // grab the locations of the placeholders (HIR::InferredType) their
1030 : // location, for now maybe we can use their hirid to lookup the location
1031 3 : location_t placeholder_locus
1032 3 : = mappings.lookup_location (placeholder->get_ref ());
1033 3 : location_t type_locus = function.get_return_type ().get_locus ();
1034 3 : rich_location r (line_table, placeholder_locus);
1035 :
1036 3 : bool have_expected_type
1037 6 : = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
1038 3 : if (!have_expected_type)
1039 : {
1040 0 : r.add_range (type_locus);
1041 : }
1042 : else
1043 : {
1044 3 : std::string fixit
1045 3 : = "replace with the correct type " + block_expr_ty->get_name ();
1046 3 : r.add_fixit_replace (type_locus, fixit.c_str ());
1047 3 : }
1048 :
1049 3 : rust_error_at (r, ErrorCode::E0121,
1050 : "the type placeholder %<_%> is not allowed within types "
1051 : "on item signatures");
1052 3 : }
1053 :
1054 7065 : location_t fn_return_locus = function.has_function_return_type ()
1055 7065 : ? function.get_return_type ().get_locus ()
1056 3514 : : function.get_locus ();
1057 14130 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
1058 7065 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
1059 7065 : TyTy::TyWithLocation (block_expr_ty),
1060 7065 : function.get_definition ().get_locus ());
1061 :
1062 7065 : context->pop_return_type ();
1063 :
1064 7065 : infered = resolved_fn_type;
1065 7069 : }
1066 :
1067 : void
1068 1257 : TypeCheckItem::visit (HIR::Module &module)
1069 : {
1070 5443 : for (auto &item : module.get_items ())
1071 4186 : TypeCheckItem::Resolve (*item);
1072 1257 : }
1073 :
1074 : void
1075 4229 : TypeCheckItem::visit (HIR::Trait &trait)
1076 : {
1077 4229 : infered = resolve_trait (trait, true);
1078 4229 : }
1079 :
1080 : TyTy::BaseType *
1081 4638 : TypeCheckItem::resolve_trait (HIR::Trait &trait, bool resolve_bodies)
1082 : {
1083 4638 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
1084 :
1085 4638 : if (trait.has_type_param_bounds ())
1086 : {
1087 1733 : for (auto &tp_bound : trait.get_type_param_bounds ())
1088 : {
1089 942 : if (tp_bound.get ()->get_bound_type ()
1090 : == HIR::TypeParamBound::BoundType::TRAITBOUND)
1091 : {
1092 942 : HIR::TraitBound &tb
1093 942 : = static_cast<HIR::TraitBound &> (*tp_bound.get ());
1094 942 : if (tb.get_polarity () == BoundPolarity::AntiBound)
1095 : {
1096 1 : rust_error_at (tb.get_locus (),
1097 : "%<?Trait%> is not permitted in supertraits");
1098 : }
1099 : }
1100 : }
1101 : }
1102 :
1103 4638 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
1104 4638 : if (trait_ref->is_error ())
1105 : {
1106 7 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
1107 7 : return infered;
1108 : }
1109 :
1110 4631 : if (resolve_bodies)
1111 4223 : trait_ref->resolve_default_function_bodies ();
1112 :
1113 4631 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
1114 4631 : return new TyTy::DynamicObjectType (
1115 4631 : trait.get_mappings ().get_hirid (), ident,
1116 : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
1117 9262 : trait.get_locus ())});
1118 4638 : }
1119 :
1120 : void
1121 1706 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
1122 : {
1123 4392 : for (auto &item : extern_block.get_extern_items ())
1124 : {
1125 2686 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
1126 : }
1127 1706 : }
1128 :
1129 : void
1130 0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
1131 : {
1132 0 : if (extern_crate.references_self ())
1133 : return;
1134 :
1135 0 : auto &crate_mappings = Analysis::Mappings::get ().crate;
1136 0 : CrateNum num
1137 0 : = crate_mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
1138 0 : .value ();
1139 0 : HIR::Crate &crate = mappings.get_hir_crate (num);
1140 :
1141 0 : CrateNum saved_crate_num = crate_mappings.get_current_crate ();
1142 0 : crate_mappings.set_current_crate (num);
1143 0 : for (auto &item : crate.get_items ())
1144 0 : TypeCheckItem::Resolve (*item);
1145 0 : crate_mappings.set_current_crate (saved_crate_num);
1146 : }
1147 :
1148 : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
1149 35040 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
1150 : bool &failure_flag)
1151 : {
1152 35040 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
1153 35040 : if (impl_block.has_generics ())
1154 4864 : resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
1155 4864 : impl_block.get_generic_params (), substitutions);
1156 :
1157 35040 : TyTy::RegionConstraints region_constraints;
1158 35040 : ResolveWhereClauseItem::Resolve (impl_block.get_where_clause (),
1159 : region_constraints);
1160 :
1161 35040 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
1162 35040 : TraitReference *trait_reference = &TraitReference::error_node ();
1163 35040 : if (impl_block.has_trait_ref ())
1164 : {
1165 23452 : auto &ref = impl_block.get_trait_ref ();
1166 23452 : trait_reference = TraitResolver::Resolve (ref);
1167 23452 : if (!trait_reference->is_error ())
1168 : {
1169 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
1170 : // for example
1171 23449 : specified_bound
1172 46897 : = get_predicate_from_bound (ref, impl_block.get_type (),
1173 23448 : impl_block.get_polarity ());
1174 : }
1175 : }
1176 :
1177 35039 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
1178 35039 : if (self->is<TyTy::ErrorType> ())
1179 : {
1180 : // we cannot check for unconstrained type arguments when the Self type is
1181 : // not resolved it will just add extra errors that dont help as well as
1182 : // the case where this could just be a recursive type query that should
1183 : // fail and will work later on anyway
1184 1 : return {substitutions, region_constraints};
1185 : }
1186 :
1187 : // inherit the bounds
1188 35038 : if (!specified_bound.is_error ())
1189 23445 : self->inherit_bound (specified_bound);
1190 :
1191 : // check for any unconstrained type-params
1192 35038 : const TyTy::SubstitutionArgumentMappings trait_constraints
1193 35038 : = specified_bound.get_substitution_arguments ();
1194 35038 : const TyTy::SubstitutionArgumentMappings impl_constraints
1195 35038 : = GetUsedSubstArgs::From (self);
1196 :
1197 35038 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
1198 : impl_constraints, self);
1199 :
1200 35038 : return {substitutions, region_constraints};
1201 70078 : }
1202 :
1203 : TyTy::BaseType *
1204 32982 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
1205 : {
1206 32982 : return TypeCheckType::Resolve (impl_block.get_type ());
1207 : }
1208 :
1209 : bool
1210 14 : TypeCheckItem::validate_repr_simd (
1211 : const std::vector<TyTy::StructFieldType *> &fields, location_t locus)
1212 : {
1213 14 : if (fields.empty ())
1214 : {
1215 0 : rust_error_at (locus, ErrorCode::E0075, "SIMD vector cannot be empty");
1216 0 : return false;
1217 : }
1218 :
1219 : // in 1.49, repr simd assumes all fields are same type with its size
1220 : // being power-of-two.
1221 : //
1222 : // TODO update this typecheck to make repr simd take in a single field
1223 : // of an array instead when we move past 1.49. Relevant Rust github
1224 : // issues/PRs:
1225 : // - https://github.com/rust-lang/compiler-team/issues/621
1226 : // - https://github.com/rust-lang/rust/pull/78863 (implemented
1227 : // for 1.50.0)
1228 :
1229 14 : TyTy::BaseType *first_field_ty = fields.at (0)->get_field_type ();
1230 14 : TyTy::TypeKind ty_kind = first_field_ty->get_kind ();
1231 14 : bool fields_are_same_type = true;
1232 :
1233 14 : switch (ty_kind)
1234 : {
1235 4 : case TyTy::TypeKind::INT:
1236 4 : {
1237 4 : auto int_ty = static_cast<TyTy::IntType *> (first_field_ty);
1238 4 : auto int_kind = int_ty->get_int_kind ();
1239 22 : for (const auto field : fields)
1240 : {
1241 18 : if (field->get_field_type ()->get_kind () != ty_kind)
1242 : {
1243 : fields_are_same_type = false;
1244 : break;
1245 : }
1246 18 : auto field_int_ty
1247 18 : = static_cast<TyTy::IntType *> (field->get_field_type ());
1248 18 : if (field_int_ty->get_int_kind () != int_kind)
1249 : {
1250 : fields_are_same_type = false;
1251 : break;
1252 : }
1253 : }
1254 : break;
1255 : }
1256 1 : case TyTy::TypeKind::UINT:
1257 1 : {
1258 1 : auto uint_ty = static_cast<TyTy::UintType *> (first_field_ty);
1259 1 : auto uint_kind = uint_ty->get_uint_kind ();
1260 5 : for (const auto field : fields)
1261 : {
1262 4 : if (field->get_field_type ()->get_kind () != ty_kind)
1263 : {
1264 : fields_are_same_type = false;
1265 : break;
1266 : }
1267 4 : auto field_uint_ty
1268 4 : = static_cast<TyTy::UintType *> (field->get_field_type ());
1269 4 : if (field_uint_ty->get_uint_kind () != uint_kind)
1270 : {
1271 : fields_are_same_type = false;
1272 : break;
1273 : }
1274 : }
1275 : break;
1276 : }
1277 8 : case TyTy::TypeKind::FLOAT:
1278 8 : {
1279 8 : auto float_ty = static_cast<TyTy::FloatType *> (first_field_ty);
1280 8 : auto float_kind = float_ty->get_float_kind ();
1281 54 : for (const auto field : fields)
1282 : {
1283 47 : if (field->get_field_type ()->get_kind () != ty_kind)
1284 : {
1285 : fields_are_same_type = false;
1286 : break;
1287 : }
1288 46 : auto field_float_ty
1289 46 : = static_cast<TyTy::FloatType *> (field->get_field_type ());
1290 46 : if (field_float_ty->get_float_kind () != float_kind)
1291 : {
1292 : fields_are_same_type = false;
1293 : break;
1294 : }
1295 : }
1296 : break;
1297 : }
1298 1 : default:
1299 1 : rust_error_at (locus, ErrorCode::E0077,
1300 : "SIMD vector element type should be a primitive scalar");
1301 1 : return false;
1302 : }
1303 :
1304 13 : if (!fields_are_same_type)
1305 : {
1306 1 : rust_error_at (locus, "SIMD struct fields should be of the same type");
1307 1 : return false;
1308 : }
1309 :
1310 : // check whether field count is power of 2
1311 12 : size_t field_count = fields.size ();
1312 12 : if ((field_count & (field_count - 1)) != 0)
1313 : {
1314 1 : rust_error_at (locus, "Size of SIMD struct must be a power of 2");
1315 1 : return false;
1316 : }
1317 : return true;
1318 : }
1319 :
1320 : } // namespace Resolver
1321 : } // namespace Rust
|