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