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 61121 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
44 :
45 : TyTy::BaseType *
46 27971 : TypeCheckItem::Resolve (HIR::Item &item)
47 : {
48 : // is it already resolved?
49 27971 : auto context = TypeCheckContext::get ();
50 27971 : TyTy::BaseType *resolved = nullptr;
51 27971 : bool already_resolved
52 27971 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
53 27971 : if (already_resolved)
54 4880 : return resolved;
55 :
56 23091 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
57 23091 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
58 :
59 23091 : TypeCheckItem resolver;
60 23091 : vis_item.accept_vis (resolver);
61 23091 : return resolver.infered;
62 23091 : }
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 29547 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
73 : {
74 29547 : TypeCheckItem resolver;
75 :
76 29547 : bool failed_flag = false;
77 29547 : auto result
78 29547 : = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
79 29547 : if (failed_flag)
80 : {
81 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
82 : }
83 29546 : std::vector<TyTy::SubstitutionParamMapping> substitutions
84 29546 : = std::move (result.first);
85 29546 : TyTy::RegionConstraints region_constraints = std::move (result.second);
86 :
87 29546 : return resolver.resolve_impl_block_self (impl_block);
88 29547 : }
89 :
90 : TyTy::BaseType *
91 3013 : TypeCheckItem::ResolveImplBlockSelfWithInference (
92 : HIR::ImplBlock &impl, location_t locus,
93 : TyTy::SubstitutionArgumentMappings *infer_arguments)
94 : {
95 3013 : TypeCheckItem resolver;
96 :
97 3013 : bool failed_flag = false;
98 3013 : auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
99 3013 : if (failed_flag)
100 : {
101 1 : return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
102 : }
103 3012 : std::vector<TyTy::SubstitutionParamMapping> substitutions
104 3012 : = std::move (result.first);
105 3012 : 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 3012 : TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
109 :
110 : // nothing to do
111 3012 : if (substitutions.empty () || self->is_concrete ())
112 2284 : return self;
113 :
114 : // generate inference variables for the subst-param-mappings
115 728 : std::vector<TyTy::SubstitutionArg> args;
116 1481 : for (auto &p : substitutions)
117 : {
118 753 : auto param = p.get_param_ty ();
119 753 : 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 753 : TyTy::BaseType *argument = nullptr;
128 753 : 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 725 : auto i = TyTy::TyVar::get_implicit_infer_var (locus);
136 725 : argument = i.get_tyty ();
137 : }
138 753 : args.emplace_back (&p, argument);
139 : }
140 :
141 : // create argument mappings
142 1456 : *infer_arguments = TyTy::SubstitutionArgumentMappings (
143 : std::move (args), {},
144 728 : TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
145 : infer_arguments),
146 1456 : locus);
147 :
148 728 : 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 728 : if (!infer->has_substitutions_defined ())
153 : {
154 628 : for (auto &bound : infer->get_specified_bounds ())
155 161 : bound.handle_substitions (*infer_arguments);
156 : }
157 :
158 728 : return infer;
159 3741 : }
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 4719 : 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 4719 : bool impl_block_missing_trait_items
180 4719 : = !specified_bound.is_error ()
181 4719 : && 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 12 : 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 4719 : }
227 :
228 : void
229 70 : TypeCheckItem::visit (HIR::TypeAlias &alias)
230 : {
231 70 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
232 :
233 70 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
234 70 : 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 70 : TyTy::BaseType *actual_type
239 70 : = TypeCheckType::Resolve (alias.get_type_aliased ());
240 :
241 70 : context->insert_type (alias.get_mappings (), actual_type);
242 :
243 70 : TyTy::RegionConstraints region_constraints;
244 70 : for (auto &where_clause_item : alias.get_where_clause ().get_items ())
245 : {
246 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
247 : }
248 70 : infered = actual_type;
249 70 : }
250 :
251 : void
252 960 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
253 : {
254 960 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
255 :
256 960 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
257 960 : if (struct_decl.has_generics ())
258 297 : resolve_generic_params (HIR::Item::ItemKind::Struct,
259 : struct_decl.get_locus (),
260 297 : struct_decl.get_generic_params (), substitutions);
261 :
262 960 : TyTy::RegionConstraints region_constraints;
263 960 : 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 960 : std::vector<TyTy::StructFieldType *> fields;
269 960 : size_t idx = 0;
270 2585 : for (auto &field : struct_decl.get_fields ())
271 : {
272 1625 : TyTy::BaseType *field_type
273 1625 : = TypeCheckType::Resolve (field.get_field_type ());
274 1625 : auto *ty_field
275 3250 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
276 1625 : std::to_string (idx), field_type,
277 1625 : field.get_locus ());
278 1625 : fields.push_back (ty_field);
279 1625 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
280 1625 : idx++;
281 : }
282 :
283 : // get the path
284 :
285 960 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
286 :
287 960 : CanonicalPath path
288 960 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
289 960 : Resolver2_0::Namespace::Types);
290 :
291 960 : RustIdent ident{path, struct_decl.get_locus ()};
292 :
293 : // its a single variant ADT
294 960 : std::vector<TyTy::VariantDef *> variants;
295 960 : variants.push_back (
296 960 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
297 960 : struct_decl.get_mappings ().get_defid (),
298 960 : struct_decl.get_identifier ().as_string (), ident,
299 1920 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
300 2880 : std::move (fields)));
301 :
302 : // Process #[repr(X)] attribute, if any
303 960 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
304 960 : TyTy::ADTType::ReprOptions repr
305 960 : = parse_repr_options (attrs, struct_decl.get_locus ());
306 :
307 960 : auto *type = new TyTy::ADTType (
308 960 : struct_decl.get_mappings ().get_defid (),
309 960 : struct_decl.get_mappings ().get_hirid (),
310 960 : struct_decl.get_mappings ().get_hirid (),
311 960 : struct_decl.get_identifier ().as_string (), ident,
312 : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
313 : std::move (substitutions), repr,
314 1920 : TyTy::SubstitutionArgumentMappings::empty (
315 960 : context->get_lifetime_resolver ().get_num_bound_regions ()),
316 3840 : region_constraints);
317 :
318 960 : context->insert_type (struct_decl.get_mappings (), type);
319 960 : infered = type;
320 :
321 960 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
322 1920 : }
323 :
324 : void
325 1567 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
326 : {
327 1567 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
328 1567 : auto &mappings = Analysis::Mappings::get ();
329 :
330 1567 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
331 1567 : if (struct_decl.has_generics ())
332 489 : resolve_generic_params (HIR::Item::ItemKind::Struct,
333 : struct_decl.get_locus (),
334 489 : struct_decl.get_generic_params (), substitutions);
335 :
336 1567 : TyTy::RegionConstraints region_constraints;
337 1571 : 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 1567 : std::vector<TyTy::StructFieldType *> fields;
343 3423 : for (auto &field : struct_decl.get_fields ())
344 : {
345 1861 : TyTy::BaseType *field_type
346 1861 : = TypeCheckType::Resolve (field.get_field_type ());
347 1861 : auto infer_type = field_type->contains_infer ();
348 1861 : if (infer_type)
349 : {
350 5 : rust_error_at (mappings.lookup_location (infer_type->get_ref ()),
351 : "the placeholder %<_%> is not allowed within types on "
352 : "item signatures for structs");
353 5 : return;
354 : }
355 1856 : auto *ty_field
356 1856 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
357 1856 : field.get_field_name ().as_string (),
358 3712 : field_type, field.get_locus ());
359 1856 : fields.push_back (ty_field);
360 1856 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
361 : }
362 :
363 1562 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
364 :
365 1562 : CanonicalPath path
366 1562 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
367 1562 : Resolver2_0::Namespace::Types);
368 :
369 1562 : RustIdent ident{path, struct_decl.get_locus ()};
370 :
371 : // its a single variant ADT
372 1562 : auto variant_type = struct_decl.is_unit_struct ()
373 1562 : ? TyTy::VariantDef::VariantType::UNIT
374 1007 : : TyTy::VariantDef::VariantType::STRUCT;
375 1562 : std::vector<TyTy::VariantDef *> variants;
376 1562 : variants.push_back (
377 1562 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
378 1562 : struct_decl.get_mappings ().get_defid (),
379 1562 : struct_decl.get_identifier ().as_string (), ident,
380 4686 : variant_type, tl::nullopt, std::move (fields)));
381 :
382 : // Process #[repr(X)] attribute, if any
383 1562 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
384 1562 : TyTy::ADTType::ReprOptions repr
385 1562 : = parse_repr_options (attrs, struct_decl.get_locus ());
386 :
387 1562 : auto *type = new TyTy::ADTType (
388 1562 : struct_decl.get_mappings ().get_defid (),
389 1562 : struct_decl.get_mappings ().get_hirid (),
390 1562 : struct_decl.get_mappings ().get_hirid (),
391 1562 : struct_decl.get_identifier ().as_string (), ident,
392 : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
393 : std::move (substitutions), repr,
394 3124 : TyTy::SubstitutionArgumentMappings::empty (
395 1562 : context->get_lifetime_resolver ().get_num_bound_regions ()),
396 6248 : region_constraints);
397 :
398 1562 : context->insert_type (struct_decl.get_mappings (), type);
399 1562 : infered = type;
400 :
401 1562 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
402 3134 : }
403 :
404 : void
405 527 : TypeCheckItem::visit (HIR::Enum &enum_decl)
406 : {
407 527 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
408 527 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
409 527 : if (enum_decl.has_generics ())
410 228 : resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
411 228 : enum_decl.get_generic_params (), substitutions);
412 :
413 : // Process #[repr(X)] attribute, if any
414 527 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
415 527 : TyTy::ADTType::ReprOptions repr
416 527 : = parse_repr_options (attrs, enum_decl.get_locus ());
417 :
418 527 : std::vector<TyTy::VariantDef *> variants;
419 527 : int64_t discriminant_value = 0;
420 1750 : for (auto &variant : enum_decl.get_variants ())
421 : {
422 1223 : TyTy::VariantDef *field_type
423 1223 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
424 1223 : if (field_type)
425 : {
426 1222 : discriminant_value++;
427 1222 : variants.push_back (field_type);
428 : }
429 : }
430 :
431 : // Check for zero-variant enum compatibility
432 527 : if (enum_decl.is_zero_variant ())
433 : {
434 10 : if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
435 10 : || repr.repr_kind == TyTy::ADTType::ReprKind::C)
436 : {
437 2 : rust_error_at (enum_decl.get_locus (),
438 : "unsupported representation for zero-variant enum");
439 2 : return;
440 : }
441 : }
442 :
443 525 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
444 :
445 : // get the path
446 525 : CanonicalPath canonical_path
447 525 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid (),
448 525 : Resolver2_0::Namespace::Types);
449 :
450 525 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
451 :
452 : // multi variant ADT
453 525 : auto *type
454 525 : = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
455 525 : enum_decl.get_mappings ().get_hirid (),
456 525 : enum_decl.get_mappings ().get_hirid (),
457 525 : enum_decl.get_identifier ().as_string (), ident,
458 : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
459 1575 : std::move (substitutions), repr);
460 :
461 525 : context->insert_type (enum_decl.get_mappings (), type);
462 525 : infered = type;
463 :
464 525 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
465 527 : }
466 :
467 : void
468 104 : TypeCheckItem::visit (HIR::Union &union_decl)
469 : {
470 104 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
471 104 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
472 104 : if (union_decl.has_generics ())
473 74 : resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
474 74 : union_decl.get_generic_params (), substitutions);
475 :
476 104 : TyTy::RegionConstraints region_constraints;
477 104 : for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
478 : {
479 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
480 : }
481 :
482 104 : std::vector<TyTy::StructFieldType *> fields;
483 406 : for (auto &variant : union_decl.get_variants ())
484 : {
485 302 : TyTy::BaseType *variant_type
486 302 : = TypeCheckType::Resolve (variant.get_field_type ());
487 302 : auto *ty_variant
488 302 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
489 302 : variant.get_field_name ().as_string (),
490 604 : variant_type, variant.get_locus ());
491 302 : fields.push_back (ty_variant);
492 302 : context->insert_type (variant.get_mappings (),
493 : ty_variant->get_field_type ());
494 : }
495 :
496 104 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
497 :
498 : // get the path
499 104 : CanonicalPath canonical_path
500 104 : = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid (),
501 104 : Resolver2_0::Namespace::Types);
502 :
503 104 : RustIdent ident{canonical_path, union_decl.get_locus ()};
504 :
505 : // there is only a single variant
506 104 : std::vector<TyTy::VariantDef *> variants;
507 104 : variants.push_back (
508 104 : new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
509 104 : union_decl.get_mappings ().get_defid (),
510 104 : union_decl.get_identifier ().as_string (), ident,
511 208 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
512 312 : std::move (fields)));
513 :
514 104 : auto *type
515 104 : = new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
516 104 : union_decl.get_mappings ().get_hirid (),
517 104 : union_decl.get_mappings ().get_hirid (),
518 104 : union_decl.get_identifier ().as_string (), ident,
519 : TyTy::ADTType::ADTKind::UNION, std::move (variants),
520 312 : std::move (substitutions));
521 :
522 104 : context->insert_type (union_decl.get_mappings (), type);
523 104 : infered = type;
524 :
525 104 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
526 208 : }
527 :
528 : void
529 53 : TypeCheckItem::visit (HIR::StaticItem &var)
530 : {
531 53 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
532 53 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
533 :
534 53 : TyTy::BaseType *unified
535 53 : = coercion_site (var.get_mappings ().get_hirid (),
536 53 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
537 : TyTy::TyWithLocation (expr_type,
538 53 : var.get_expr ().get_locus ()),
539 : var.get_locus ());
540 53 : context->insert_type (var.get_mappings (), unified);
541 53 : infered = unified;
542 53 : }
543 :
544 : void
545 412 : TypeCheckItem::visit (HIR::ConstantItem &constant)
546 : {
547 412 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
548 412 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
549 :
550 824 : TyTy::BaseType *unified = unify_site (
551 412 : constant.get_mappings ().get_hirid (),
552 412 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
553 412 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
554 : constant.get_locus ());
555 412 : context->insert_type (constant.get_mappings (), unified);
556 412 : infered = unified;
557 412 : }
558 :
559 : void
560 5692 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
561 : {
562 5692 : if (impl_block.has_trait_ref ())
563 4723 : resolve_trait_impl_block (impl_block);
564 : else
565 969 : resolve_impl_block (impl_block);
566 5692 : }
567 :
568 : void
569 969 : TypeCheckItem::resolve_impl_block (HIR::ImplBlock &impl_block)
570 : {
571 969 : auto binder_pin = context->push_clean_lifetime_resolver (true);
572 :
573 969 : bool failed_flag = false;
574 969 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
575 969 : if (failed_flag)
576 : {
577 3 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
578 3 : return;
579 : }
580 966 : std::vector<TyTy::SubstitutionParamMapping> substitutions
581 966 : = std::move (result.first);
582 966 : TyTy::RegionConstraints region_constraints = std::move (result.second);
583 :
584 966 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
585 :
586 3735 : for (auto &impl_item : impl_block.get_impl_items ())
587 2769 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
588 969 : }
589 :
590 : void
591 4723 : TypeCheckItem::resolve_trait_impl_block (HIR::ImplBlock &impl_block)
592 : {
593 4723 : auto binder_pin = context->push_clean_lifetime_resolver (true);
594 :
595 4723 : bool failed_flag = false;
596 4723 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
597 4723 : if (failed_flag)
598 : {
599 1 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
600 1 : return;
601 : }
602 4722 : std::vector<TyTy::SubstitutionParamMapping> substitutions
603 4722 : = std::move (result.first);
604 4722 : TyTy::RegionConstraints region_constraints = std::move (result.second);
605 :
606 4722 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
607 4722 : TraitReference *trait_reference = &TraitReference::error_node ();
608 4722 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
609 :
610 4722 : HIR::TypePath &ref = impl_block.get_trait_ref ();
611 4722 : trait_reference = TraitResolver::Resolve (ref);
612 4722 : if (trait_reference->is_error ())
613 3 : return;
614 :
615 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
616 : // for example
617 9438 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
618 4719 : impl_block.get_polarity ());
619 :
620 : // need to check that if this specified bound has super traits does this
621 : // Self implement them?
622 4719 : specified_bound.validate_type_implements_super_traits (
623 4719 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
624 :
625 4719 : std::map<DefId, AssocTypeEntry> assoc_types_by_trait_item;
626 4719 : std::vector<const TraitItemReference *> trait_item_refs;
627 4719 : ResolveImplTraitAssociatedTypes (context, impl_block, specified_bound, self,
628 : substitutions, assoc_types_by_trait_item,
629 : trait_item_refs);
630 :
631 4719 : ImplTraitContextFrame frame{trait_reference, self,
632 4719 : std::move (assoc_types_by_trait_item)};
633 4719 : ImplTraitFrameGuard guard (frame);
634 10133 : for (auto &impl_item : impl_block.get_impl_items ())
635 : {
636 5414 : bool is_type_alias = impl_item->get_impl_item_type ()
637 5414 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
638 5414 : if (is_type_alias)
639 1184 : continue;
640 :
641 4230 : auto trait_item_ref
642 4230 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
643 4230 : specified_bound, substitutions);
644 4230 : if (!trait_item_ref.is_error ())
645 4225 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
646 4230 : }
647 :
648 4719 : validate_trait_impl_block (specified_bound, trait_item_refs, trait_reference,
649 : impl_block, self, substitutions);
650 :
651 4719 : AssociatedImplTrait associated (trait_reference, specified_bound, &impl_block,
652 4719 : self, frame);
653 4719 : context->insert_associated_trait_impl (
654 4719 : impl_block.get_mappings ().get_hirid (), std::move (associated));
655 4719 : context->insert_associated_impl_mapping (
656 4719 : trait_reference->get_mappings ().get_hirid (), self,
657 4719 : impl_block.get_mappings ().get_hirid ());
658 9445 : }
659 :
660 : void
661 7198 : TypeCheckItem::ResolveImplTraitAssociatedTypes (
662 : TypeCheckContext *context, HIR::ImplBlock &impl_block,
663 : TyTy::TypeBoundPredicate &specified_bound, TyTy::BaseType *self,
664 : std::vector<TyTy::SubstitutionParamMapping> &substitutions,
665 : std::map<DefId, AssocTypeEntry> &assoc_types_by_trait_item,
666 : std::vector<const TraitItemReference *> &trait_item_refs)
667 : {
668 17880 : for (auto &impl_item : impl_block.get_impl_items ())
669 : {
670 10682 : bool is_type_alias = impl_item->get_impl_item_type ()
671 10682 : == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
672 10682 : if (!is_type_alias)
673 8829 : continue;
674 :
675 1853 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 1");
676 1853 : self->debug ();
677 1853 : auto trait_item_ref
678 1853 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
679 1853 : specified_bound, substitutions);
680 1853 : rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 2");
681 1853 : if (!trait_item_ref.is_error ())
682 : {
683 1853 : const TraitItemReference *tiref = trait_item_ref.get_raw_item ();
684 1853 : trait_item_refs.push_back (tiref);
685 :
686 1853 : DefId impl_item_defid = impl_item->get_impl_mappings ().get_defid ();
687 1853 : DefId trait_item_defid = tiref->get_mappings ().get_defid ();
688 1853 : TyTy::BaseType *impl_item_ty;
689 :
690 1853 : bool ok = context->lookup_type (
691 1853 : impl_item->get_impl_mappings ().get_hirid (), &impl_item_ty);
692 1853 : rust_assert (ok);
693 :
694 1853 : AssocTypeEntry entry
695 1853 : = {trait_item_defid, impl_item_defid, impl_item_ty};
696 1853 : assoc_types_by_trait_item[trait_item_defid] = std::move (entry);
697 : }
698 1853 : }
699 7198 : }
700 :
701 : TyTy::BaseType *
702 2991 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
703 : HIR::ImplItem &item)
704 : {
705 2991 : bool failed_flag = false;
706 2991 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
707 2991 : if (failed_flag)
708 : {
709 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
710 : }
711 :
712 2990 : std::vector<TyTy::SubstitutionParamMapping> substitutions
713 2990 : = std::move (result.first);
714 2990 : TyTy::RegionConstraints region_constraints = std::move (result.second);
715 :
716 2990 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
717 :
718 2990 : return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
719 2991 : }
720 :
721 : void
722 6581 : TypeCheckItem::visit (HIR::Function &function)
723 : {
724 6581 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
725 6581 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
726 6581 : if (function.has_generics ())
727 603 : resolve_generic_params (HIR::Item::ItemKind::Function,
728 : function.get_locus (),
729 603 : function.get_generic_params (), substitutions);
730 :
731 6581 : TyTy::RegionConstraints region_constraints;
732 6628 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
733 : {
734 47 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
735 : }
736 :
737 6581 : TyTy::BaseType *ret_type = nullptr;
738 6581 : if (!function.has_function_return_type ())
739 3281 : ret_type = TyTy::TupleType::get_unit_type ();
740 : else
741 : {
742 3300 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
743 3300 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
744 4 : return;
745 :
746 3296 : ret_type = resolved->clone ();
747 3296 : ret_type->set_ref (
748 3296 : function.get_return_type ().get_mappings ().get_hirid ());
749 : }
750 :
751 6577 : std::vector<TyTy::FnParam> params;
752 8495 : for (auto ¶m : function.get_function_params ())
753 : {
754 : // get the name as well required for later on
755 1918 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
756 1918 : context->insert_type (param.get_mappings (), param_tyty);
757 1918 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
758 1918 : params.emplace_back (param.get_param_name ().clone_pattern (),
759 : param_tyty);
760 : }
761 :
762 6577 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
763 :
764 6577 : CanonicalPath path
765 6577 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
766 6577 : Resolver2_0::Namespace::Values);
767 :
768 6577 : RustIdent ident{path, function.get_locus ()};
769 :
770 6577 : auto fn_type = new TyTy::FnType (
771 6577 : function.get_mappings ().get_hirid (),
772 6577 : function.get_mappings ().get_defid (),
773 6577 : function.get_function_name ().as_string (), ident,
774 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
775 : std::move (substitutions),
776 13154 : TyTy::SubstitutionArgumentMappings::empty (
777 6577 : context->get_lifetime_resolver ().get_num_bound_regions ()),
778 26308 : region_constraints);
779 :
780 6577 : context->insert_type (function.get_mappings (), fn_type);
781 :
782 : // need to get the return type from this
783 6577 : TyTy::FnType *resolved_fn_type = fn_type;
784 6577 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
785 6577 : context->push_return_type (TypeCheckContextItem (&function),
786 : expected_ret_tyty);
787 :
788 6577 : context->switch_to_fn_body ();
789 6577 : auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
790 :
791 : // emit check for
792 : // error[E0121]: the type placeholder `_` is not allowed within types on item
793 6577 : const auto placeholder = ret_type->contains_infer ();
794 6577 : if (placeholder != nullptr && function.has_return_type ())
795 : {
796 : // FIXME
797 : // this will be a great place for the Default Hir Visitor we want to
798 : // grab the locations of the placeholders (HIR::InferredType) their
799 : // location, for now maybe we can use their hirid to lookup the location
800 3 : location_t placeholder_locus
801 3 : = mappings.lookup_location (placeholder->get_ref ());
802 3 : location_t type_locus = function.get_return_type ().get_locus ();
803 3 : rich_location r (line_table, placeholder_locus);
804 :
805 3 : bool have_expected_type
806 6 : = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
807 3 : if (!have_expected_type)
808 : {
809 0 : r.add_range (type_locus);
810 : }
811 : else
812 : {
813 3 : std::string fixit
814 3 : = "replace with the correct type " + block_expr_ty->get_name ();
815 3 : r.add_fixit_replace (type_locus, fixit.c_str ());
816 3 : }
817 :
818 3 : rust_error_at (r, ErrorCode::E0121,
819 : "the type placeholder %<_%> is not allowed within types "
820 : "on item signatures");
821 3 : }
822 :
823 6577 : location_t fn_return_locus = function.has_function_return_type ()
824 6577 : ? function.get_return_type ().get_locus ()
825 3281 : : function.get_locus ();
826 13154 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
827 6577 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
828 6577 : TyTy::TyWithLocation (block_expr_ty),
829 6577 : function.get_definition ().get_locus ());
830 :
831 6577 : context->pop_return_type ();
832 :
833 6577 : infered = fn_type;
834 13158 : }
835 :
836 : void
837 1212 : TypeCheckItem::visit (HIR::Module &module)
838 : {
839 5154 : for (auto &item : module.get_items ())
840 3942 : TypeCheckItem::Resolve (*item);
841 1212 : }
842 :
843 : void
844 4285 : TypeCheckItem::visit (HIR::Trait &trait)
845 : {
846 4285 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
847 :
848 4285 : if (trait.has_type_param_bounds ())
849 : {
850 1639 : for (auto &tp_bound : trait.get_type_param_bounds ())
851 : {
852 894 : if (tp_bound.get ()->get_bound_type ()
853 : == HIR::TypeParamBound::BoundType::TRAITBOUND)
854 : {
855 894 : HIR::TraitBound &tb
856 894 : = static_cast<HIR::TraitBound &> (*tp_bound.get ());
857 894 : if (tb.get_polarity () == BoundPolarity::AntiBound)
858 : {
859 1 : rust_error_at (tb.get_locus (),
860 : "%<?Trait%> is not permitted in supertraits");
861 : }
862 : }
863 : }
864 : }
865 :
866 4285 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
867 4285 : if (trait_ref->is_error ())
868 : {
869 7 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
870 7 : return;
871 : }
872 :
873 4278 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
874 4278 : infered = new TyTy::DynamicObjectType (
875 4278 : trait.get_mappings ().get_hirid (), ident,
876 : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
877 12834 : trait.get_locus ())});
878 4285 : }
879 :
880 : void
881 1628 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
882 : {
883 4148 : for (auto &item : extern_block.get_extern_items ())
884 : {
885 2520 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
886 : }
887 1628 : }
888 :
889 : void
890 0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
891 : {
892 0 : if (extern_crate.references_self ())
893 : return;
894 :
895 0 : auto &mappings = Analysis::Mappings::get ();
896 0 : CrateNum num
897 0 : = mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
898 0 : .value ();
899 0 : HIR::Crate &crate = mappings.get_hir_crate (num);
900 :
901 0 : CrateNum saved_crate_num = mappings.get_current_crate ();
902 0 : mappings.set_current_crate (num);
903 0 : for (auto &item : crate.get_items ())
904 0 : TypeCheckItem::Resolve (*item);
905 0 : mappings.set_current_crate (saved_crate_num);
906 : }
907 :
908 : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
909 43722 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
910 : bool &failure_flag)
911 : {
912 43722 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
913 43722 : if (impl_block.has_generics ())
914 6195 : resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
915 6195 : impl_block.get_generic_params (), substitutions);
916 :
917 43722 : TyTy::RegionConstraints region_constraints;
918 44245 : for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
919 : {
920 523 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
921 : }
922 :
923 43722 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
924 43722 : TraitReference *trait_reference = &TraitReference::error_node ();
925 43722 : if (impl_block.has_trait_ref ())
926 : {
927 32838 : auto &ref = impl_block.get_trait_ref ();
928 32838 : trait_reference = TraitResolver::Resolve (ref);
929 32838 : if (!trait_reference->is_error ())
930 : {
931 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
932 : // for example
933 32834 : specified_bound
934 65668 : = get_predicate_from_bound (ref, impl_block.get_type (),
935 32834 : impl_block.get_polarity ());
936 : }
937 : }
938 :
939 43722 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
940 43722 : if (self->is<TyTy::ErrorType> ())
941 : {
942 : // we cannot check for unconstrained type arguments when the Self type is
943 : // not resolved it will just add extra errors that dont help as well as
944 : // the case where this could just be a recursive type query that should
945 : // fail and will work later on anyway
946 1 : return {substitutions, region_constraints};
947 : }
948 :
949 : // inherit the bounds
950 43721 : if (!specified_bound.is_error ())
951 65660 : self->inherit_bounds ({specified_bound});
952 :
953 : // check for any unconstrained type-params
954 43721 : const TyTy::SubstitutionArgumentMappings trait_constraints
955 43721 : = specified_bound.get_substitution_arguments ();
956 43721 : const TyTy::SubstitutionArgumentMappings impl_constraints
957 43721 : = GetUsedSubstArgs::From (self);
958 :
959 43721 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
960 : impl_constraints, self);
961 :
962 43721 : return {substitutions, region_constraints};
963 87444 : }
964 :
965 : TyTy::BaseType *
966 41236 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
967 : {
968 41236 : return TypeCheckType::Resolve (impl_block.get_type ());
969 : }
970 :
971 : } // namespace Resolver
972 : } // namespace Rust
|