Branch data Line data Source code
1 : : // Copyright (C) 2020-2024 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 "rust-hir-type-check-enumitem.h"
21 : : #include "rust-hir-type-check-implitem.h"
22 : : #include "rust-hir-type-check-type.h"
23 : : #include "rust-hir-type-check-expr.h"
24 : : #include "rust-hir-type-check-pattern.h"
25 : : #include "rust-hir-trait-resolve.h"
26 : : #include "rust-substitution-mapper.h"
27 : : #include "rust-type-util.h"
28 : :
29 : : namespace Rust {
30 : : namespace Resolver {
31 : :
32 : 22953 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
33 : :
34 : : TyTy::BaseType *
35 : 14906 : TypeCheckItem::Resolve (HIR::Item &item)
36 : : {
37 : : // is it already resolved?
38 : 14906 : auto context = TypeCheckContext::get ();
39 : 14906 : TyTy::BaseType *resolved = nullptr;
40 : 14906 : bool already_resolved
41 : 14906 : = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
42 : 14906 : if (already_resolved)
43 : 925 : return resolved;
44 : :
45 : 13981 : rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
46 : 13981 : HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
47 : :
48 : 13981 : TypeCheckItem resolver;
49 : 13981 : vis_item.accept_vis (resolver);
50 : 13977 : return resolver.infered;
51 : 13977 : }
52 : :
53 : : TyTy::BaseType *
54 : 1392 : TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
55 : : {
56 : 1392 : TypeCheckItem resolver;
57 : 1392 : return resolver.resolve_impl_item (impl_block, item);
58 : 1392 : }
59 : :
60 : : TyTy::BaseType *
61 : 5967 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
62 : : {
63 : 5967 : TypeCheckItem resolver;
64 : :
65 : 5967 : bool failed_flag = false;
66 : 5967 : auto result
67 : 5967 : = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
68 : 5967 : if (failed_flag)
69 : : {
70 : 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
71 : : }
72 : 5966 : std::vector<TyTy::SubstitutionParamMapping> substitutions
73 : 5966 : = std::move (result.first);
74 : 5966 : TyTy::RegionConstraints region_constraints = std::move (result.second);
75 : :
76 : 5966 : return resolver.resolve_impl_block_self (impl_block);
77 : 5967 : }
78 : :
79 : : TyTy::BaseType *
80 : 1613 : TypeCheckItem::ResolveImplBlockSelfWithInference (
81 : : HIR::ImplBlock &impl, location_t locus,
82 : : TyTy::SubstitutionArgumentMappings *infer_arguments)
83 : : {
84 : 1613 : TypeCheckItem resolver;
85 : :
86 : 1613 : bool failed_flag = false;
87 : 1613 : auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
88 : 1613 : if (failed_flag)
89 : : {
90 : 1 : return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
91 : : }
92 : 1612 : std::vector<TyTy::SubstitutionParamMapping> substitutions
93 : 1612 : = std::move (result.first);
94 : 1612 : TyTy::RegionConstraints region_constraints = std::move (result.second);
95 : :
96 : : // now that we have the param mappings we need to query the self type
97 : 1612 : TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
98 : :
99 : : // nothing to do
100 : 1612 : if (substitutions.empty () || self->is_concrete ())
101 : 1063 : return self;
102 : :
103 : : // generate inference variables for the subst-param-mappings
104 : 549 : std::vector<TyTy::SubstitutionArg> args;
105 : 1156 : for (auto &p : substitutions)
106 : : {
107 : 607 : if (p.needs_substitution ())
108 : : {
109 : 607 : TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
110 : 607 : args.push_back (TyTy::SubstitutionArg (&p, infer_var.get_tyty ()));
111 : : }
112 : : else
113 : : {
114 : 0 : TyTy::ParamType *param = p.get_param_ty ();
115 : 0 : TyTy::BaseType *resolved = param->destructure ();
116 : 0 : args.push_back (TyTy::SubstitutionArg (&p, resolved));
117 : : }
118 : : }
119 : :
120 : : // create argument mappings
121 : 1098 : *infer_arguments = TyTy::SubstitutionArgumentMappings (
122 : : std::move (args), {},
123 : 1098 : TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
124 : : infer_arguments),
125 : 549 : locus);
126 : :
127 : 549 : TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
128 : :
129 : : // we only need to apply to the bounds manually on types which dont bind
130 : : // generics
131 : 549 : if (!infer->has_substitutions_defined ())
132 : : {
133 : 464 : for (auto &bound : infer->get_specified_bounds ())
134 : 96 : bound.handle_substitions (*infer_arguments);
135 : : }
136 : :
137 : 549 : return infer;
138 : 2162 : }
139 : :
140 : : void
141 : 33 : TypeCheckItem::visit (HIR::TypeAlias &alias)
142 : : {
143 : 33 : TyTy::BaseType *actual_type
144 : 33 : = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
145 : :
146 : 33 : context->insert_type (alias.get_mappings (), actual_type);
147 : :
148 : 33 : TyTy::RegionConstraints region_constraints;
149 : 33 : for (auto &where_clause_item : alias.get_where_clause ().get_items ())
150 : : {
151 : 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
152 : : }
153 : 33 : infered = actual_type;
154 : 33 : }
155 : :
156 : : void
157 : 754 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
158 : : {
159 : 754 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
160 : :
161 : 754 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
162 : 754 : if (struct_decl.has_generics ())
163 : 279 : resolve_generic_params (struct_decl.get_generic_params (), substitutions);
164 : :
165 : 754 : TyTy::RegionConstraints region_constraints;
166 : 754 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
167 : : {
168 : 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
169 : : }
170 : :
171 : 754 : std::vector<TyTy::StructFieldType *> fields;
172 : 754 : size_t idx = 0;
173 : 2024 : for (auto &field : struct_decl.get_fields ())
174 : : {
175 : 1270 : TyTy::BaseType *field_type
176 : 1270 : = TypeCheckType::Resolve (field.get_field_type ().get ());
177 : 1270 : auto *ty_field
178 : 2540 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
179 : 1270 : std::to_string (idx), field_type,
180 : 1270 : field.get_locus ());
181 : 1270 : fields.push_back (ty_field);
182 : 1270 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
183 : 1270 : idx++;
184 : : }
185 : :
186 : : // get the path
187 : 754 : const CanonicalPath *canonical_path = nullptr;
188 : 754 : bool ok = mappings->lookup_canonical_path (
189 : 754 : struct_decl.get_mappings ().get_nodeid (), &canonical_path);
190 : 754 : rust_assert (ok);
191 : 754 : RustIdent ident{*canonical_path, struct_decl.get_locus ()};
192 : :
193 : : // its a single variant ADT
194 : 754 : std::vector<TyTy::VariantDef *> variants;
195 : 754 : variants.push_back (
196 : 754 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
197 : 754 : struct_decl.get_mappings ().get_defid (),
198 : 754 : struct_decl.get_identifier ().as_string (), ident,
199 : : TyTy::VariantDef::VariantType::TUPLE, nullptr,
200 : 1508 : std::move (fields)));
201 : :
202 : : // Process #[repr(X)] attribute, if any
203 : 754 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
204 : 754 : TyTy::ADTType::ReprOptions repr
205 : 754 : = parse_repr_options (attrs, struct_decl.get_locus ());
206 : :
207 : 754 : TyTy::BaseType *type = new TyTy::ADTType (
208 : 1508 : struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
209 : 754 : struct_decl.get_identifier ().as_string (), ident,
210 : : TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
211 : : std::move (substitutions), repr,
212 : 1508 : TyTy::SubstitutionArgumentMappings::empty (
213 : 754 : context->get_lifetime_resolver ().get_num_bound_regions ()),
214 : 2262 : region_constraints);
215 : :
216 : 754 : context->insert_type (struct_decl.get_mappings (), type);
217 : 754 : infered = type;
218 : 1508 : }
219 : :
220 : : void
221 : 913 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
222 : : {
223 : 913 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
224 : :
225 : 913 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
226 : 913 : if (struct_decl.has_generics ())
227 : 240 : resolve_generic_params (struct_decl.get_generic_params (), substitutions);
228 : :
229 : 913 : TyTy::RegionConstraints region_constraints;
230 : 917 : for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
231 : : {
232 : 4 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
233 : : }
234 : :
235 : 913 : std::vector<TyTy::StructFieldType *> fields;
236 : 2204 : for (auto &field : struct_decl.get_fields ())
237 : : {
238 : 1291 : TyTy::BaseType *field_type
239 : 1291 : = TypeCheckType::Resolve (field.get_field_type ().get ());
240 : 1291 : auto *ty_field
241 : 1291 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
242 : 1291 : field.get_field_name ().as_string (),
243 : 1291 : field_type, field.get_locus ());
244 : 1291 : fields.push_back (ty_field);
245 : 1291 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
246 : : }
247 : :
248 : : // get the path
249 : 913 : const CanonicalPath *canonical_path = nullptr;
250 : 913 : bool ok = mappings->lookup_canonical_path (
251 : 913 : struct_decl.get_mappings ().get_nodeid (), &canonical_path);
252 : 913 : rust_assert (ok);
253 : 913 : RustIdent ident{*canonical_path, struct_decl.get_locus ()};
254 : :
255 : : // its a single variant ADT
256 : 913 : std::vector<TyTy::VariantDef *> variants;
257 : 913 : variants.push_back (
258 : 913 : new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
259 : 913 : struct_decl.get_mappings ().get_defid (),
260 : 913 : struct_decl.get_identifier ().as_string (), ident,
261 : : TyTy::VariantDef::VariantType::STRUCT, nullptr,
262 : 1826 : std::move (fields)));
263 : :
264 : : // Process #[repr(X)] attribute, if any
265 : 913 : const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
266 : 913 : TyTy::ADTType::ReprOptions repr
267 : 913 : = parse_repr_options (attrs, struct_decl.get_locus ());
268 : :
269 : 913 : TyTy::BaseType *type = new TyTy::ADTType (
270 : 1826 : struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
271 : 913 : struct_decl.get_identifier ().as_string (), ident,
272 : : TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
273 : : std::move (substitutions), repr,
274 : 1826 : TyTy::SubstitutionArgumentMappings::empty (
275 : 913 : context->get_lifetime_resolver ().get_num_bound_regions ()),
276 : 2739 : region_constraints);
277 : :
278 : 913 : context->insert_type (struct_decl.get_mappings (), type);
279 : 913 : infered = type;
280 : 1826 : }
281 : :
282 : : void
283 : 163 : TypeCheckItem::visit (HIR::Enum &enum_decl)
284 : : {
285 : 163 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
286 : 163 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
287 : 163 : if (enum_decl.has_generics ())
288 : 81 : resolve_generic_params (enum_decl.get_generic_params (), substitutions);
289 : :
290 : 163 : std::vector<TyTy::VariantDef *> variants;
291 : 163 : int64_t discriminant_value = 0;
292 : 564 : for (auto &variant : enum_decl.get_variants ())
293 : : {
294 : 401 : TyTy::VariantDef *field_type
295 : 401 : = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value);
296 : :
297 : 401 : discriminant_value++;
298 : 401 : variants.push_back (field_type);
299 : : }
300 : :
301 : : // get the path
302 : 163 : const CanonicalPath *canonical_path = nullptr;
303 : 163 : bool ok
304 : 163 : = mappings->lookup_canonical_path (enum_decl.get_mappings ().get_nodeid (),
305 : : &canonical_path);
306 : 163 : rust_assert (ok);
307 : 163 : RustIdent ident{*canonical_path, enum_decl.get_locus ()};
308 : :
309 : : // multi variant ADT
310 : 163 : TyTy::BaseType *type
311 : 163 : = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
312 : 163 : mappings->get_next_hir_id (),
313 : 163 : enum_decl.get_identifier ().as_string (), ident,
314 : : TyTy::ADTType::ADTKind::ENUM, std::move (variants),
315 : 326 : std::move (substitutions));
316 : :
317 : 163 : context->insert_type (enum_decl.get_mappings (), type);
318 : 163 : infered = type;
319 : 163 : }
320 : :
321 : : void
322 : 90 : TypeCheckItem::visit (HIR::Union &union_decl)
323 : : {
324 : 90 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
325 : 90 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
326 : 90 : if (union_decl.has_generics ())
327 : 65 : resolve_generic_params (union_decl.get_generic_params (), substitutions);
328 : :
329 : 90 : TyTy::RegionConstraints region_constraints;
330 : 90 : for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
331 : : {
332 : 0 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
333 : : }
334 : :
335 : 90 : std::vector<TyTy::StructFieldType *> fields;
336 : 356 : for (auto &variant : union_decl.get_variants ())
337 : : {
338 : 266 : TyTy::BaseType *variant_type
339 : 266 : = TypeCheckType::Resolve (variant.get_field_type ().get ());
340 : 266 : auto *ty_variant
341 : 266 : = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
342 : 266 : variant.get_field_name ().as_string (),
343 : 266 : variant_type, variant.get_locus ());
344 : 266 : fields.push_back (ty_variant);
345 : 266 : context->insert_type (variant.get_mappings (),
346 : : ty_variant->get_field_type ());
347 : : }
348 : :
349 : : // get the path
350 : 90 : const CanonicalPath *canonical_path = nullptr;
351 : 90 : bool ok
352 : 90 : = mappings->lookup_canonical_path (union_decl.get_mappings ().get_nodeid (),
353 : : &canonical_path);
354 : 90 : rust_assert (ok);
355 : 90 : RustIdent ident{*canonical_path, union_decl.get_locus ()};
356 : :
357 : : // there is only a single variant
358 : 90 : std::vector<TyTy::VariantDef *> variants;
359 : 90 : variants.push_back (
360 : 90 : new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
361 : 90 : union_decl.get_mappings ().get_defid (),
362 : 90 : union_decl.get_identifier ().as_string (), ident,
363 : : TyTy::VariantDef::VariantType::STRUCT, nullptr,
364 : 180 : std::move (fields)));
365 : :
366 : 90 : TyTy::BaseType *type
367 : 90 : = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
368 : 90 : mappings->get_next_hir_id (),
369 : 90 : union_decl.get_identifier ().as_string (), ident,
370 : : TyTy::ADTType::ADTKind::UNION, std::move (variants),
371 : 180 : std::move (substitutions));
372 : :
373 : 90 : context->insert_type (union_decl.get_mappings (), type);
374 : 90 : infered = type;
375 : 180 : }
376 : :
377 : : void
378 : 40 : TypeCheckItem::visit (HIR::StaticItem &var)
379 : : {
380 : 40 : TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ().get ());
381 : 40 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ().get ());
382 : :
383 : 40 : TyTy::BaseType *unified
384 : 40 : = coercion_site (var.get_mappings ().get_hirid (),
385 : 40 : TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
386 : : TyTy::TyWithLocation (expr_type,
387 : 40 : var.get_expr ()->get_locus ()),
388 : : var.get_locus ());
389 : 40 : context->insert_type (var.get_mappings (), unified);
390 : 40 : infered = unified;
391 : 40 : }
392 : :
393 : : void
394 : 372 : TypeCheckItem::visit (HIR::ConstantItem &constant)
395 : : {
396 : 372 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
397 : 372 : TyTy::BaseType *expr_type
398 : 372 : = TypeCheckExpr::Resolve (constant.get_expr ().get ());
399 : :
400 : 372 : TyTy::BaseType *unified = unify_site (
401 : 372 : constant.get_mappings ().get_hirid (),
402 : 372 : TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
403 : 372 : TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
404 : : constant.get_locus ());
405 : 372 : context->insert_type (constant.get_mappings (), unified);
406 : 372 : infered = unified;
407 : 372 : }
408 : :
409 : : void
410 : 3002 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
411 : : {
412 : 3002 : auto binder_pin = context->push_clean_lifetime_resolver (true);
413 : :
414 : 3002 : bool failed_flag = false;
415 : 3002 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
416 : 3002 : if (failed_flag)
417 : : {
418 : 2 : infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
419 : 2 : return;
420 : : }
421 : 3000 : std::vector<TyTy::SubstitutionParamMapping> substitutions
422 : 3000 : = std::move (result.first);
423 : 3000 : TyTy::RegionConstraints region_constraints = std::move (result.second);
424 : :
425 : 3000 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
426 : :
427 : : // resolve each impl_item
428 : 7096 : for (auto &impl_item : impl_block.get_impl_items ())
429 : : {
430 : 4096 : TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self,
431 : : substitutions);
432 : : }
433 : :
434 : : // validate the impl items
435 : 3000 : validate_trait_impl_block (impl_block, self, substitutions);
436 : 3002 : }
437 : :
438 : : TyTy::BaseType *
439 : 1392 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
440 : : HIR::ImplItem &item)
441 : : {
442 : 1392 : bool failed_flag = false;
443 : 1392 : auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
444 : 1392 : if (failed_flag)
445 : : {
446 : 1 : return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
447 : : }
448 : :
449 : 1391 : std::vector<TyTy::SubstitutionParamMapping> substitutions
450 : 1391 : = std::move (result.first);
451 : 1391 : TyTy::RegionConstraints region_constraints = std::move (result.second);
452 : :
453 : 1391 : TyTy::BaseType *self = resolve_impl_block_self (impl_block);
454 : :
455 : 1391 : return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
456 : 1392 : }
457 : :
458 : : void
459 : 4995 : TypeCheckItem::visit (HIR::Function &function)
460 : : {
461 : 4995 : auto lifetime_pin = context->push_clean_lifetime_resolver ();
462 : 4995 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
463 : 4995 : if (function.has_generics ())
464 : 393 : resolve_generic_params (function.get_generic_params (),
465 : : substitutions); // TODO resolve constraints
466 : :
467 : 4995 : TyTy::RegionConstraints region_constraints;
468 : 5003 : for (auto &where_clause_item : function.get_where_clause ().get_items ())
469 : : {
470 : 8 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
471 : : }
472 : :
473 : 4995 : TyTy::BaseType *ret_type = nullptr;
474 : 4995 : if (!function.has_function_return_type ())
475 : 2732 : ret_type
476 : 2732 : = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
477 : : else
478 : : {
479 : 2263 : auto resolved
480 : 2263 : = TypeCheckType::Resolve (function.get_return_type ().get ());
481 : 2263 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
482 : : {
483 : 3 : rust_error_at (function.get_locus (),
484 : : "failed to resolve return type");
485 : 3 : return;
486 : : }
487 : :
488 : 2260 : ret_type = resolved->clone ();
489 : 2260 : ret_type->set_ref (
490 : 4520 : function.get_return_type ()->get_mappings ().get_hirid ());
491 : : }
492 : :
493 : 4992 : std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *>> params;
494 : 6216 : for (auto ¶m : function.get_function_params ())
495 : : {
496 : : // get the name as well required for later on
497 : 1224 : auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
498 : 1224 : params.emplace_back (param.get_param_name ().get (), param_tyty);
499 : :
500 : 1224 : context->insert_type (param.get_mappings (), param_tyty);
501 : 1224 : TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
502 : : }
503 : :
504 : 4992 : const CanonicalPath *canonical_path = nullptr;
505 : 4992 : bool ok
506 : 4992 : = mappings->lookup_canonical_path (function.get_mappings ().get_nodeid (),
507 : : &canonical_path);
508 : 4992 : rust_assert (ok);
509 : :
510 : 4992 : RustIdent ident{*canonical_path, function.get_locus ()};
511 : :
512 : 4992 : auto fn_type = new TyTy::FnType (
513 : 4992 : function.get_mappings ().get_hirid (),
514 : 4992 : function.get_mappings ().get_defid (),
515 : 4992 : function.get_function_name ().as_string (), ident,
516 : : TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
517 : : std::move (substitutions),
518 : 9984 : TyTy::SubstitutionArgumentMappings::empty (
519 : 4992 : context->get_lifetime_resolver ().get_num_bound_regions ()),
520 : 14976 : region_constraints);
521 : :
522 : 4992 : context->insert_type (function.get_mappings (), fn_type);
523 : :
524 : : // need to get the return type from this
525 : 4992 : TyTy::FnType *resolved_fn_type = fn_type;
526 : 4992 : auto expected_ret_tyty = resolved_fn_type->get_return_type ();
527 : 4992 : context->push_return_type (TypeCheckContextItem (&function),
528 : : expected_ret_tyty);
529 : :
530 : 4992 : context->switch_to_fn_body ();
531 : 4992 : auto block_expr_ty
532 : 4992 : = TypeCheckExpr::Resolve (function.get_definition ().get ());
533 : :
534 : 4991 : location_t fn_return_locus = function.has_function_return_type ()
535 : 4991 : ? function.get_return_type ()->get_locus ()
536 : 2731 : : function.get_locus ();
537 : 4991 : coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
538 : : TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
539 : : TyTy::TyWithLocation (block_expr_ty),
540 : 4991 : function.get_definition ()->get_locus ());
541 : :
542 : 4991 : context->pop_return_type ();
543 : :
544 : 4991 : infered = fn_type;
545 : 9985 : }
546 : :
547 : : void
548 : 432 : TypeCheckItem::visit (HIR::Module &module)
549 : : {
550 : 968 : for (auto &item : module.get_items ())
551 : 537 : TypeCheckItem::Resolve (*item);
552 : 431 : }
553 : :
554 : : void
555 : 2172 : TypeCheckItem::visit (HIR::Trait &trait)
556 : : {
557 : 2172 : TraitReference *trait_ref = TraitResolver::Resolve (trait);
558 : 2171 : if (trait_ref->is_error ())
559 : : {
560 : 4 : infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
561 : 4 : return;
562 : : }
563 : :
564 : 2167 : RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
565 : 2167 : infered = new TyTy::DynamicObjectType (
566 : 2167 : trait.get_mappings ().get_hirid (), ident,
567 : : {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
568 : 6501 : trait.get_locus ())});
569 : 2167 : }
570 : :
571 : : void
572 : 1015 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
573 : : {
574 : 2597 : for (auto &item : extern_block.get_extern_items ())
575 : : {
576 : 1583 : TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
577 : : }
578 : 1014 : }
579 : :
580 : : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
581 : 11974 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
582 : : bool &failure_flag)
583 : : {
584 : 11974 : std::vector<TyTy::SubstitutionParamMapping> substitutions;
585 : 11974 : if (impl_block.has_generics ())
586 : 4456 : resolve_generic_params (impl_block.get_generic_params (), substitutions);
587 : :
588 : 11974 : TyTy::RegionConstraints region_constraints;
589 : 12397 : for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
590 : : {
591 : 423 : ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
592 : : }
593 : :
594 : 11974 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
595 : 11974 : TraitReference *trait_reference = &TraitReference::error_node ();
596 : 11974 : if (impl_block.has_trait_ref ())
597 : : {
598 : 8462 : std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
599 : 8462 : trait_reference = TraitResolver::Resolve (*ref);
600 : 8462 : rust_assert (!trait_reference->is_error ());
601 : :
602 : : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
603 : : // for example
604 : 8462 : specified_bound
605 : 8462 : = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
606 : : }
607 : :
608 : 11974 : TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
609 : :
610 : : // inherit the bounds
611 : 11974 : if (!specified_bound.is_error ())
612 : 16920 : self->inherit_bounds ({specified_bound});
613 : :
614 : : // check for any unconstrained type-params
615 : 11974 : const TyTy::SubstitutionArgumentMappings trait_constraints
616 : 11974 : = specified_bound.get_substitution_arguments ();
617 : 11974 : const TyTy::SubstitutionArgumentMappings impl_constraints
618 : 11974 : = GetUsedSubstArgs::From (self);
619 : :
620 : 11974 : failure_flag = check_for_unconstrained (substitutions, trait_constraints,
621 : : impl_constraints, self);
622 : :
623 : 11974 : return {substitutions, region_constraints};
624 : 23948 : }
625 : :
626 : : void
627 : 3000 : TypeCheckItem::validate_trait_impl_block (
628 : : HIR::ImplBlock &impl_block, TyTy::BaseType *self,
629 : : std::vector<TyTy::SubstitutionParamMapping> &substitutions)
630 : : {
631 : 3000 : auto specified_bound = TyTy::TypeBoundPredicate::error ();
632 : 3000 : TraitReference *trait_reference = &TraitReference::error_node ();
633 : 3000 : if (impl_block.has_trait_ref ())
634 : : {
635 : 2317 : std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
636 : 2317 : trait_reference = TraitResolver::Resolve (*ref);
637 : 2317 : rust_assert (!trait_reference->is_error ());
638 : :
639 : : // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
640 : : // for example
641 : 2317 : specified_bound
642 : 2317 : = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
643 : : }
644 : :
645 : 3000 : bool is_trait_impl_block = !trait_reference->is_error ();
646 : 3000 : std::vector<const TraitItemReference *> trait_item_refs;
647 : 7096 : for (auto &impl_item : impl_block.get_impl_items ())
648 : : {
649 : 4096 : if (!specified_bound.is_error ())
650 : : {
651 : 2464 : auto trait_item_ref
652 : 2464 : = TypeCheckImplItemWithTrait::Resolve (&impl_block,
653 : : impl_item.get (), self,
654 : : specified_bound,
655 : : substitutions);
656 : 2464 : if (!trait_item_ref.is_error ())
657 : 2461 : trait_item_refs.push_back (trait_item_ref.get_raw_item ());
658 : : }
659 : : }
660 : :
661 : 3000 : bool impl_block_missing_trait_items
662 : 3000 : = !specified_bound.is_error ()
663 : 3000 : && trait_reference->size () != trait_item_refs.size ();
664 : 742 : if (impl_block_missing_trait_items)
665 : : {
666 : : // filter the missing impl_items
667 : 742 : std::vector<std::reference_wrapper<const TraitItemReference>>
668 : 742 : missing_trait_items;
669 : 2184 : for (const auto &trait_item_ref : trait_reference->get_trait_items ())
670 : : {
671 : 1442 : bool found = false;
672 : 2138 : for (auto implemented_trait_item : trait_item_refs)
673 : : {
674 : 1384 : std::string trait_item_name = trait_item_ref.get_identifier ();
675 : 1384 : std::string impl_item_name
676 : 1384 : = implemented_trait_item->get_identifier ();
677 : 1384 : found = trait_item_name == impl_item_name;
678 : 1384 : if (found)
679 : : break;
680 : 1384 : }
681 : :
682 : 1442 : bool is_required_trait_item = !trait_item_ref.is_optional ();
683 : 1442 : if (!found && is_required_trait_item)
684 : 6 : missing_trait_items.emplace_back (trait_item_ref);
685 : : }
686 : :
687 : 742 : if (!missing_trait_items.empty ())
688 : : {
689 : 4 : std::string missing_items_buf;
690 : 4 : rich_location r (line_table, impl_block.get_locus ());
691 : 10 : for (size_t i = 0; i < missing_trait_items.size (); i++)
692 : : {
693 : 6 : bool has_more = (i + 1) < missing_trait_items.size ();
694 : 6 : const TraitItemReference &missing_trait_item
695 : 6 : = missing_trait_items.at (i);
696 : 6 : missing_items_buf += missing_trait_item.get_identifier ()
697 : 12 : + (has_more ? ", " : "");
698 : 6 : r.add_range (missing_trait_item.get_locus ());
699 : : }
700 : :
701 : 4 : rust_error_at (r, ErrorCode::E0046,
702 : : "missing %s in implementation of trait %<%s%>",
703 : : missing_items_buf.c_str (),
704 : 4 : trait_reference->get_name ().c_str ());
705 : 4 : }
706 : 742 : }
707 : :
708 : 3000 : if (is_trait_impl_block)
709 : : {
710 : 2317 : trait_reference->clear_associated_types ();
711 : :
712 : 2317 : AssociatedImplTrait associated (trait_reference, specified_bound,
713 : 2317 : &impl_block, self, context);
714 : 2317 : context->insert_associated_trait_impl (
715 : 2317 : impl_block.get_mappings ().get_hirid (), std::move (associated));
716 : 2317 : context->insert_associated_impl_mapping (
717 : 2317 : trait_reference->get_mappings ().get_hirid (), self,
718 : 2317 : impl_block.get_mappings ().get_hirid ());
719 : 2317 : }
720 : 3000 : }
721 : :
722 : : TyTy::BaseType *
723 : 11969 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
724 : : {
725 : 11969 : return TypeCheckType::Resolve (impl_block.get_type ().get ());
726 : : }
727 : :
728 : : } // namespace Resolver
729 : : } // namespace Rust
|