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 :
40 : namespace Rust {
41 : namespace Resolver {
42 :
43 61360 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
44 :
45 : TyTy::BaseType *
46 28245 : TypeCheckItem::Resolve (HIR::Item &item)
47 : {
48 : // is it already resolved?
49 28245 : auto context = TypeCheckContext::get ();
50 28245 : TyTy::BaseType *resolved = nullptr;
51 28245 : bool already_resolved
52 28245 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
53 28245 : if (already_resolved)
54 4911 : return resolved;
55 :
56 23334 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
57 23334 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
58 :
59 23334 : TypeCheckItem resolver;
60 23334 : vis_item.accept_vis (resolver);
61 23334 : return resolver.infered;
62 23334 : }
63 :
64 : TyTy::BaseType *
65 2991 : TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
66 : {
67 2991 : TypeCheckItem resolver;
68 2991 : return resolver.resolve_impl_item (impl_block, item);
69 2991 : }
70 :
71 : TyTy::BaseType *
72 29541 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
73 : {
74 29541 : TypeCheckItem resolver;
75 :
76 29541 : bool failed_flag = false;
77 29541 : auto result
78 29541 : = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
79 29541 : if (failed_flag)
80 : {
81 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
82 : }
83 29540 : std::vector<TyTy::SubstitutionParamMapping> substitutions
84 29540 : = std::move (result.first);
85 29540 : TyTy::RegionConstraints region_constraints = std::move (result.second);
86 :
87 29540 : return resolver.resolve_impl_block_self (impl_block);
88 29541 : }
89 :
90 : TyTy::BaseType *
91 3015 : TypeCheckItem::ResolveImplBlockSelfWithInference (
92 : HIR::ImplBlock &impl, location_t locus,
93 : TyTy::SubstitutionArgumentMappings *infer_arguments)
94 : {
95 3015 : TypeCheckItem resolver;
96 :
97 3015 : bool failed_flag = false;
98 3015 : auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
99 3015 : if (failed_flag)
100 : {
101 1 : return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
102 : }
103 3014 : std::vector<TyTy::SubstitutionParamMapping> substitutions
104 3014 : = std::move (result.first);
105 3014 : TyTy::RegionConstraints region_constraints = std::move (result.second);
106 :
107 : // now that we have the param mappings we need to query the self type
108 3014 : TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
109 :
110 : // nothing to do
111 3014 : if (substitutions.empty () || self->is_concrete ())
112 : return self;
113 :
114 : // generate inference variables for the subst-param-mappings
115 729 : std::vector<TyTy::SubstitutionArg> args;
116 1483 : for (auto &p : substitutions)
117 : {
118 754 : auto param = p.get_param_ty ();
119 754 : if (!p.needs_substitution ())
120 : {
121 0 : auto resolved = param->destructure ();
122 0 : args.emplace_back (&p, resolved);
123 :
124 0 : continue;
125 0 : }
126 :
127 754 : TyTy::BaseType *argument = nullptr;
128 754 : if (param->get_kind () == TyTy::TypeKind::CONST)
129 : {
130 28 : auto i = TyTy::TyVar::get_implicit_const_infer_var (locus);
131 28 : argument = i.get_tyty ();
132 : }
133 : else
134 : {
135 726 : auto i = TyTy::TyVar::get_implicit_infer_var (locus);
136 726 : argument = i.get_tyty ();
137 : }
138 754 : args.emplace_back (&p, argument);
139 : }
140 :
141 : // create argument mappings
142 1458 : *infer_arguments = TyTy::SubstitutionArgumentMappings (
143 : std::move (args), {},
144 729 : TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
145 : infer_arguments),
146 1458 : locus);
147 :
148 729 : TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
149 :
150 : // we only need to apply to the bounds manually on types which dont bind
151 : // generics
152 729 : if (!infer->has_substitutions_defined ())
153 : {
154 629 : for (auto &bound : infer->get_specified_bounds ())
155 161 : bound.handle_substitions (*infer_arguments);
156 : }
157 :
158 729 : return infer;
159 3744 : }
160 :
161 : std::vector<TyTy::SubstitutionParamMapping>
162 2479 : TypeCheckItem::ResolveImplBlockSubstitutions (HIR::ImplBlock &impl_block,
163 : bool &failure_flag)
164 : {
165 2479 : TypeCheckItem resolver;
166 2479 : auto result
167 2479 : = resolver.resolve_impl_block_substitutions (impl_block, failure_flag);
168 2479 : return std::move (result.first);
169 2479 : }
170 :
171 : void
172 4728 : TypeCheckItem::validate_trait_impl_block (
173 : const TyTy::TypeBoundPredicate &specified_bound,
174 : std::vector<const TraitItemReference *> trait_item_refs,
175 : TraitReference *trait_reference, HIR::ImplBlock &impl_block,
176 : TyTy::BaseType *self,
177 : std::vector<TyTy::SubstitutionParamMapping> &substitutions)
178 : {
179 4728 : bool impl_block_missing_trait_items
180 4728 : = !specified_bound.is_error ()
181 4728 : && trait_reference->size () != trait_item_refs.size ();
182 1609 : if (impl_block_missing_trait_items
183 1609 : && impl_block.get_polarity () == BoundPolarity::RegularBound)
184 : {
185 : // filter the missing impl_items
186 1607 : std::vector<std::reference_wrapper<const TraitItemReference>>
187 1607 : missing_trait_items;
188 5096 : for (const auto &trait_item_ref : trait_reference->get_trait_items ())
189 : {
190 3489 : bool found = false;
191 5367 : for (auto implemented_trait_item : trait_item_refs)
192 : {
193 3313 : std::string trait_item_name = trait_item_ref.get_identifier ();
194 3313 : std::string impl_item_name
195 3313 : = implemented_trait_item->get_identifier ();
196 3313 : found = trait_item_name == impl_item_name;
197 3313 : if (found)
198 : break;
199 3313 : }
200 :
201 3489 : bool is_required_trait_item = !trait_item_ref.is_optional ();
202 3489 : if (!found && is_required_trait_item)
203 7 : missing_trait_items.emplace_back (trait_item_ref);
204 : }
205 :
206 1607 : if (!missing_trait_items.empty ())
207 : {
208 5 : std::string missing_items_buf;
209 5 : rich_location r (line_table, impl_block.get_locus ());
210 17 : for (size_t i = 0; i < missing_trait_items.size (); i++)
211 : {
212 7 : bool has_more = (i + 1) < missing_trait_items.size ();
213 7 : const TraitItemReference &missing_trait_item
214 7 : = missing_trait_items.at (i);
215 7 : missing_items_buf += missing_trait_item.get_identifier ()
216 21 : + (has_more ? ", " : "");
217 7 : r.add_range (missing_trait_item.get_locus ());
218 : }
219 :
220 5 : rust_error_at (r, ErrorCode::E0046,
221 : "missing %s in implementation of trait %qs",
222 : missing_items_buf.c_str (),
223 5 : trait_reference->get_name ().c_str ());
224 5 : }
225 1607 : }
226 4728 : }
227 :
228 : void
229 71 : TypeCheckItem::visit (HIR::TypeAlias &alias)
230 : {
231 71 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
232 :
233 71 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
234 71 : if (alias.has_generics ())
235 9 : resolve_generic_params (HIR::Item::ItemKind::TypeAlias, alias.get_locus (),
236 9 : alias.get_generic_params (), substitutions);
237 :
238 71 : TyTy::BaseType *actual_type
239 71 : = TypeCheckType::Resolve (alias.get_type_aliased ());
240 :
241 71 : context->insert_type (alias.get_mappings (), actual_type);
242 :
243 71 : TyTy::RegionConstraints region_constraints;
244 71 : for (auto &where_clause_item : alias.get_where_clause ().get_items ())
245 : {
246 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
247 : }
248 71 : infered = actual_type;
249 71 : }
250 :
251 : void
252 963 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
253 : {
254 963 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
255 :
256 963 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
257 963 : if (struct_decl.has_generics ())
258 298 : resolve_generic_params (HIR::Item::ItemKind::Struct,
259 : struct_decl.get_locus (),
260 298 : struct_decl.get_generic_params (), substitutions);
261 :
262 963 : TyTy::RegionConstraints region_constraints;
263 963 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
264 : {
265 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
266 : }
267 :
268 963 : std::vector<TyTy::StructFieldType *> fields;
269 963 : size_t idx = 0;
270 2593 : for (auto &field : struct_decl.get_fields ())
271 : {
272 1630 : TyTy::BaseType *field_type
273 1630 : = TypeCheckType::Resolve (field.get_field_type ());
274 1630 : auto *ty_field
275 3260 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
276 1630 : std::to_string (idx), field_type,
277 1630 : field.get_locus ());
278 1630 : fields.push_back (ty_field);
279 1630 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
280 1630 : idx++;
281 : }
282 :
283 : // get the path
284 :
285 963 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
286 :
287 963 : CanonicalPath path
288 963 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
289 963 : Resolver2_0::Namespace::Types);
290 :
291 963 : RustIdent ident{path, struct_decl.get_locus ()};
292 :
293 : // its a single variant ADT
294 963 : std::vector<TyTy::VariantDef *> variants;
295 963 : variants.push_back (
296 963 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
297 963 : struct_decl.get_mappings ().get_defid (),
298 963 : struct_decl.get_identifier ().as_string (), ident,
299 1926 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
300 2889 : std::move (fields)));
301 :
302 : // Process #[repr(X)] attribute, if any
303 963 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
304 963 : TyTy::ADTType::ReprOptions repr
305 963 : = parse_repr_options (attrs, struct_decl.get_locus ());
306 :
307 963 : auto *type = new TyTy::ADTType (
308 963 : struct_decl.get_mappings ().get_defid (),
309 963 : struct_decl.get_mappings ().get_hirid (),
310 963 : struct_decl.get_mappings ().get_hirid (),
311 963 : struct_decl.get_identifier ().as_string (), ident,
312 : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
313 : std::move (substitutions), repr,
314 1926 : TyTy::SubstitutionArgumentMappings::empty (
315 963 : context->get_lifetime_resolver ().get_num_bound_regions ()),
316 3852 : region_constraints);
317 :
318 963 : context->insert_type (struct_decl.get_mappings (), type);
319 963 : infered = type;
320 :
321 963 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
322 1926 : }
323 :
324 : void
325 1600 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
326 : {
327 1600 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
328 1600 : auto &mappings = Analysis::Mappings::get ();
329 :
330 1600 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
331 1600 : if (struct_decl.has_generics ())
332 492 : resolve_generic_params (HIR::Item::ItemKind::Struct,
333 : struct_decl.get_locus (),
334 492 : struct_decl.get_generic_params (), substitutions);
335 :
336 1600 : TyTy::RegionConstraints region_constraints;
337 1604 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
338 : {
339 4 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
340 : }
341 :
342 : // Process #[repr(X)] attribute, if any
343 1600 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
344 1600 : TyTy::ADTType::ReprOptions repr
345 1600 : = parse_repr_options (attrs, struct_decl.get_locus ());
346 :
347 1600 : std::vector<TyTy::StructFieldType *> fields;
348 3483 : for (auto &field : struct_decl.get_fields ())
349 : {
350 1888 : TyTy::BaseType *field_type
351 1888 : = TypeCheckType::Resolve (field.get_field_type ());
352 1888 : auto infer_type = field_type->contains_infer ();
353 1888 : if (infer_type)
354 : {
355 5 : rust_error_at (mappings.lookup_location (infer_type->get_ref ()),
356 : "the placeholder %<_%> is not allowed within types on "
357 : "item signatures for structs");
358 5 : return;
359 : }
360 1883 : auto *ty_field
361 1883 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
362 1883 : field.get_field_name ().as_string (),
363 3766 : field_type, field.get_locus ());
364 1883 : fields.push_back (ty_field);
365 1883 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
366 : }
367 :
368 1595 : if (repr.repr_kind == TyTy::ADTType::ReprKind::TRANSPARENT)
369 : {
370 26 : size_t num_non_zst = 0;
371 55 : for (auto &field : fields)
372 : {
373 29 : if (!field->get_field_type ()->is_zero_sized ())
374 26 : num_non_zst++;
375 : }
376 26 : if (num_non_zst > 1)
377 : {
378 1 : rust_error_at (struct_decl.get_locus (), ErrorCode::E0690,
379 : "transparent struct needs at most one field with "
380 : "non-trivial size or alignment, but has %lu",
381 : (unsigned long) num_non_zst);
382 1 : return;
383 : }
384 : }
385 :
386 1594 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
387 :
388 1594 : CanonicalPath path
389 1594 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
390 1594 : Resolver2_0::Namespace::Types);
391 :
392 1594 : RustIdent ident{path, struct_decl.get_locus ()};
393 :
394 : // its a single variant ADT
395 1594 : auto variant_type = struct_decl.is_unit_struct ()
396 1594 : ? TyTy::VariantDef::VariantType::UNIT
397 1022 : : TyTy::VariantDef::VariantType::STRUCT;
398 1594 : std::vector<TyTy::VariantDef *> variants;
399 1594 : variants.push_back (
400 1594 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
401 1594 : struct_decl.get_mappings ().get_defid (),
402 1594 : struct_decl.get_identifier ().as_string (), ident,
403 4782 : variant_type, tl::nullopt, std::move (fields)));
404 :
405 1594 : auto *type = new TyTy::ADTType (
406 1594 : struct_decl.get_mappings ().get_defid (),
407 1594 : struct_decl.get_mappings ().get_hirid (),
408 1594 : struct_decl.get_mappings ().get_hirid (),
409 1594 : struct_decl.get_identifier ().as_string (), ident,
410 : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
411 : std::move (substitutions), repr,
412 3188 : TyTy::SubstitutionArgumentMappings::empty (
413 1594 : context->get_lifetime_resolver ().get_num_bound_regions ()),
414 6376 : region_constraints);
415 :
416 1594 : context->insert_type (struct_decl.get_mappings (), type);
417 1594 : infered = type;
418 :
419 1594 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
420 3200 : }
421 :
422 : void
423 537 : TypeCheckItem::visit (HIR::Enum &enum_decl)
424 : {
425 537 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
426 537 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
427 537 : if (enum_decl.has_generics ())
428 228 : resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
429 228 : enum_decl.get_generic_params (), substitutions);
430 :
431 : // Process #[repr(X)] attribute, if any
432 537 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
433 537 : TyTy::ADTType::ReprOptions repr
434 537 : = parse_repr_options (attrs, enum_decl.get_locus ());
435 :
436 537 : std::vector<TyTy::VariantDef *> variants;
437 537 : int64_t discriminant_value = 0;
438 1778 : for (auto &variant : enum_decl.get_variants ())
439 : {
440 1241 : TyTy::VariantDef *field_type
441 1241 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
442 1241 : if (field_type)
443 : {
444 1240 : discriminant_value++;
445 1240 : variants.push_back (field_type);
446 : }
447 : }
448 :
449 : // Check for zero-variant enum compatibility
450 537 : if (enum_decl.is_zero_variant ())
451 : {
452 11 : if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
453 11 : || repr.repr_kind == TyTy::ADTType::ReprKind::C)
454 : {
455 2 : rust_error_at (enum_decl.get_locus (),
456 : "unsupported representation for zero-variant enum");
457 2 : return;
458 : }
459 : }
460 :
461 535 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
462 :
463 : // get the path
464 535 : CanonicalPath canonical_path
465 535 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid (),
466 535 : Resolver2_0::Namespace::Types);
467 :
468 535 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
469 :
470 : // multi variant ADT
471 535 : auto *type
472 535 : = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
473 535 : enum_decl.get_mappings ().get_hirid (),
474 535 : enum_decl.get_mappings ().get_hirid (),
475 535 : enum_decl.get_identifier ().as_string (), ident,
476 : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
477 1605 : std::move (substitutions), repr);
478 :
479 535 : context->insert_type (enum_decl.get_mappings (), type);
480 535 : infered = type;
481 :
482 535 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
483 537 : }
484 :
485 : void
486 105 : TypeCheckItem::visit (HIR::Union &union_decl)
487 : {
488 105 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
489 105 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
490 105 : if (union_decl.has_generics ())
491 75 : resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
492 75 : union_decl.get_generic_params (), substitutions);
493 :
494 105 : TyTy::RegionConstraints region_constraints;
495 105 : for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
496 : {
497 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
498 : }
499 :
500 105 : std::vector<TyTy::StructFieldType *> fields;
501 409 : for (auto &variant : union_decl.get_variants ())
502 : {
503 304 : TyTy::BaseType *variant_type
504 304 : = TypeCheckType::Resolve (variant.get_field_type ());
505 304 : auto *ty_variant
506 304 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
507 304 : variant.get_field_name ().as_string (),
508 608 : variant_type, variant.get_locus ());
509 304 : fields.push_back (ty_variant);
510 304 : context->insert_type (variant.get_mappings (),
511 : ty_variant->get_field_type ());
512 : }
513 :
514 105 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
515 :
516 : // get the path
517 105 : CanonicalPath canonical_path
518 105 : = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid (),
519 105 : Resolver2_0::Namespace::Types);
520 :
521 105 : RustIdent ident{canonical_path, union_decl.get_locus ()};
522 :
523 : // there is only a single variant
524 105 : std::vector<TyTy::VariantDef *> variants;
525 105 : variants.push_back (
526 105 : new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
527 105 : union_decl.get_mappings ().get_defid (),
528 105 : union_decl.get_identifier ().as_string (), ident,
529 210 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
530 315 : std::move (fields)));
531 :
532 105 : auto *type
533 105 : = new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
534 105 : union_decl.get_mappings ().get_hirid (),
535 105 : union_decl.get_mappings ().get_hirid (),
536 105 : union_decl.get_identifier ().as_string (), ident,
537 : TyTy::ADTType::ADTKind::UNION, std::move (variants),
538 315 : std::move (substitutions));
539 :
540 105 : context->insert_type (union_decl.get_mappings (), type);
541 105 : infered = type;
542 :
543 105 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
544 210 : }
545 :
546 : void
547 54 : TypeCheckItem::visit (HIR::StaticItem &var)
548 : {
549 54 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
550 54 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
551 :
552 54 : TyTy::BaseType *unified
553 54 : = coercion_site (var.get_mappings ().get_hirid (),
554 54 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
555 : TyTy::TyWithLocation (expr_type,
556 54 : var.get_expr ().get_locus ()),
557 : var.get_locus ());
558 54 : context->insert_type (var.get_mappings (), unified);
559 54 : infered = unified;
560 54 : }
561 :
562 : void
563 416 : TypeCheckItem::visit (HIR::ConstantItem &constant)
564 : {
565 416 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
566 416 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
567 :
568 832 : TyTy::BaseType *unified = unify_site (
569 416 : constant.get_mappings ().get_hirid (),
570 416 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
571 416 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
572 : constant.get_locus ());
573 416 : context->insert_type (constant.get_mappings (), unified);
574 416 : infered = unified;
575 416 : }
576 :
577 : void
578 5710 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
579 : {
580 5710 : if (impl_block.has_trait_ref ())
581 4732 : resolve_trait_impl_block (impl_block);
582 : else
583 978 : resolve_impl_block (impl_block);
584 5710 : }
585 :
586 : void
587 978 : TypeCheckItem::resolve_impl_block (HIR::ImplBlock &impl_block)
588 : {
589 978 : auto binder_pin = context->push_clean_lifetime_resolver (true);
590 :
591 978 : bool failed_flag = false;
592 978 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
593 978 : if (failed_flag)
594 : {
595 3 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
596 3 : return;
597 : }
598 975 : std::vector<TyTy::SubstitutionParamMapping> substitutions
599 975 : = std::move (result.first);
600 975 : TyTy::RegionConstraints region_constraints = std::move (result.second);
601 :
602 975 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
603 :
604 3755 : for (auto &impl_item : impl_block.get_impl_items ())
605 2780 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
606 978 : }
607 :
608 : void
609 4732 : TypeCheckItem::resolve_trait_impl_block (HIR::ImplBlock &impl_block)
610 : {
611 4732 : auto binder_pin = context->push_clean_lifetime_resolver (true);
612 :
613 4732 : bool failed_flag = false;
614 4732 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
615 4732 : if (failed_flag)
616 : {
617 1 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
618 1 : return;
619 : }
620 4731 : std::vector<TyTy::SubstitutionParamMapping> substitutions
621 4731 : = std::move (result.first);
622 4731 : TyTy::RegionConstraints region_constraints = std::move (result.second);
623 :
624 4731 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
625 4731 : TraitReference *trait_reference = &TraitReference::error_node ();
626 4731 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
627 :
628 4731 : HIR::TypePath &ref = impl_block.get_trait_ref ();
629 4731 : trait_reference = TraitResolver::Resolve (ref);
630 4731 : if (trait_reference->is_error ())
631 3 : return;
632 :
633 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
634 : // for example
635 9456 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
636 4728 : impl_block.get_polarity ());
637 :
638 : // need to check that if this specified bound has super traits does this
639 : // Self implement them?
640 4728 : specified_bound.validate_type_implements_super_traits (
641 4728 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
642 :
643 4728 : std::map<DefId, AssocTypeEntry> assoc_types_by_trait_item;
644 4728 : std::vector<const TraitItemReference *> trait_item_refs;
645 4728 : ResolveImplTraitAssociatedTypes (context, impl_block, specified_bound, self,
646 : substitutions, assoc_types_by_trait_item,
647 : trait_item_refs);
648 :
649 4728 : ImplTraitContextFrame frame{trait_reference, self,
650 4728 : std::move (assoc_types_by_trait_item)};
651 4728 : ImplTraitFrameGuard guard (frame);
652 10151 : for (auto &impl_item : impl_block.get_impl_items ())
653 : {
654 5423 : bool is_type_alias = impl_item->get_impl_item_type ()
655 5423 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
656 5423 : if (is_type_alias)
657 1184 : continue;
658 :
659 4239 : auto trait_item_ref
660 4239 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
661 4239 : specified_bound, substitutions);
662 4239 : if (!trait_item_ref.is_error ())
663 4234 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
664 4239 : }
665 :
666 4728 : validate_trait_impl_block (specified_bound, trait_item_refs, trait_reference,
667 : impl_block, self, substitutions);
668 :
669 4728 : AssociatedImplTrait associated (trait_reference, specified_bound, &impl_block,
670 4728 : self, frame);
671 4728 : context->insert_associated_trait_impl (
672 4728 : impl_block.get_mappings ().get_hirid (), std::move (associated));
673 4728 : context->insert_associated_impl_mapping (
674 4728 : trait_reference->get_mappings ().get_hirid (), self,
675 4728 : impl_block.get_mappings ().get_hirid ());
676 9463 : }
677 :
678 : void
679 7207 : TypeCheckItem::ResolveImplTraitAssociatedTypes (
680 : TypeCheckContext *context, HIR::ImplBlock &impl_block,
681 : TyTy::TypeBoundPredicate &specified_bound, TyTy::BaseType *self,
682 : std::vector<TyTy::SubstitutionParamMapping> &substitutions,
683 : std::map<DefId, AssocTypeEntry> &assoc_types_by_trait_item,
684 : std::vector<const TraitItemReference *> &trait_item_refs)
685 : {
686 17898 : for (auto &impl_item : impl_block.get_impl_items ())
687 : {
688 10691 : bool is_type_alias = impl_item->get_impl_item_type ()
689 10691 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
690 10691 : if (!is_type_alias)
691 8838 : continue;
692 :
693 1853 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 1");
694 1853 : self->debug ();
695 1853 : auto trait_item_ref
696 1853 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
697 1853 : specified_bound, substitutions);
698 1853 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 2");
699 1853 : if (!trait_item_ref.is_error ())
700 : {
701 1853 : const TraitItemReference *tiref = trait_item_ref.get_raw_item ();
702 1853 : trait_item_refs.push_back (tiref);
703 :
704 1853 : DefId impl_item_defid = impl_item->get_impl_mappings ().get_defid ();
705 1853 : DefId trait_item_defid = tiref->get_mappings ().get_defid ();
706 1853 : TyTy::BaseType *impl_item_ty;
707 :
708 1853 : bool ok = context->lookup_type (
709 1853 : impl_item->get_impl_mappings ().get_hirid (), &impl_item_ty);
710 1853 : rust_assert (ok);
711 :
712 1853 : AssocTypeEntry entry
713 1853 : = {trait_item_defid, impl_item_defid, impl_item_ty};
714 1853 : assoc_types_by_trait_item[trait_item_defid] = std::move (entry);
715 : }
716 1853 : }
717 7207 : }
718 :
719 : TyTy::BaseType *
720 2991 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
721 : HIR::ImplItem &item)
722 : {
723 2991 : bool failed_flag = false;
724 2991 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
725 2991 : if (failed_flag)
726 : {
727 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
728 : }
729 :
730 2990 : std::vector<TyTy::SubstitutionParamMapping> substitutions
731 2990 : = std::move (result.first);
732 2990 : TyTy::RegionConstraints region_constraints = std::move (result.second);
733 :
734 2990 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
735 :
736 2990 : return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
737 2991 : }
738 :
739 : void
740 6725 : TypeCheckItem::visit (HIR::Function &function)
741 : {
742 6725 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
743 6725 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
744 6725 : if (function.has_generics ())
745 607 : resolve_generic_params (HIR::Item::ItemKind::Function,
746 : function.get_locus (),
747 607 : function.get_generic_params (), substitutions);
748 :
749 6725 : TyTy::RegionConstraints region_constraints;
750 6772 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
751 : {
752 47 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
753 : }
754 :
755 6725 : TyTy::BaseType *ret_type = nullptr;
756 6725 : if (!function.has_function_return_type ())
757 3376 : ret_type = TyTy::TupleType::get_unit_type ();
758 : else
759 : {
760 3349 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
761 3349 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
762 4 : return;
763 :
764 3345 : ret_type = resolved->clone ();
765 3345 : ret_type->set_ref (
766 3345 : function.get_return_type ().get_mappings ().get_hirid ());
767 : }
768 :
769 6721 : std::vector<TyTy::FnParam> params;
770 8711 : for (auto ¶m : function.get_function_params ())
771 : {
772 : // get the name as well required for later on
773 1990 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
774 1990 : context->insert_type (param.get_mappings (), param_tyty);
775 1990 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
776 1990 : params.emplace_back (param.get_param_name ().clone_pattern (),
777 : param_tyty);
778 : }
779 :
780 6721 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
781 :
782 6721 : CanonicalPath path
783 6721 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
784 6721 : Resolver2_0::Namespace::Values);
785 :
786 6721 : RustIdent ident{path, function.get_locus ()};
787 :
788 6721 : auto fn_type = new TyTy::FnType (
789 6721 : function.get_mappings ().get_hirid (),
790 6721 : function.get_mappings ().get_defid (),
791 6721 : function.get_function_name ().as_string (), ident,
792 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
793 : std::move (substitutions),
794 13442 : TyTy::SubstitutionArgumentMappings::empty (
795 6721 : context->get_lifetime_resolver ().get_num_bound_regions ()),
796 26884 : region_constraints);
797 :
798 6721 : context->insert_type (function.get_mappings (), fn_type);
799 :
800 : // need to get the return type from this
801 6721 : TyTy::FnType *resolved_fn_type = fn_type;
802 6721 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
803 6721 : context->push_return_type (TypeCheckContextItem (&function),
804 : expected_ret_tyty);
805 :
806 6721 : context->switch_to_fn_body ();
807 6721 : auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
808 :
809 : // emit check for
810 : // error[E0121]: the type placeholder `_` is not allowed within types on item
811 6721 : const auto placeholder = ret_type->contains_infer ();
812 6721 : if (placeholder != nullptr && function.has_return_type ())
813 : {
814 : // FIXME
815 : // this will be a great place for the Default Hir Visitor we want to
816 : // grab the locations of the placeholders (HIR::InferredType) their
817 : // location, for now maybe we can use their hirid to lookup the location
818 3 : location_t placeholder_locus
819 3 : = mappings.lookup_location (placeholder->get_ref ());
820 3 : location_t type_locus = function.get_return_type ().get_locus ();
821 3 : rich_location r (line_table, placeholder_locus);
822 :
823 3 : bool have_expected_type
824 6 : = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
825 3 : if (!have_expected_type)
826 : {
827 0 : r.add_range (type_locus);
828 : }
829 : else
830 : {
831 3 : std::string fixit
832 3 : = "replace with the correct type " + block_expr_ty->get_name ();
833 3 : r.add_fixit_replace (type_locus, fixit.c_str ());
834 3 : }
835 :
836 3 : rust_error_at (r, ErrorCode::E0121,
837 : "the type placeholder %<_%> is not allowed within types "
838 : "on item signatures");
839 3 : }
840 :
841 6721 : location_t fn_return_locus = function.has_function_return_type ()
842 6721 : ? function.get_return_type ().get_locus ()
843 3376 : : function.get_locus ();
844 13442 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
845 6721 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
846 6721 : TyTy::TyWithLocation (block_expr_ty),
847 6721 : function.get_definition ().get_locus ());
848 :
849 6721 : context->pop_return_type ();
850 :
851 6721 : infered = fn_type;
852 13446 : }
853 :
854 : void
855 1188 : TypeCheckItem::visit (HIR::Module &module)
856 : {
857 5020 : for (auto &item : module.get_items ())
858 3832 : TypeCheckItem::Resolve (*item);
859 1188 : }
860 :
861 : void
862 4309 : TypeCheckItem::visit (HIR::Trait &trait)
863 : {
864 4309 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
865 :
866 4309 : if (trait.has_type_param_bounds ())
867 : {
868 1639 : for (auto &tp_bound : trait.get_type_param_bounds ())
869 : {
870 894 : if (tp_bound.get ()->get_bound_type ()
871 : == HIR::TypeParamBound::BoundType::TRAITBOUND)
872 : {
873 894 : HIR::TraitBound &tb
874 894 : = static_cast<HIR::TraitBound &> (*tp_bound.get ());
875 894 : if (tb.get_polarity () == BoundPolarity::AntiBound)
876 : {
877 1 : rust_error_at (tb.get_locus (),
878 : "%<?Trait%> is not permitted in supertraits");
879 : }
880 : }
881 : }
882 : }
883 :
884 4309 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
885 4309 : if (trait_ref->is_error ())
886 : {
887 7 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
888 7 : return;
889 : }
890 :
891 4302 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
892 4302 : infered = new TyTy::DynamicObjectType (
893 4302 : trait.get_mappings ().get_hirid (), ident,
894 : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
895 12906 : trait.get_locus ())});
896 4309 : }
897 :
898 : void
899 1656 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
900 : {
901 4204 : for (auto &item : extern_block.get_extern_items ())
902 : {
903 2548 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
904 : }
905 1656 : }
906 :
907 : void
908 0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
909 : {
910 0 : if (extern_crate.references_self ())
911 : return;
912 :
913 0 : auto &mappings = Analysis::Mappings::get ();
914 0 : CrateNum num
915 0 : = mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
916 0 : .value ();
917 0 : HIR::Crate &crate = mappings.get_hir_crate (num);
918 :
919 0 : CrateNum saved_crate_num = mappings.get_current_crate ();
920 0 : mappings.set_current_crate (num);
921 0 : for (auto &item : crate.get_items ())
922 0 : TypeCheckItem::Resolve (*item);
923 0 : mappings.set_current_crate (saved_crate_num);
924 : }
925 :
926 : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
927 43736 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
928 : bool &failure_flag)
929 : {
930 43736 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
931 43736 : if (impl_block.has_generics ())
932 6205 : resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
933 6205 : impl_block.get_generic_params (), substitutions);
934 :
935 43736 : TyTy::RegionConstraints region_constraints;
936 44259 : for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
937 : {
938 523 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
939 : }
940 :
941 43736 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
942 43736 : TraitReference *trait_reference = &TraitReference::error_node ();
943 43736 : if (impl_block.has_trait_ref ())
944 : {
945 32838 : auto &ref = impl_block.get_trait_ref ();
946 32838 : trait_reference = TraitResolver::Resolve (ref);
947 32838 : if (!trait_reference->is_error ())
948 : {
949 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
950 : // for example
951 32834 : specified_bound
952 65668 : = get_predicate_from_bound (ref, impl_block.get_type (),
953 32834 : impl_block.get_polarity ());
954 : }
955 : }
956 :
957 43736 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
958 43736 : if (self->is<TyTy::ErrorType> ())
959 : {
960 : // we cannot check for unconstrained type arguments when the Self type is
961 : // not resolved it will just add extra errors that dont help as well as
962 : // the case where this could just be a recursive type query that should
963 : // fail and will work later on anyway
964 1 : return {substitutions, region_constraints};
965 : }
966 :
967 : // inherit the bounds
968 43735 : if (!specified_bound.is_error ())
969 65660 : self->inherit_bounds ({specified_bound});
970 :
971 : // check for any unconstrained type-params
972 43735 : const TyTy::SubstitutionArgumentMappings trait_constraints
973 43735 : = specified_bound.get_substitution_arguments ();
974 43735 : const TyTy::SubstitutionArgumentMappings impl_constraints
975 43735 : = GetUsedSubstArgs::From (self);
976 :
977 43735 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
978 : impl_constraints, self);
979 :
980 43735 : return {substitutions, region_constraints};
981 87472 : }
982 :
983 : TyTy::BaseType *
984 41250 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
985 : {
986 41250 : return TypeCheckType::Resolve (impl_block.get_type ());
987 : }
988 :
989 : } // namespace Resolver
990 : } // namespace Rust
|