Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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 : 57746 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
41 : :
42 : : TyTy::BaseType *
43 : 26913 : TypeCheckItem::Resolve (HIR::Item &item)
44 : : {
45 : : // is it already resolved?
46 : 26913 : auto context = TypeCheckContext::get ();
47 : 26913 : TyTy::BaseType *resolved = nullptr;
48 : 26913 : bool already_resolved
49 : 26913 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
50 : 26913 : if (already_resolved)
51 : 4838 : return resolved;
52 : :
53 : 22075 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
54 : 22075 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
55 : :
56 : 22075 : TypeCheckItem resolver;
57 : 22075 : vis_item.accept_vis (resolver);
58 : 22073 : return resolver.infered;
59 : 22073 : }
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 : 47 : TypeCheckItem::visit (HIR::TypeAlias &alias)
160 : : {
161 : 47 : TyTy::BaseType *actual_type
162 : 47 : = TypeCheckType::Resolve (alias.get_type_aliased ());
163 : :
164 : 47 : context->insert_type (alias.get_mappings (), actual_type);
165 : :
166 : 47 : TyTy::RegionConstraints region_constraints;
167 : 47 : for (auto &where_clause_item : alias.get_where_clause ().get_items ())
168 : : {
169 : 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
170 : : }
171 : 47 : infered = actual_type;
172 : 47 : }
173 : :
174 : : void
175 : 946 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
176 : : {
177 : 946 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
178 : :
179 : 946 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
180 : 946 : 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 : 946 : TyTy::RegionConstraints region_constraints;
186 : 946 : 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 : 946 : std::vector<TyTy::StructFieldType *> fields;
192 : 946 : size_t idx = 0;
193 : 2544 : for (auto &field : struct_decl.get_fields ())
194 : : {
195 : 1598 : TyTy::BaseType *field_type
196 : 1598 : = TypeCheckType::Resolve (field.get_field_type ());
197 : 1598 : auto *ty_field
198 : 3196 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
199 : 1598 : std::to_string (idx), field_type,
200 : 1598 : field.get_locus ());
201 : 1598 : fields.push_back (ty_field);
202 : 1598 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
203 : 1598 : idx++;
204 : : }
205 : :
206 : : // get the path
207 : :
208 : 946 : auto &nr_ctx
209 : 946 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
210 : :
211 : 946 : CanonicalPath path
212 : 946 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
213 : :
214 : 946 : RustIdent ident{path, struct_decl.get_locus ()};
215 : :
216 : : // its a single variant ADT
217 : 946 : std::vector<TyTy::VariantDef *> variants;
218 : 946 : variants.push_back (
219 : 946 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
220 : 946 : struct_decl.get_mappings ().get_defid (),
221 : 946 : struct_decl.get_identifier ().as_string (), ident,
222 : 1892 : TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
223 : 2838 : std::move (fields)));
224 : :
225 : : // Process #[repr(X)] attribute, if any
226 : 946 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
227 : 946 : TyTy::ADTType::ReprOptions repr
228 : 946 : = parse_repr_options (attrs, struct_decl.get_locus ());
229 : :
230 : 946 : auto *type = new TyTy::ADTType (
231 : 946 : struct_decl.get_mappings ().get_defid (),
232 : 946 : struct_decl.get_mappings ().get_hirid (),
233 : 946 : struct_decl.get_mappings ().get_hirid (),
234 : 946 : struct_decl.get_identifier ().as_string (), ident,
235 : : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
236 : : std::move (substitutions), repr,
237 : 1892 : TyTy::SubstitutionArgumentMappings::empty (
238 : 946 : context->get_lifetime_resolver ().get_num_bound_regions ()),
239 : 3784 : region_constraints);
240 : :
241 : 946 : context->insert_type (struct_decl.get_mappings (), type);
242 : 946 : infered = type;
243 : :
244 : 946 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
245 : 1892 : }
246 : :
247 : : void
248 : 1491 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
249 : : {
250 : 1491 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
251 : :
252 : 1491 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
253 : 1491 : 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 : 1491 : TyTy::RegionConstraints region_constraints;
259 : 1495 : 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 : 1491 : std::vector<TyTy::StructFieldType *> fields;
265 : 3298 : for (auto &field : struct_decl.get_fields ())
266 : : {
267 : 1807 : TyTy::BaseType *field_type
268 : 1807 : = TypeCheckType::Resolve (field.get_field_type ());
269 : 1807 : auto *ty_field
270 : 1807 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
271 : 1807 : field.get_field_name ().as_string (),
272 : 3614 : field_type, field.get_locus ());
273 : 1807 : fields.push_back (ty_field);
274 : 1807 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
275 : : }
276 : :
277 : 1491 : auto &nr_ctx
278 : 1491 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
279 : :
280 : 1491 : CanonicalPath path
281 : 1491 : = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid ());
282 : :
283 : 1491 : RustIdent ident{path, struct_decl.get_locus ()};
284 : :
285 : : // its a single variant ADT
286 : 1491 : std::vector<TyTy::VariantDef *> variants;
287 : 1491 : variants.push_back (
288 : 1491 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
289 : 1491 : struct_decl.get_mappings ().get_defid (),
290 : 1491 : struct_decl.get_identifier ().as_string (), ident,
291 : 2982 : TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
292 : 4473 : std::move (fields)));
293 : :
294 : : // Process #[repr(X)] attribute, if any
295 : 1491 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
296 : 1491 : TyTy::ADTType::ReprOptions repr
297 : 1491 : = parse_repr_options (attrs, struct_decl.get_locus ());
298 : :
299 : 1491 : auto *type = new TyTy::ADTType (
300 : 1491 : struct_decl.get_mappings ().get_defid (),
301 : 1491 : struct_decl.get_mappings ().get_hirid (),
302 : 1491 : struct_decl.get_mappings ().get_hirid (),
303 : 1491 : struct_decl.get_identifier ().as_string (), ident,
304 : : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
305 : : std::move (substitutions), repr,
306 : 2982 : TyTy::SubstitutionArgumentMappings::empty (
307 : 1491 : context->get_lifetime_resolver ().get_num_bound_regions ()),
308 : 5964 : region_constraints);
309 : :
310 : 1491 : context->insert_type (struct_decl.get_mappings (), type);
311 : 1491 : infered = type;
312 : :
313 : 1491 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
314 : 2982 : }
315 : :
316 : : void
317 : 511 : TypeCheckItem::visit (HIR::Enum &enum_decl)
318 : : {
319 : 511 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
320 : 511 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
321 : 511 : 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 : 511 : const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
327 : 511 : TyTy::ADTType::ReprOptions repr
328 : 511 : = parse_repr_options (attrs, enum_decl.get_locus ());
329 : :
330 : 511 : std::vector<TyTy::VariantDef *> variants;
331 : 511 : int64_t discriminant_value = 0;
332 : 1705 : for (auto &variant : enum_decl.get_variants ())
333 : : {
334 : 1194 : TyTy::VariantDef *field_type
335 : 1194 : = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
336 : :
337 : 1194 : discriminant_value++;
338 : 1194 : variants.push_back (field_type);
339 : : }
340 : :
341 : : // Check for zero-variant enum compatibility
342 : 511 : 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 : 509 : auto &nr_ctx
354 : 509 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
355 : :
356 : : // get the path
357 : 509 : CanonicalPath canonical_path
358 : 509 : = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid ());
359 : :
360 : 509 : RustIdent ident{canonical_path, enum_decl.get_locus ()};
361 : :
362 : : // multi variant ADT
363 : 509 : auto *type
364 : 509 : = new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
365 : 509 : enum_decl.get_mappings ().get_hirid (),
366 : 509 : enum_decl.get_mappings ().get_hirid (),
367 : 509 : enum_decl.get_identifier ().as_string (), ident,
368 : : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
369 : 1527 : std::move (substitutions), repr);
370 : :
371 : 509 : context->insert_type (enum_decl.get_mappings (), type);
372 : 509 : infered = type;
373 : :
374 : 509 : context->get_variance_analysis_ctx ().add_type_constraints (*type);
375 : 511 : }
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 : 51 : TypeCheckItem::visit (HIR::StaticItem &var)
440 : : {
441 : 51 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
442 : 51 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
443 : :
444 : 51 : TyTy::BaseType *unified
445 : 51 : = coercion_site (var.get_mappings ().get_hirid (),
446 : 51 : TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
447 : : TyTy::TyWithLocation (expr_type,
448 : 51 : var.get_expr ().get_locus ()),
449 : : var.get_locus ());
450 : 51 : context->insert_type (var.get_mappings (), unified);
451 : 51 : infered = unified;
452 : 51 : }
453 : :
454 : : void
455 : 403 : TypeCheckItem::visit (HIR::ConstantItem &constant)
456 : : {
457 : 403 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
458 : 403 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
459 : :
460 : 806 : TyTy::BaseType *unified = unify_site (
461 : 403 : constant.get_mappings ().get_hirid (),
462 : 403 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
463 : 403 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
464 : : constant.get_locus ());
465 : 403 : context->insert_type (constant.get_mappings (), unified);
466 : 403 : infered = unified;
467 : 403 : }
468 : :
469 : : void
470 : 5585 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
471 : : {
472 : 5585 : auto binder_pin = context->push_clean_lifetime_resolver (true);
473 : :
474 : 5585 : TraitReference *trait_reference = &TraitReference::error_node ();
475 : 5585 : if (impl_block.has_trait_ref ())
476 : : {
477 : 4644 : HIR::TypePath &ref = impl_block.get_trait_ref ();
478 : 4644 : trait_reference = TraitResolver::Resolve (ref);
479 : 4644 : if (trait_reference->is_error ())
480 : : return;
481 : : }
482 : :
483 : 5584 : bool failed_flag = false;
484 : 5584 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
485 : 5584 : if (failed_flag)
486 : : {
487 : 3 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
488 : 3 : return;
489 : : }
490 : 5581 : std::vector<TyTy::SubstitutionParamMapping> substitutions
491 : 5581 : = std::move (result.first);
492 : 5581 : TyTy::RegionConstraints region_constraints = std::move (result.second);
493 : :
494 : 5581 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
495 : :
496 : : // resolve each impl_item
497 : 13649 : for (auto &impl_item : impl_block.get_impl_items ())
498 : : {
499 : 8068 : TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
500 : : }
501 : :
502 : : // validate the impl items
503 : 5581 : validate_trait_impl_block (trait_reference, impl_block, self, substitutions);
504 : 5585 : }
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 : 6273 : TypeCheckItem::visit (HIR::Function &function)
528 : : {
529 : 6273 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
530 : 6273 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
531 : 6273 : if (function.has_generics ())
532 : 599 : resolve_generic_params (HIR::Item::ItemKind::Function,
533 : : function.get_locus (),
534 : 599 : function.get_generic_params (), substitutions);
535 : :
536 : 6273 : TyTy::RegionConstraints region_constraints;
537 : 6319 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
538 : : {
539 : 46 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
540 : : }
541 : :
542 : 6273 : TyTy::BaseType *ret_type = nullptr;
543 : 6273 : if (!function.has_function_return_type ())
544 : 3196 : ret_type = TyTy::TupleType::get_unit_type ();
545 : : else
546 : : {
547 : 3077 : auto resolved = TypeCheckType::Resolve (function.get_return_type ());
548 : 3077 : 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 : 3074 : ret_type = resolved->clone ();
556 : 3074 : ret_type->set_ref (
557 : 3074 : function.get_return_type ().get_mappings ().get_hirid ());
558 : : }
559 : :
560 : 6270 : std::vector<TyTy::FnParam> params;
561 : 8172 : for (auto ¶m : function.get_function_params ())
562 : : {
563 : : // get the name as well required for later on
564 : 1902 : auto param_tyty = TypeCheckType::Resolve (param.get_type ());
565 : 1902 : context->insert_type (param.get_mappings (), param_tyty);
566 : 1902 : TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
567 : 1902 : params.emplace_back (param.get_param_name ().clone_pattern (),
568 : : param_tyty);
569 : : }
570 : :
571 : 6270 : auto &nr_ctx
572 : 6270 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
573 : :
574 : 6270 : CanonicalPath path
575 : 6270 : = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid ());
576 : :
577 : 6270 : RustIdent ident{path, function.get_locus ()};
578 : :
579 : 6270 : auto fn_type = new TyTy::FnType (
580 : 6270 : function.get_mappings ().get_hirid (),
581 : 6270 : function.get_mappings ().get_defid (),
582 : 6270 : 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 : 12540 : TyTy::SubstitutionArgumentMappings::empty (
586 : 6270 : context->get_lifetime_resolver ().get_num_bound_regions ()),
587 : 25080 : region_constraints);
588 : :
589 : 6270 : context->insert_type (function.get_mappings (), fn_type);
590 : :
591 : : // need to get the return type from this
592 : 6270 : TyTy::FnType *resolved_fn_type = fn_type;
593 : 6270 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
594 : 6270 : context->push_return_type (TypeCheckContextItem (&function),
595 : : expected_ret_tyty);
596 : :
597 : 6270 : context->switch_to_fn_body ();
598 : 6270 : 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 : 6270 : const auto placeholder = ret_type->contains_infer ();
603 : 6270 : 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 : 6270 : location_t fn_return_locus = function.has_function_return_type ()
633 : 6270 : ? function.get_return_type ().get_locus ()
634 : 3196 : : function.get_locus ();
635 : 12540 : coercion_site (function.get_definition ().get_mappings ().get_hirid (),
636 : 6270 : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
637 : 6270 : TyTy::TyWithLocation (block_expr_ty),
638 : 6270 : function.get_definition ().get_locus ());
639 : :
640 : 6270 : context->pop_return_type ();
641 : :
642 : 6270 : infered = fn_type;
643 : 12543 : }
644 : :
645 : : void
646 : 1199 : TypeCheckItem::visit (HIR::Module &module)
647 : : {
648 : 5120 : for (auto &item : module.get_items ())
649 : 3922 : TypeCheckItem::Resolve (*item);
650 : 1198 : }
651 : :
652 : : void
653 : 4027 : TypeCheckItem::visit (HIR::Trait &trait)
654 : : {
655 : 4027 : 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 : 4027 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
674 : 4027 : if (trait_ref->is_error ())
675 : : {
676 : 4 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
677 : 4 : return;
678 : : }
679 : :
680 : 4023 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
681 : 4023 : infered = new TyTy::DynamicObjectType (
682 : 4023 : trait.get_mappings ().get_hirid (), ident,
683 : : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
684 : 12069 : trait.get_locus ())});
685 : 4023 : }
686 : :
687 : : void
688 : 1442 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
689 : : {
690 : 3628 : for (auto &item : extern_block.get_extern_items ())
691 : : {
692 : 2187 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
693 : : }
694 : 1441 : }
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 : 41255 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
717 : : bool &failure_flag)
718 : : {
719 : 41255 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
720 : 41255 : 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 : 41255 : TyTy::RegionConstraints region_constraints;
725 : 41769 : 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 : 41255 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
731 : 41255 : TraitReference *trait_reference = &TraitReference::error_node ();
732 : 41255 : if (impl_block.has_trait_ref ())
733 : : {
734 : 30466 : auto &ref = impl_block.get_trait_ref ();
735 : 30466 : trait_reference = TraitResolver::Resolve (ref);
736 : 30466 : 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 : 60932 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
741 : 30466 : impl_block.get_polarity ());
742 : : }
743 : :
744 : 41255 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
745 : 41255 : 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 : 41254 : if (!specified_bound.is_error ())
756 : 60924 : self->inherit_bounds ({specified_bound});
757 : :
758 : : // check for any unconstrained type-params
759 : 41254 : const TyTy::SubstitutionArgumentMappings trait_constraints
760 : 41254 : = specified_bound.get_substitution_arguments ();
761 : 41254 : const TyTy::SubstitutionArgumentMappings impl_constraints
762 : 41254 : = GetUsedSubstArgs::From (self);
763 : :
764 : 41254 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
765 : : impl_constraints, self);
766 : :
767 : 41254 : return {substitutions, region_constraints};
768 : 82510 : }
769 : :
770 : : void
771 : 5581 : 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 : 5581 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
777 : 5581 : if (impl_block.has_trait_ref ())
778 : : {
779 : 4642 : auto &ref = impl_block.get_trait_ref ();
780 : 4642 : trait_reference = TraitResolver::Resolve (ref);
781 : 4642 : 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 : 9284 : specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
787 : 4642 : 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 : 4642 : specified_bound.validate_type_implements_super_traits (
793 : 4642 : *self, impl_block.get_type (), impl_block.get_trait_ref ());
794 : : }
795 : :
796 : 5581 : bool is_trait_impl_block = !trait_reference->is_error ();
797 : 5581 : std::vector<const TraitItemReference *> trait_item_refs;
798 : 13649 : for (auto &impl_item : impl_block.get_impl_items ())
799 : : {
800 : 8068 : if (!specified_bound.is_error ())
801 : : {
802 : 5340 : auto trait_item_ref
803 : 5340 : = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
804 : : specified_bound,
805 : 5340 : substitutions);
806 : 5340 : if (!trait_item_ref.is_error ())
807 : 5336 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
808 : 5340 : }
809 : : }
810 : :
811 : 5581 : bool impl_block_missing_trait_items
812 : 5581 : = !specified_bound.is_error ()
813 : 5581 : && 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 : 5581 : if (is_trait_impl_block)
860 : : {
861 : 4642 : trait_reference->clear_associated_types ();
862 : :
863 : 4642 : AssociatedImplTrait associated (trait_reference, specified_bound,
864 : 4642 : &impl_block, self, context);
865 : 4642 : context->insert_associated_trait_impl (
866 : 4642 : impl_block.get_mappings ().get_hirid (), std::move (associated));
867 : 4642 : context->insert_associated_impl_mapping (
868 : 4642 : trait_reference->get_mappings ().get_hirid (), self,
869 : 4642 : impl_block.get_mappings ().get_hirid ());
870 : 4642 : }
871 : 5581 : }
872 : :
873 : : TyTy::BaseType *
874 : 41249 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
875 : : {
876 : 41249 : return TypeCheckType::Resolve (impl_block.get_type ());
877 : : }
878 : :
879 : : } // namespace Resolver
880 : : } // namespace Rust
|