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 57867 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
41 :
42 : TyTy::BaseType *
43 27039 : TypeCheckItem::Resolve (HIR::Item &item)
44 : {
45 : // is it already resolved?
46 27039 : auto context = TypeCheckContext::get ();
47 27039 : TyTy::BaseType *resolved = nullptr;
48 27039 : bool already_resolved
49 27039 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
50 27039 : if (already_resolved)
51 4843 : return resolved;
52 :
53 22196 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
54 22196 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
55 :
56 22196 : TypeCheckItem resolver;
57 22196 : vis_item.accept_vis (resolver);
58 22194 : return resolver.infered;
59 22194 : }
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 955 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
176 : {
177 955 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
178 :
179 955 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
180 955 : 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 955 : TyTy::RegionConstraints region_constraints;
186 955 : 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 955 : std::vector<TyTy::StructFieldType *> fields;
192 955 : size_t idx = 0;
193 2571 : for (auto &field : struct_decl.get_fields ())
194 : {
195 1616 : TyTy::BaseType *field_type
196 1616 : = TypeCheckType::Resolve (field.get_field_type ());
197 1616 : auto *ty_field
198 3232 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
199 1616 : std::to_string (idx), field_type,
200 1616 : field.get_locus ());
201 1616 : fields.push_back (ty_field);
202 1616 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
203 1616 : idx++;
204 : }
205 :
206 : // get the path
207 :
208 955 : auto &nr_ctx
209 955 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
210 :
211 955 : CanonicalPath path
212 955 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
213 :
214 955 : RustIdent ident{path, struct_decl.get_locus ()};
215 :
216 : // its a single variant ADT
217 955 : std::vector<TyTy::VariantDef *> variants;
218 955 : variants.push_back (
219 955 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
220 955 : struct_decl.get_mappings ().get_defid (),
221 955 : struct_decl.get_identifier ().as_string (), ident,
222 1910 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
223 2865 : std::move (fields)));
224 :
225 : // Process #[repr(X)] attribute, if any
226 955 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
227 955 : TyTy::ADTType::ReprOptions repr
228 955 : = parse_repr_options (attrs, struct_decl.get_locus ());
229 :
230 955 : auto *type = new TyTy::ADTType (
231 955 : struct_decl.get_mappings ().get_defid (),
232 955 : struct_decl.get_mappings ().get_hirid (),
233 955 : struct_decl.get_mappings ().get_hirid (),
234 955 : struct_decl.get_identifier ().as_string (), ident,
235 : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
236 : std::move (substitutions), repr,
237 1910 : TyTy::SubstitutionArgumentMappings::empty (
238 955 : context->get_lifetime_resolver ().get_num_bound_regions ()),
239 3820 : region_constraints);
240 :
241 955 : context->insert_type (struct_decl.get_mappings (), type);
242 955 : infered = type;
243 :
244 955 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
245 1910 : }
246 :
247 : void
248 1501 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
249 : {
250 1501 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
251 :
252 1501 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
253 1501 : if (struct_decl.has_generics ())
254 481 : resolve_generic_params (HIR::Item::ItemKind::Struct,
255 : struct_decl.get_locus (),
256 481 : struct_decl.get_generic_params (), substitutions);
257 :
258 1501 : TyTy::RegionConstraints region_constraints;
259 1505 : 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 1501 : std::vector<TyTy::StructFieldType *> fields;
265 3310 : 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 1501 : auto &nr_ctx
278 1501 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
279 :
280 1501 : CanonicalPath path
281 1501 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
282 :
283 1501 : RustIdent ident{path, struct_decl.get_locus ()};
284 :
285 : // its a single variant ADT
286 1501 : std::vector<TyTy::VariantDef *> variants;
287 1501 : variants.push_back (
288 1501 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
289 1501 : struct_decl.get_mappings ().get_defid (),
290 1501 : struct_decl.get_identifier ().as_string (), ident,
291 3002 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
292 4503 : std::move (fields)));
293 :
294 : // Process #[repr(X)] attribute, if any
295 1501 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
296 1501 : TyTy::ADTType::ReprOptions repr
297 1501 : = parse_repr_options (attrs, struct_decl.get_locus ());
298 :
299 1501 : auto *type = new TyTy::ADTType (
300 1501 : struct_decl.get_mappings ().get_defid (),
301 1501 : struct_decl.get_mappings ().get_hirid (),
302 1501 : struct_decl.get_mappings ().get_hirid (),
303 1501 : struct_decl.get_identifier ().as_string (), ident,
304 : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
305 : std::move (substitutions), repr,
306 3002 : TyTy::SubstitutionArgumentMappings::empty (
307 1501 : context->get_lifetime_resolver ().get_num_bound_regions ()),
308 6004 : region_constraints);
309 :
310 1501 : context->insert_type (struct_decl.get_mappings (), type);
311 1501 : infered = type;
312 :
313 1501 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
314 3002 : }
315 :
316 : void
317 514 : TypeCheckItem::visit (HIR::Enum &enum_decl)
318 : {
319 514 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
320 514 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
321 514 : if (enum_decl.has_generics ())
322 226 : resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
323 226 : enum_decl.get_generic_params (), substitutions);
324 :
325 : // Process #[repr(X)] attribute, if any
326 514 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
327 514 : TyTy::ADTType::ReprOptions repr
328 514 : = parse_repr_options (attrs, enum_decl.get_locus ());
329 :
330 514 : std::vector<TyTy::VariantDef *> variants;
331 514 : int64_t discriminant_value = 0;
332 1716 : for (auto &variant : enum_decl.get_variants ())
333 : {
334 1202 : TyTy::VariantDef *field_type
335 1202 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
336 :
337 1202 : discriminant_value++;
338 1202 : variants.push_back (field_type);
339 : }
340 :
341 : // Check for zero-variant enum compatibility
342 514 : if (enum_decl.is_zero_variant ())
343 : {
344 9 : if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
345 9 : || repr.repr_kind == TyTy::ADTType::ReprKind::C)
346 : {
347 2 : rust_error_at (enum_decl.get_locus (),
348 : "unsupported representation for zero-variant enum");
349 2 : return;
350 : }
351 : }
352 :
353 512 : auto &nr_ctx
354 512 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
355 :
356 : // get the path
357 512 : CanonicalPath canonical_path
358 512 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid ());
359 :
360 512 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
361 :
362 : // multi variant ADT
363 512 : auto *type
364 512 : = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
365 512 : enum_decl.get_mappings ().get_hirid (),
366 512 : enum_decl.get_mappings ().get_hirid (),
367 512 : enum_decl.get_identifier ().as_string (), ident,
368 : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
369 1536 : std::move (substitutions), repr);
370 :
371 512 : context->insert_type (enum_decl.get_mappings (), type);
372 512 : infered = type;
373 :
374 512 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
375 514 : }
376 :
377 : void
378 100 : TypeCheckItem::visit (HIR::Union &union_decl)
379 : {
380 100 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
381 100 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
382 100 : if (union_decl.has_generics ())
383 74 : resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
384 74 : union_decl.get_generic_params (), substitutions);
385 :
386 100 : TyTy::RegionConstraints region_constraints;
387 100 : for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
388 : {
389 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
390 : }
391 :
392 100 : std::vector<TyTy::StructFieldType *> fields;
393 394 : for (auto &variant : union_decl.get_variants ())
394 : {
395 294 : TyTy::BaseType *variant_type
396 294 : = TypeCheckType::Resolve (variant.get_field_type ());
397 294 : auto *ty_variant
398 294 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
399 294 : variant.get_field_name ().as_string (),
400 588 : variant_type, variant.get_locus ());
401 294 : fields.push_back (ty_variant);
402 294 : context->insert_type (variant.get_mappings (),
403 : ty_variant->get_field_type ());
404 : }
405 :
406 100 : auto &nr_ctx
407 100 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
408 :
409 : // get the path
410 100 : CanonicalPath canonical_path
411 100 : = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid ());
412 :
413 100 : RustIdent ident{canonical_path, union_decl.get_locus ()};
414 :
415 : // there is only a single variant
416 100 : std::vector<TyTy::VariantDef *> variants;
417 100 : variants.push_back (
418 100 : new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
419 100 : union_decl.get_mappings ().get_defid (),
420 100 : union_decl.get_identifier ().as_string (), ident,
421 200 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
422 300 : std::move (fields)));
423 :
424 100 : auto *type
425 100 : = new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
426 100 : union_decl.get_mappings ().get_hirid (),
427 100 : union_decl.get_mappings ().get_hirid (),
428 100 : union_decl.get_identifier ().as_string (), ident,
429 : TyTy::ADTType::ADTKind::UNION, std::move (variants),
430 300 : std::move (substitutions));
431 :
432 100 : context->insert_type (union_decl.get_mappings (), type);
433 100 : infered = type;
434 :
435 100 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
436 200 : }
437 :
438 : void
439 53 : TypeCheckItem::visit (HIR::StaticItem &var)
440 : {
441 53 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
442 53 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
443 :
444 53 : TyTy::BaseType *unified
445 53 : = coercion_site (var.get_mappings ().get_hirid (),
446 53 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
447 : TyTy::TyWithLocation (expr_type,
448 53 : var.get_expr ().get_locus ()),
449 : var.get_locus ());
450 53 : context->insert_type (var.get_mappings (), unified);
451 53 : infered = unified;
452 53 : }
453 :
454 : void
455 405 : TypeCheckItem::visit (HIR::ConstantItem &constant)
456 : {
457 405 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
458 405 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
459 :
460 810 : TyTy::BaseType *unified = unify_site (
461 405 : constant.get_mappings ().get_hirid (),
462 405 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
463 405 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
464 : constant.get_locus ());
465 405 : context->insert_type (constant.get_mappings (), unified);
466 405 : infered = unified;
467 405 : }
468 :
469 : void
470 5594 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
471 : {
472 5594 : auto binder_pin = context->push_clean_lifetime_resolver (true);
473 :
474 5594 : TraitReference *trait_reference = &TraitReference::error_node ();
475 5594 : if (impl_block.has_trait_ref ())
476 : {
477 4653 : HIR::TypePath &ref = impl_block.get_trait_ref ();
478 4653 : trait_reference = TraitResolver::Resolve (ref);
479 4653 : if (trait_reference->is_error ())
480 : return;
481 : }
482 :
483 5593 : bool failed_flag = false;
484 5593 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
485 5593 : if (failed_flag)
486 : {
487 3 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
488 3 : return;
489 : }
490 5590 : std::vector<TyTy::SubstitutionParamMapping> substitutions
491 5590 : = std::move (result.first);
492 5590 : TyTy::RegionConstraints region_constraints = std::move (result.second);
493 :
494 5590 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
495 :
496 : // resolve each impl_item
497 13669 : for (auto &impl_item : impl_block.get_impl_items ())
498 : {
499 8079 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
500 : }
501 :
502 : // validate the impl items
503 5590 : validate_trait_impl_block (trait_reference, impl_block, self, substitutions);
504 5594 : }
505 :
506 : TyTy::BaseType *
507 3279 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
508 : HIR::ImplItem &item)
509 : {
510 3279 : bool failed_flag = false;
511 3279 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
512 3279 : if (failed_flag)
513 : {
514 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
515 : }
516 :
517 3278 : std::vector<TyTy::SubstitutionParamMapping> substitutions
518 3278 : = std::move (result.first);
519 3278 : TyTy::RegionConstraints region_constraints = std::move (result.second);
520 :
521 3278 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
522 :
523 3278 : return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
524 3279 : }
525 :
526 : void
527 6329 : TypeCheckItem::visit (HIR::Function &function)
528 : {
529 6329 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
530 6329 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
531 6329 : if (function.has_generics ())
532 601 : resolve_generic_params (HIR::Item::ItemKind::Function,
533 : function.get_locus (),
534 601 : function.get_generic_params (), substitutions);
535 :
536 6329 : TyTy::RegionConstraints region_constraints;
537 6375 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
538 : {
539 46 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
540 : }
541 :
542 6329 : TyTy::BaseType *ret_type = nullptr;
543 6329 : if (!function.has_function_return_type ())
544 3225 : ret_type = TyTy::TupleType::get_unit_type ();
545 : else
546 : {
547 3104 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
548 3104 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
549 : {
550 3 : rust_error_at (function.get_locus (),
551 : "failed to resolve return type");
552 3 : return;
553 : }
554 :
555 3101 : ret_type = resolved->clone ();
556 3101 : ret_type->set_ref (
557 3101 : function.get_return_type ().get_mappings ().get_hirid ());
558 : }
559 :
560 6326 : std::vector<TyTy::FnParam> params;
561 8233 : for (auto ¶m : function.get_function_params ())
562 : {
563 : // get the name as well required for later on
564 1907 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
565 1907 : context->insert_type (param.get_mappings (), param_tyty);
566 1907 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
567 1907 : params.emplace_back (param.get_param_name ().clone_pattern (),
568 : param_tyty);
569 : }
570 :
571 6326 : auto &nr_ctx
572 6326 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
573 :
574 6326 : CanonicalPath path
575 6326 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
576 :
577 6326 : RustIdent ident{path, function.get_locus ()};
578 :
579 6326 : auto fn_type = new TyTy::FnType (
580 6326 : function.get_mappings ().get_hirid (),
581 6326 : function.get_mappings ().get_defid (),
582 6326 : function.get_function_name ().as_string (), ident,
583 : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
584 : std::move (substitutions),
585 12652 : TyTy::SubstitutionArgumentMappings::empty (
586 6326 : context->get_lifetime_resolver ().get_num_bound_regions ()),
587 25304 : region_constraints);
588 :
589 6326 : context->insert_type (function.get_mappings (), fn_type);
590 :
591 : // need to get the return type from this
592 6326 : TyTy::FnType *resolved_fn_type = fn_type;
593 6326 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
594 6326 : context->push_return_type (TypeCheckContextItem (&function),
595 : expected_ret_tyty);
596 :
597 6326 : context->switch_to_fn_body ();
598 6326 : auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
599 :
600 : // emit check for
601 : // error[E0121]: the type placeholder `_` is not allowed within types on item
602 6326 : const auto placeholder = ret_type->contains_infer ();
603 6326 : if (placeholder != nullptr && function.has_return_type ())
604 : {
605 : // FIXME
606 : // this will be a great place for the Default Hir Visitor we want to
607 : // grab the locations of the placeholders (HIR::InferredType) their
608 : // location, for now maybe we can use their hirid to lookup the location
609 3 : location_t placeholder_locus
610 3 : = mappings.lookup_location (placeholder->get_ref ());
611 3 : location_t type_locus = function.get_return_type ().get_locus ();
612 3 : rich_location r (line_table, placeholder_locus);
613 :
614 3 : bool have_expected_type
615 6 : = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
616 3 : if (!have_expected_type)
617 : {
618 0 : r.add_range (type_locus);
619 : }
620 : else
621 : {
622 3 : std::string fixit
623 3 : = "replace with the correct type " + block_expr_ty->get_name ();
624 3 : r.add_fixit_replace (type_locus, fixit.c_str ());
625 3 : }
626 :
627 3 : rust_error_at (r, ErrorCode::E0121,
628 : "the type placeholder %<_%> is not allowed within types "
629 : "on item signatures");
630 3 : }
631 :
632 6326 : location_t fn_return_locus = function.has_function_return_type ()
633 6326 : ? function.get_return_type ().get_locus ()
634 3225 : : function.get_locus ();
635 12652 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
636 6326 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
637 6326 : TyTy::TyWithLocation (block_expr_ty),
638 6326 : function.get_definition ().get_locus ());
639 :
640 6326 : context->pop_return_type ();
641 :
642 6326 : infered = fn_type;
643 12655 : }
644 :
645 : void
646 1202 : TypeCheckItem::visit (HIR::Module &module)
647 : {
648 5124 : for (auto &item : module.get_items ())
649 3923 : TypeCheckItem::Resolve (*item);
650 1201 : }
651 :
652 : void
653 4045 : TypeCheckItem::visit (HIR::Trait &trait)
654 : {
655 4045 : if (trait.has_type_param_bounds ())
656 : {
657 1625 : for (auto &tp_bound : trait.get_type_param_bounds ())
658 : {
659 886 : if (tp_bound.get ()->get_bound_type ()
660 : == HIR::TypeParamBound::BoundType::TRAITBOUND)
661 : {
662 886 : HIR::TraitBound &tb
663 886 : = static_cast<HIR::TraitBound &> (*tp_bound.get ());
664 886 : if (tb.get_polarity () == BoundPolarity::AntiBound)
665 : {
666 1 : rust_error_at (tb.get_locus (),
667 : "%<?Trait%> is not permitted in supertraits");
668 : }
669 : }
670 : }
671 : }
672 :
673 4045 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
674 4045 : if (trait_ref->is_error ())
675 : {
676 4 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
677 4 : return;
678 : }
679 :
680 4041 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
681 4041 : infered = new TyTy::DynamicObjectType (
682 4041 : trait.get_mappings ().get_hirid (), ident,
683 : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
684 12123 : trait.get_locus ())});
685 4041 : }
686 :
687 : void
688 1444 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
689 : {
690 3632 : for (auto &item : extern_block.get_extern_items ())
691 : {
692 2189 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
693 : }
694 1443 : }
695 :
696 : void
697 0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
698 : {
699 0 : if (extern_crate.references_self ())
700 : return;
701 :
702 0 : auto &mappings = Analysis::Mappings::get ();
703 0 : CrateNum num
704 0 : = mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
705 0 : .value ();
706 0 : HIR::Crate &crate = mappings.get_hir_crate (num);
707 :
708 0 : CrateNum saved_crate_num = mappings.get_current_crate ();
709 0 : mappings.set_current_crate (num);
710 0 : for (auto &item : crate.get_items ())
711 0 : TypeCheckItem::Resolve (*item);
712 0 : mappings.set_current_crate (saved_crate_num);
713 : }
714 :
715 : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
716 41264 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
717 : bool &failure_flag)
718 : {
719 41264 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
720 41264 : if (impl_block.has_generics ())
721 5933 : resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
722 5933 : impl_block.get_generic_params (), substitutions);
723 :
724 41264 : TyTy::RegionConstraints region_constraints;
725 41778 : for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
726 : {
727 514 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
728 : }
729 :
730 41264 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
731 41264 : TraitReference *trait_reference = &TraitReference::error_node ();
732 41264 : if (impl_block.has_trait_ref ())
733 : {
734 30475 : auto &ref = impl_block.get_trait_ref ();
735 30475 : trait_reference = TraitResolver::Resolve (ref);
736 30475 : rust_assert (!trait_reference->is_error ());
737 :
738 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
739 : // for example
740 60950 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
741 30475 : impl_block.get_polarity ());
742 : }
743 :
744 41264 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
745 41264 : if (self->is<TyTy::ErrorType> ())
746 : {
747 : // we cannot check for unconstrained type arguments when the Self type is
748 : // not resolved it will just add extra errors that dont help as well as
749 : // the case where this could just be a recursive type query that should
750 : // fail and will work later on anyway
751 1 : return {substitutions, region_constraints};
752 : }
753 :
754 : // inherit the bounds
755 41263 : if (!specified_bound.is_error ())
756 60942 : self->inherit_bounds ({specified_bound});
757 :
758 : // check for any unconstrained type-params
759 41263 : const TyTy::SubstitutionArgumentMappings trait_constraints
760 41263 : = specified_bound.get_substitution_arguments ();
761 41263 : const TyTy::SubstitutionArgumentMappings impl_constraints
762 41263 : = GetUsedSubstArgs::From (self);
763 :
764 41263 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
765 : impl_constraints, self);
766 :
767 41263 : return {substitutions, region_constraints};
768 82528 : }
769 :
770 : void
771 5590 : TypeCheckItem::validate_trait_impl_block (
772 : TraitReference *trait_reference, HIR::ImplBlock &impl_block,
773 : TyTy::BaseType *self,
774 : std::vector<TyTy::SubstitutionParamMapping> &substitutions)
775 : {
776 5590 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
777 5590 : if (impl_block.has_trait_ref ())
778 : {
779 4651 : auto &ref = impl_block.get_trait_ref ();
780 4651 : trait_reference = TraitResolver::Resolve (ref);
781 4651 : if (trait_reference->is_error ())
782 0 : return;
783 :
784 : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
785 : // for example
786 9302 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
787 4651 : impl_block.get_polarity ());
788 :
789 : // need to check that if this specified bound has super traits does this
790 : // Self
791 : // implement them?
792 4651 : specified_bound.validate_type_implements_super_traits (
793 4651 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
794 : }
795 :
796 5590 : bool is_trait_impl_block = !trait_reference->is_error ();
797 5590 : std::vector<const TraitItemReference *> trait_item_refs;
798 13669 : for (auto &impl_item : impl_block.get_impl_items ())
799 : {
800 8079 : if (!specified_bound.is_error ())
801 : {
802 5351 : auto trait_item_ref
803 5351 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
804 : specified_bound,
805 5351 : substitutions);
806 5351 : if (!trait_item_ref.is_error ())
807 5347 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
808 5351 : }
809 : }
810 :
811 5590 : bool impl_block_missing_trait_items
812 5590 : = !specified_bound.is_error ()
813 5590 : && trait_reference->size () != trait_item_refs.size ();
814 1603 : if (impl_block_missing_trait_items
815 1603 : && impl_block.get_polarity () == BoundPolarity::RegularBound)
816 : {
817 : // filter the missing impl_items
818 1601 : std::vector<std::reference_wrapper<const TraitItemReference>>
819 1601 : missing_trait_items;
820 5084 : for (const auto &trait_item_ref : trait_reference->get_trait_items ())
821 : {
822 3483 : bool found = false;
823 5361 : for (auto implemented_trait_item : trait_item_refs)
824 : {
825 3313 : std::string trait_item_name = trait_item_ref.get_identifier ();
826 3313 : std::string impl_item_name
827 3313 : = implemented_trait_item->get_identifier ();
828 3313 : found = trait_item_name == impl_item_name;
829 3313 : if (found)
830 : break;
831 3313 : }
832 :
833 3483 : bool is_required_trait_item = !trait_item_ref.is_optional ();
834 3483 : if (!found && is_required_trait_item)
835 6 : missing_trait_items.emplace_back (trait_item_ref);
836 : }
837 :
838 1601 : if (!missing_trait_items.empty ())
839 : {
840 4 : std::string missing_items_buf;
841 4 : rich_location r (line_table, impl_block.get_locus ());
842 10 : for (size_t i = 0; i < missing_trait_items.size (); i++)
843 : {
844 6 : bool has_more = (i + 1) < missing_trait_items.size ();
845 6 : const TraitItemReference &missing_trait_item
846 6 : = missing_trait_items.at (i);
847 6 : missing_items_buf += missing_trait_item.get_identifier ()
848 18 : + (has_more ? ", " : "");
849 6 : r.add_range (missing_trait_item.get_locus ());
850 : }
851 :
852 4 : rust_error_at (r, ErrorCode::E0046,
853 : "missing %s in implementation of trait %qs",
854 : missing_items_buf.c_str (),
855 4 : trait_reference->get_name ().c_str ());
856 4 : }
857 1601 : }
858 :
859 5590 : if (is_trait_impl_block)
860 : {
861 4651 : trait_reference->clear_associated_types ();
862 :
863 4651 : AssociatedImplTrait associated (trait_reference, specified_bound,
864 4651 : &impl_block, self, context);
865 4651 : context->insert_associated_trait_impl (
866 4651 : impl_block.get_mappings ().get_hirid (), std::move (associated));
867 4651 : context->insert_associated_impl_mapping (
868 4651 : trait_reference->get_mappings ().get_hirid (), self,
869 4651 : impl_block.get_mappings ().get_hirid ());
870 4651 : }
871 5590 : }
872 :
873 : TyTy::BaseType *
874 41258 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
875 : {
876 41258 : return TypeCheckType::Resolve (impl_block.get_type ());
877 : }
878 :
879 : } // namespace Resolver
880 : } // namespace Rust
|