LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-item.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.8 % 498 477
Test Date: 2026-02-28 14:20:25 Functions: 95.5 % 22 21
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.