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-identifier.h"
31 : #include "rust-session-manager.h"
32 : #include "rust-immutable-name-resolution-context.h"
33 : #include "rust-substitution-mapper.h"
34 : #include "rust-type-util.h"
35 : #include "rust-tyty-variance-analysis.h"
36 :
37 : namespace Rust {
38 : namespace Resolver {
39 :
40 58355 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
41 :
42 : TyTy::BaseType *
43 27555 : TypeCheckItem::Resolve (HIR::Item &item)
44 : {
45 : // is it already resolved?
46 27555 : auto context = TypeCheckContext::get ();
47 27555 : TyTy::BaseType *resolved = nullptr;
48 27555 : bool already_resolved
49 27555 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
50 27555 : if (already_resolved)
51 4871 : return resolved;
52 :
53 22684 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
54 22684 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
55 :
56 22684 : TypeCheckItem resolver;
57 22684 : vis_item.accept_vis (resolver);
58 22682 : return resolver.infered;
59 22682 : }
60 :
61 : TyTy::BaseType *
62 3279 : TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
63 : {
64 3279 : TypeCheckItem resolver;
65 3279 : return resolver.resolve_impl_item (impl_block, item);
66 3279 : }
67 :
68 : TyTy::BaseType *
69 29406 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
70 : {
71 29406 : TypeCheckItem resolver;
72 :
73 29406 : bool failed_flag = false;
74 29406 : auto result
75 29406 : = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
76 29406 : if (failed_flag)
77 : {
78 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
79 : }
80 29405 : std::vector<TyTy::SubstitutionParamMapping> substitutions
81 29405 : = std::move (result.first);
82 29405 : TyTy::RegionConstraints region_constraints = std::move (result.second);
83 :
84 29405 : return resolver.resolve_impl_block_self (impl_block);
85 29406 : }
86 :
87 : TyTy::BaseType *
88 2986 : TypeCheckItem::ResolveImplBlockSelfWithInference (
89 : HIR::ImplBlock &impl, location_t locus,
90 : TyTy::SubstitutionArgumentMappings *infer_arguments)
91 : {
92 2986 : TypeCheckItem resolver;
93 :
94 2986 : bool failed_flag = false;
95 2986 : auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
96 2986 : if (failed_flag)
97 : {
98 1 : return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
99 : }
100 2985 : std::vector<TyTy::SubstitutionParamMapping> substitutions
101 2985 : = std::move (result.first);
102 2985 : TyTy::RegionConstraints region_constraints = std::move (result.second);
103 :
104 : // now that we have the param mappings we need to query the self type
105 2985 : TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
106 :
107 : // nothing to do
108 2985 : if (substitutions.empty () || self->is_concrete ())
109 2274 : return self;
110 :
111 : // generate inference variables for the subst-param-mappings
112 711 : std::vector<TyTy::SubstitutionArg> args;
113 1447 : for (auto &p : substitutions)
114 : {
115 736 : auto param = p.get_param_ty ();
116 736 : if (!p.needs_substitution ())
117 : {
118 0 : auto resolved = param->destructure ();
119 0 : args.emplace_back (&p, resolved);
120 :
121 0 : continue;
122 0 : }
123 :
124 736 : TyTy::BaseType *argument = nullptr;
125 736 : if (param->get_kind () == TyTy::TypeKind::CONST)
126 : {
127 28 : auto i = TyTy::TyVar::get_implicit_const_infer_var (locus);
128 28 : argument = i.get_tyty ();
129 : }
130 : else
131 : {
132 708 : auto i = TyTy::TyVar::get_implicit_infer_var (locus);
133 708 : argument = i.get_tyty ();
134 : }
135 736 : args.emplace_back (&p, argument);
136 : }
137 :
138 : // create argument mappings
139 1422 : *infer_arguments = TyTy::SubstitutionArgumentMappings (
140 : std::move (args), {},
141 711 : TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
142 : infer_arguments),
143 1422 : locus);
144 :
145 711 : TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
146 :
147 : // we only need to apply to the bounds manually on types which dont bind
148 : // generics
149 711 : if (!infer->has_substitutions_defined ())
150 : {
151 613 : for (auto &bound : infer->get_specified_bounds ())
152 161 : bound.handle_substitions (*infer_arguments);
153 : }
154 :
155 711 : return infer;
156 3697 : }
157 :
158 : void
159 54 : TypeCheckItem::visit (HIR::TypeAlias &alias)
160 : {
161 54 : TyTy::BaseType *actual_type
162 54 : = TypeCheckType::Resolve (alias.get_type_aliased ());
163 :
164 54 : context->insert_type (alias.get_mappings (), actual_type);
165 :
166 54 : TyTy::RegionConstraints region_constraints;
167 54 : for (auto &where_clause_item : alias.get_where_clause ().get_items ())
168 : {
169 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
170 : }
171 54 : infered = actual_type;
172 54 : }
173 :
174 : void
175 957 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
176 : {
177 957 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
178 :
179 957 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
180 957 : if (struct_decl.has_generics ())
181 295 : resolve_generic_params (HIR::Item::ItemKind::Struct,
182 : struct_decl.get_locus (),
183 295 : struct_decl.get_generic_params (), substitutions);
184 :
185 957 : TyTy::RegionConstraints region_constraints;
186 957 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
187 : {
188 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
189 : }
190 :
191 957 : std::vector<TyTy::StructFieldType *> fields;
192 957 : size_t idx = 0;
193 2576 : for (auto &field : struct_decl.get_fields ())
194 : {
195 1619 : TyTy::BaseType *field_type
196 1619 : = TypeCheckType::Resolve (field.get_field_type ());
197 1619 : auto *ty_field
198 3238 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
199 1619 : std::to_string (idx), field_type,
200 1619 : field.get_locus ());
201 1619 : fields.push_back (ty_field);
202 1619 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
203 1619 : idx++;
204 : }
205 :
206 : // get the path
207 :
208 957 : auto &nr_ctx
209 957 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
210 :
211 957 : CanonicalPath path
212 957 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
213 :
214 957 : RustIdent ident{path, struct_decl.get_locus ()};
215 :
216 : // its a single variant ADT
217 957 : std::vector<TyTy::VariantDef *> variants;
218 957 : variants.push_back (
219 957 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
220 957 : struct_decl.get_mappings ().get_defid (),
221 957 : struct_decl.get_identifier ().as_string (), ident,
222 1914 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
223 2871 : std::move (fields)));
224 :
225 : // Process #[repr(X)] attribute, if any
226 957 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
227 957 : TyTy::ADTType::ReprOptions repr
228 957 : = parse_repr_options (attrs, struct_decl.get_locus ());
229 :
230 957 : auto *type = new TyTy::ADTType (
231 957 : struct_decl.get_mappings ().get_defid (),
232 957 : struct_decl.get_mappings ().get_hirid (),
233 957 : struct_decl.get_mappings ().get_hirid (),
234 957 : struct_decl.get_identifier ().as_string (), ident,
235 : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
236 : std::move (substitutions), repr,
237 1914 : TyTy::SubstitutionArgumentMappings::empty (
238 957 : context->get_lifetime_resolver ().get_num_bound_regions ()),
239 3828 : region_constraints);
240 :
241 957 : context->insert_type (struct_decl.get_mappings (), type);
242 957 : infered = type;
243 :
244 957 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
245 1914 : }
246 :
247 : void
248 1503 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
249 : {
250 1503 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
251 :
252 1503 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
253 1503 : if (struct_decl.has_generics ())
254 482 : resolve_generic_params (HIR::Item::ItemKind::Struct,
255 : struct_decl.get_locus (),
256 482 : struct_decl.get_generic_params (), substitutions);
257 :
258 1503 : TyTy::RegionConstraints region_constraints;
259 1507 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
260 : {
261 4 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
262 : }
263 :
264 1503 : std::vector<TyTy::StructFieldType *> fields;
265 3312 : for (auto &field : struct_decl.get_fields ())
266 : {
267 1809 : TyTy::BaseType *field_type
268 1809 : = TypeCheckType::Resolve (field.get_field_type ());
269 1809 : auto *ty_field
270 1809 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
271 1809 : field.get_field_name ().as_string (),
272 3618 : field_type, field.get_locus ());
273 1809 : fields.push_back (ty_field);
274 1809 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
275 : }
276 :
277 1503 : auto &nr_ctx
278 1503 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
279 :
280 1503 : CanonicalPath path
281 1503 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
282 :
283 1503 : RustIdent ident{path, struct_decl.get_locus ()};
284 :
285 : // its a single variant ADT
286 1503 : auto variant_type = struct_decl.is_unit_struct ()
287 1503 : ? TyTy::VariantDef::VariantType::UNIT
288 967 : : TyTy::VariantDef::VariantType::STRUCT;
289 1503 : std::vector<TyTy::VariantDef *> variants;
290 1503 : variants.push_back (
291 1503 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
292 1503 : struct_decl.get_mappings ().get_defid (),
293 1503 : struct_decl.get_identifier ().as_string (), ident,
294 4509 : variant_type, tl::nullopt, std::move (fields)));
295 :
296 : // Process #[repr(X)] attribute, if any
297 1503 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
298 1503 : TyTy::ADTType::ReprOptions repr
299 1503 : = parse_repr_options (attrs, struct_decl.get_locus ());
300 :
301 1503 : auto *type = new TyTy::ADTType (
302 1503 : struct_decl.get_mappings ().get_defid (),
303 1503 : struct_decl.get_mappings ().get_hirid (),
304 1503 : struct_decl.get_mappings ().get_hirid (),
305 1503 : struct_decl.get_identifier ().as_string (), ident,
306 : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
307 : std::move (substitutions), repr,
308 3006 : TyTy::SubstitutionArgumentMappings::empty (
309 1503 : context->get_lifetime_resolver ().get_num_bound_regions ()),
310 6012 : region_constraints);
311 :
312 1503 : context->insert_type (struct_decl.get_mappings (), type);
313 1503 : infered = type;
314 :
315 1503 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
316 3006 : }
317 :
318 : void
319 523 : TypeCheckItem::visit (HIR::Enum &enum_decl)
320 : {
321 523 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
322 523 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
323 523 : if (enum_decl.has_generics ())
324 226 : resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
325 226 : enum_decl.get_generic_params (), substitutions);
326 :
327 : // Process #[repr(X)] attribute, if any
328 523 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
329 523 : TyTy::ADTType::ReprOptions repr
330 523 : = parse_repr_options (attrs, enum_decl.get_locus ());
331 :
332 523 : std::vector<TyTy::VariantDef *> variants;
333 523 : int64_t discriminant_value = 0;
334 1738 : for (auto &variant : enum_decl.get_variants ())
335 : {
336 1215 : TyTy::VariantDef *field_type
337 1215 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
338 :
339 1215 : discriminant_value++;
340 1215 : variants.push_back (field_type);
341 : }
342 :
343 : // Check for zero-variant enum compatibility
344 523 : if (enum_decl.is_zero_variant ())
345 : {
346 10 : if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
347 10 : || repr.repr_kind == TyTy::ADTType::ReprKind::C)
348 : {
349 2 : rust_error_at (enum_decl.get_locus (),
350 : "unsupported representation for zero-variant enum");
351 2 : return;
352 : }
353 : }
354 :
355 521 : auto &nr_ctx
356 521 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
357 :
358 : // get the path
359 521 : CanonicalPath canonical_path
360 521 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid ());
361 :
362 521 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
363 :
364 : // multi variant ADT
365 521 : auto *type
366 521 : = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
367 521 : enum_decl.get_mappings ().get_hirid (),
368 521 : enum_decl.get_mappings ().get_hirid (),
369 521 : enum_decl.get_identifier ().as_string (), ident,
370 : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
371 1563 : std::move (substitutions), repr);
372 :
373 521 : context->insert_type (enum_decl.get_mappings (), type);
374 521 : infered = type;
375 :
376 521 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
377 523 : }
378 :
379 : void
380 104 : TypeCheckItem::visit (HIR::Union &union_decl)
381 : {
382 104 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
383 104 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
384 104 : if (union_decl.has_generics ())
385 74 : resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
386 74 : union_decl.get_generic_params (), substitutions);
387 :
388 104 : TyTy::RegionConstraints region_constraints;
389 104 : for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
390 : {
391 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
392 : }
393 :
394 104 : std::vector<TyTy::StructFieldType *> fields;
395 406 : for (auto &variant : union_decl.get_variants ())
396 : {
397 302 : TyTy::BaseType *variant_type
398 302 : = TypeCheckType::Resolve (variant.get_field_type ());
399 302 : auto *ty_variant
400 302 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
401 302 : variant.get_field_name ().as_string (),
402 604 : variant_type, variant.get_locus ());
403 302 : fields.push_back (ty_variant);
404 302 : context->insert_type (variant.get_mappings (),
405 : ty_variant->get_field_type ());
406 : }
407 :
408 104 : auto &nr_ctx
409 104 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
410 :
411 : // get the path
412 104 : CanonicalPath canonical_path
413 104 : = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid ());
414 :
415 104 : RustIdent ident{canonical_path, union_decl.get_locus ()};
416 :
417 : // there is only a single variant
418 104 : std::vector<TyTy::VariantDef *> variants;
419 104 : variants.push_back (
420 104 : new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
421 104 : union_decl.get_mappings ().get_defid (),
422 104 : union_decl.get_identifier ().as_string (), ident,
423 208 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
424 312 : std::move (fields)));
425 :
426 104 : auto *type
427 104 : = new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
428 104 : union_decl.get_mappings ().get_hirid (),
429 104 : union_decl.get_mappings ().get_hirid (),
430 104 : union_decl.get_identifier ().as_string (), ident,
431 : TyTy::ADTType::ADTKind::UNION, std::move (variants),
432 312 : std::move (substitutions));
433 :
434 104 : context->insert_type (union_decl.get_mappings (), type);
435 104 : infered = type;
436 :
437 104 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
438 208 : }
439 :
440 : void
441 53 : TypeCheckItem::visit (HIR::StaticItem &var)
442 : {
443 53 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
444 53 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
445 :
446 53 : TyTy::BaseType *unified
447 53 : = coercion_site (var.get_mappings ().get_hirid (),
448 53 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
449 : TyTy::TyWithLocation (expr_type,
450 53 : var.get_expr ().get_locus ()),
451 : var.get_locus ());
452 53 : context->insert_type (var.get_mappings (), unified);
453 53 : infered = unified;
454 53 : }
455 :
456 : void
457 409 : TypeCheckItem::visit (HIR::ConstantItem &constant)
458 : {
459 409 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
460 409 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
461 :
462 818 : TyTy::BaseType *unified = unify_site (
463 409 : constant.get_mappings ().get_hirid (),
464 409 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
465 409 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
466 : constant.get_locus ());
467 409 : context->insert_type (constant.get_mappings (), unified);
468 409 : infered = unified;
469 409 : }
470 :
471 : void
472 5597 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
473 : {
474 5597 : auto binder_pin = context->push_clean_lifetime_resolver (true);
475 :
476 5597 : TraitReference *trait_reference = &TraitReference::error_node ();
477 5597 : if (impl_block.has_trait_ref ())
478 : {
479 4654 : HIR::TypePath &ref = impl_block.get_trait_ref ();
480 4654 : trait_reference = TraitResolver::Resolve (ref);
481 4654 : if (trait_reference->is_error ())
482 : return;
483 : }
484 :
485 5596 : bool failed_flag = false;
486 5596 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
487 5596 : if (failed_flag)
488 : {
489 4 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
490 4 : return;
491 : }
492 5592 : std::vector<TyTy::SubstitutionParamMapping> substitutions
493 5592 : = std::move (result.first);
494 5592 : TyTy::RegionConstraints region_constraints = std::move (result.second);
495 :
496 5592 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
497 :
498 : // resolve each impl_item
499 13673 : for (auto &impl_item : impl_block.get_impl_items ())
500 : {
501 8081 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
502 : }
503 :
504 : // validate the impl items
505 5592 : validate_trait_impl_block (trait_reference, impl_block, self, substitutions);
506 5597 : }
507 :
508 : TyTy::BaseType *
509 3279 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
510 : HIR::ImplItem &item)
511 : {
512 3279 : bool failed_flag = false;
513 3279 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
514 3279 : if (failed_flag)
515 : {
516 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
517 : }
518 :
519 3278 : std::vector<TyTy::SubstitutionParamMapping> substitutions
520 3278 : = std::move (result.first);
521 3278 : TyTy::RegionConstraints region_constraints = std::move (result.second);
522 :
523 3278 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
524 :
525 3278 : return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
526 3279 : }
527 :
528 : void
529 6491 : TypeCheckItem::visit (HIR::Function &function)
530 : {
531 6491 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
532 6491 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
533 6491 : if (function.has_generics ())
534 601 : resolve_generic_params (HIR::Item::ItemKind::Function,
535 : function.get_locus (),
536 601 : function.get_generic_params (), substitutions);
537 :
538 6491 : TyTy::RegionConstraints region_constraints;
539 6537 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
540 : {
541 46 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
542 : }
543 :
544 6491 : TyTy::BaseType *ret_type = nullptr;
545 6491 : if (!function.has_function_return_type ())
546 3243 : ret_type = TyTy::TupleType::get_unit_type ();
547 : else
548 : {
549 3248 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
550 3248 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
551 : {
552 3 : rust_error_at (function.get_locus (),
553 : "failed to resolve return type");
554 3 : return;
555 : }
556 :
557 3245 : ret_type = resolved->clone ();
558 3245 : ret_type->set_ref (
559 3245 : function.get_return_type ().get_mappings ().get_hirid ());
560 : }
561 :
562 6488 : std::vector<TyTy::FnParam> params;
563 8396 : for (auto ¶m : function.get_function_params ())
564 : {
565 : // get the name as well required for later on
566 1908 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
567 1908 : context->insert_type (param.get_mappings (), param_tyty);
568 1908 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
569 1908 : params.emplace_back (param.get_param_name ().clone_pattern (),
570 : param_tyty);
571 : }
572 :
573 6488 : auto &nr_ctx
574 6488 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
575 :
576 6488 : CanonicalPath path
577 6488 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
578 :
579 6488 : RustIdent ident{path, function.get_locus ()};
580 :
581 6488 : auto fn_type = new TyTy::FnType (
582 6488 : function.get_mappings ().get_hirid (),
583 6488 : function.get_mappings ().get_defid (),
584 6488 : function.get_function_name ().as_string (), ident,
585 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
586 : std::move (substitutions),
587 12976 : TyTy::SubstitutionArgumentMappings::empty (
588 6488 : context->get_lifetime_resolver ().get_num_bound_regions ()),
589 25952 : region_constraints);
590 :
591 6488 : context->insert_type (function.get_mappings (), fn_type);
592 :
593 : // need to get the return type from this
594 6488 : TyTy::FnType *resolved_fn_type = fn_type;
595 6488 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
596 6488 : context->push_return_type (TypeCheckContextItem (&function),
597 : expected_ret_tyty);
598 :
599 6488 : context->switch_to_fn_body ();
600 6488 : auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
601 :
602 : // emit check for
603 : // error[E0121]: the type placeholder `_` is not allowed within types on item
604 6488 : const auto placeholder = ret_type->contains_infer ();
605 6488 : if (placeholder != nullptr && function.has_return_type ())
606 : {
607 : // FIXME
608 : // this will be a great place for the Default Hir Visitor we want to
609 : // grab the locations of the placeholders (HIR::InferredType) their
610 : // location, for now maybe we can use their hirid to lookup the location
611 3 : location_t placeholder_locus
612 3 : = mappings.lookup_location (placeholder->get_ref ());
613 3 : location_t type_locus = function.get_return_type ().get_locus ();
614 3 : rich_location r (line_table, placeholder_locus);
615 :
616 3 : bool have_expected_type
617 6 : = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
618 3 : if (!have_expected_type)
619 : {
620 0 : r.add_range (type_locus);
621 : }
622 : else
623 : {
624 3 : std::string fixit
625 3 : = "replace with the correct type " + block_expr_ty->get_name ();
626 3 : r.add_fixit_replace (type_locus, fixit.c_str ());
627 3 : }
628 :
629 3 : rust_error_at (r, ErrorCode::E0121,
630 : "the type placeholder %<_%> is not allowed within types "
631 : "on item signatures");
632 3 : }
633 :
634 6488 : location_t fn_return_locus = function.has_function_return_type ()
635 6488 : ? function.get_return_type ().get_locus ()
636 3243 : : function.get_locus ();
637 12976 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
638 6488 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
639 6488 : TyTy::TyWithLocation (block_expr_ty),
640 6488 : function.get_definition ().get_locus ());
641 :
642 6488 : context->pop_return_type ();
643 :
644 6488 : infered = fn_type;
645 12979 : }
646 :
647 : void
648 1203 : TypeCheckItem::visit (HIR::Module &module)
649 : {
650 5125 : for (auto &item : module.get_items ())
651 3923 : TypeCheckItem::Resolve (*item);
652 1202 : }
653 :
654 : void
655 4200 : TypeCheckItem::visit (HIR::Trait &trait)
656 : {
657 4200 : if (trait.has_type_param_bounds ())
658 : {
659 1625 : for (auto &tp_bound : trait.get_type_param_bounds ())
660 : {
661 886 : if (tp_bound.get ()->get_bound_type ()
662 : == HIR::TypeParamBound::BoundType::TRAITBOUND)
663 : {
664 886 : HIR::TraitBound &tb
665 886 : = static_cast<HIR::TraitBound &> (*tp_bound.get ());
666 886 : if (tb.get_polarity () == BoundPolarity::AntiBound)
667 : {
668 1 : rust_error_at (tb.get_locus (),
669 : "%<?Trait%> is not permitted in supertraits");
670 : }
671 : }
672 : }
673 : }
674 :
675 4200 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
676 4200 : if (trait_ref->is_error ())
677 : {
678 4 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
679 4 : return;
680 : }
681 :
682 4196 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
683 4196 : infered = new TyTy::DynamicObjectType (
684 4196 : trait.get_mappings ().get_hirid (), ident,
685 : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
686 12588 : trait.get_locus ())});
687 4196 : }
688 :
689 : void
690 1590 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
691 : {
692 4065 : for (auto &item : extern_block.get_extern_items ())
693 : {
694 2476 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
695 : }
696 1589 : }
697 :
698 : void
699 0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
700 : {
701 0 : if (extern_crate.references_self ())
702 : return;
703 :
704 0 : auto &mappings = Analysis::Mappings::get ();
705 0 : CrateNum num
706 0 : = mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
707 0 : .value ();
708 0 : HIR::Crate &crate = mappings.get_hir_crate (num);
709 :
710 0 : CrateNum saved_crate_num = mappings.get_current_crate ();
711 0 : mappings.set_current_crate (num);
712 0 : for (auto &item : crate.get_items ())
713 0 : TypeCheckItem::Resolve (*item);
714 0 : mappings.set_current_crate (saved_crate_num);
715 : }
716 :
717 : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
718 41267 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
719 : bool &failure_flag)
720 : {
721 41267 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
722 41267 : if (impl_block.has_generics ())
723 5935 : resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
724 5935 : impl_block.get_generic_params (), substitutions);
725 :
726 41267 : TyTy::RegionConstraints region_constraints;
727 41781 : for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
728 : {
729 514 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
730 : }
731 :
732 41267 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
733 41267 : TraitReference *trait_reference = &TraitReference::error_node ();
734 41267 : if (impl_block.has_trait_ref ())
735 : {
736 30476 : auto &ref = impl_block.get_trait_ref ();
737 30476 : trait_reference = TraitResolver::Resolve (ref);
738 30476 : rust_assert (!trait_reference->is_error ());
739 :
740 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
741 : // for example
742 60952 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
743 30476 : impl_block.get_polarity ());
744 : }
745 :
746 41267 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
747 41267 : if (self->is<TyTy::ErrorType> ())
748 : {
749 : // we cannot check for unconstrained type arguments when the Self type is
750 : // not resolved it will just add extra errors that dont help as well as
751 : // the case where this could just be a recursive type query that should
752 : // fail and will work later on anyway
753 1 : return {substitutions, region_constraints};
754 : }
755 :
756 : // inherit the bounds
757 41266 : if (!specified_bound.is_error ())
758 60944 : self->inherit_bounds ({specified_bound});
759 :
760 : // check for any unconstrained type-params
761 41266 : const TyTy::SubstitutionArgumentMappings trait_constraints
762 41266 : = specified_bound.get_substitution_arguments ();
763 41266 : const TyTy::SubstitutionArgumentMappings impl_constraints
764 41266 : = GetUsedSubstArgs::From (self);
765 :
766 41266 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
767 : impl_constraints, self);
768 :
769 41266 : return {substitutions, region_constraints};
770 82534 : }
771 :
772 : void
773 5592 : TypeCheckItem::validate_trait_impl_block (
774 : TraitReference *trait_reference, HIR::ImplBlock &impl_block,
775 : TyTy::BaseType *self,
776 : std::vector<TyTy::SubstitutionParamMapping> &substitutions)
777 : {
778 5592 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
779 5592 : if (impl_block.has_trait_ref ())
780 : {
781 4652 : auto &ref = impl_block.get_trait_ref ();
782 4652 : trait_reference = TraitResolver::Resolve (ref);
783 4652 : if (trait_reference->is_error ())
784 0 : return;
785 :
786 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
787 : // for example
788 9304 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
789 4652 : impl_block.get_polarity ());
790 :
791 : // need to check that if this specified bound has super traits does this
792 : // Self
793 : // implement them?
794 4652 : specified_bound.validate_type_implements_super_traits (
795 4652 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
796 : }
797 :
798 5592 : bool is_trait_impl_block = !trait_reference->is_error ();
799 5592 : std::vector<const TraitItemReference *> trait_item_refs;
800 13673 : for (auto &impl_item : impl_block.get_impl_items ())
801 : {
802 8081 : if (!specified_bound.is_error ())
803 : {
804 5352 : auto trait_item_ref
805 5352 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
806 : specified_bound,
807 5352 : substitutions);
808 5352 : if (!trait_item_ref.is_error ())
809 5347 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
810 5352 : }
811 : }
812 :
813 5592 : bool impl_block_missing_trait_items
814 5592 : = !specified_bound.is_error ()
815 5592 : && trait_reference->size () != trait_item_refs.size ();
816 1604 : if (impl_block_missing_trait_items
817 1604 : && impl_block.get_polarity () == BoundPolarity::RegularBound)
818 : {
819 : // filter the missing impl_items
820 1602 : std::vector<std::reference_wrapper<const TraitItemReference>>
821 1602 : missing_trait_items;
822 5086 : for (const auto &trait_item_ref : trait_reference->get_trait_items ())
823 : {
824 3484 : bool found = false;
825 5362 : for (auto implemented_trait_item : trait_item_refs)
826 : {
827 3313 : std::string trait_item_name = trait_item_ref.get_identifier ();
828 3313 : std::string impl_item_name
829 3313 : = implemented_trait_item->get_identifier ();
830 3313 : found = trait_item_name == impl_item_name;
831 3313 : if (found)
832 : break;
833 3313 : }
834 :
835 3484 : bool is_required_trait_item = !trait_item_ref.is_optional ();
836 3484 : if (!found && is_required_trait_item)
837 7 : missing_trait_items.emplace_back (trait_item_ref);
838 : }
839 :
840 1602 : if (!missing_trait_items.empty ())
841 : {
842 5 : std::string missing_items_buf;
843 5 : rich_location r (line_table, impl_block.get_locus ());
844 12 : for (size_t i = 0; i < missing_trait_items.size (); i++)
845 : {
846 7 : bool has_more = (i + 1) < missing_trait_items.size ();
847 7 : const TraitItemReference &missing_trait_item
848 7 : = missing_trait_items.at (i);
849 7 : missing_items_buf += missing_trait_item.get_identifier ()
850 21 : + (has_more ? ", " : "");
851 7 : r.add_range (missing_trait_item.get_locus ());
852 : }
853 :
854 5 : rust_error_at (r, ErrorCode::E0046,
855 : "missing %s in implementation of trait %qs",
856 : missing_items_buf.c_str (),
857 5 : trait_reference->get_name ().c_str ());
858 5 : }
859 1602 : }
860 :
861 5592 : if (is_trait_impl_block)
862 : {
863 4652 : trait_reference->clear_associated_types ();
864 :
865 4652 : AssociatedImplTrait associated (trait_reference, specified_bound,
866 4652 : &impl_block, self, context);
867 4652 : context->insert_associated_trait_impl (
868 4652 : impl_block.get_mappings ().get_hirid (), std::move (associated));
869 4652 : context->insert_associated_impl_mapping (
870 4652 : trait_reference->get_mappings ().get_hirid (), self,
871 4652 : impl_block.get_mappings ().get_hirid ());
872 4652 : }
873 5592 : }
874 :
875 : TyTy::BaseType *
876 41260 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
877 : {
878 41260 : return TypeCheckType::Resolve (impl_block.get_type ());
879 : }
880 :
881 : } // namespace Resolver
882 : } // namespace Rust
|