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.1 % 739 703
Test Date: 2026-10-24 16:24:59 Functions: 97.1 % 34 33
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-hir-type-check.h"
      31              : #include "rust-identifier.h"
      32              : #include "rust-rib.h"
      33              : #include "rust-session-manager.h"
      34              : #include "rust-finalized-name-resolution-context.h"
      35              : #include "rust-substitution-mapper.h"
      36              : #include "rust-type-util.h"
      37              : #include "rust-tyty-variance-analysis.h"
      38              : #include "rust-tyty.h"
      39              : #include "options.h"
      40              : #include "rust-compile-base.h"
      41              : #include "rust-compile-context.h"
      42              : 
      43              : namespace Rust {
      44              : namespace Resolver {
      45              : 
      46              : static bool
      47         5567 : type_contains_adt_without_indirection (
      48              :   const TyTy::BaseType *type, DefId target,
      49              :   std::set<const TyTy::BaseType *> &visited)
      50              : {
      51         5567 :   bool found = visited.find (type) != visited.end ();
      52         5567 :   if (found)
      53              :     return false;
      54         5567 :   visited.insert (type);
      55              : 
      56         5567 :   switch (type->get_kind ())
      57              :     {
      58          437 :     case TyTy::TypeKind::ADT:
      59          437 :       {
      60          437 :         auto *adt = static_cast<const TyTy::ADTType *> (type);
      61          437 :         if (adt->get_id () == target)
      62            5 :           return true;
      63              : 
      64          875 :         for (auto *variant : adt->get_variants ())
      65              :           {
      66         1160 :             for (auto *field : variant->get_fields ())
      67              :               {
      68          717 :                 if (type_contains_adt_without_indirection (
      69          717 :                       field->get_field_type (), target, visited))
      70         5567 :                   return true;
      71              :               }
      72              :           }
      73              : 
      74              :         return false;
      75              :       }
      76              : 
      77           18 :     case TyTy::TypeKind::TUPLE:
      78           18 :       {
      79           18 :         auto *tuple = static_cast<const TyTy::TupleType *> (type);
      80           22 :         for (const auto &field : tuple->get_fields ())
      81              :           {
      82            5 :             if (type_contains_adt_without_indirection (field.get_tyty (),
      83              :                                                        target, visited))
      84         5567 :               return true;
      85              :           }
      86              : 
      87              :         return false;
      88              :       }
      89              : 
      90           72 :     case TyTy::TypeKind::ARRAY:
      91           72 :       return type_contains_adt_without_indirection (
      92           72 :         static_cast<const TyTy::ArrayType *> (type)->get_element_type (),
      93           72 :         target, visited);
      94              : 
      95           15 :     case TyTy::TypeKind::SLICE:
      96           15 :       return type_contains_adt_without_indirection (
      97           15 :         static_cast<const TyTy::SliceType *> (type)->get_element_type (),
      98           15 :         target, visited);
      99              : 
     100              :     default:
     101              :       return false;
     102              :     }
     103              : }
     104              : 
     105              : static bool
     106         3437 : validate_adt_size (TyTy::ADTType *type)
     107              : {
     108         7620 :   for (auto *variant : type->get_variants ())
     109              :     {
     110         8941 :       for (auto *field : variant->get_fields ())
     111              :         {
     112         4758 :           std::set<const TyTy::BaseType *> visited;
     113         4758 :           if (!type_contains_adt_without_indirection (field->get_field_type (),
     114              :                                                       type->get_id (), visited))
     115         4753 :             continue;
     116              : 
     117           10 :           rust_error_at (field->get_locus (), ErrorCode::E0072,
     118              :                          "recursive type %qs has infinite size",
     119            5 :                          type->get_identifier ().c_str ());
     120            5 :           return false;
     121         4758 :         }
     122              :     }
     123              : 
     124              :   return true;
     125              : }
     126              : 
     127              : // Const-evaluate the discriminants of a repr(C) enum and warn when a value does
     128              : // not fit into a C int/unsigned int. Done here, during type resolution, using
     129              : // the compile context (a singleton shared with the backend).
     130              : static void
     131            3 : check_repr_c_enum_discriminants (Compile::Context *ctx, TyTy::BaseType *type)
     132              : {
     133            3 :   if (type->get_kind () != TyTy::TypeKind::ADT)
     134              :     return;
     135              : 
     136            3 :   auto &adt = static_cast<TyTy::ADTType &> (*type);
     137            3 :   if (!adt.is_enum ()
     138            3 :       || adt.get_repr_options ().repr_kind != TyTy::ADTType::ReprKind::C)
     139              :     return;
     140              : 
     141            4 :   for (auto &variant : adt.get_variants ())
     142              :     {
     143            2 :       if (!variant->has_discriminant ())
     144            0 :         continue;
     145              : 
     146            2 :       HIR::Expr &discriminant = variant->get_discriminant ();
     147            2 :       TyTy::BaseType *discrim_ty = nullptr;
     148            2 :       if (!ctx->get_tyctx ()->lookup_type (
     149            2 :             discriminant.get_mappings ().get_hirid (), &discrim_ty))
     150            0 :         continue;
     151              : 
     152            2 :       tree folded
     153            2 :         = Compile::HIRCompileBase::query_compile_const_expr (ctx, discrim_ty,
     154              :                                                              discriminant);
     155            2 :       if (folded == error_mark_node || TREE_CODE (folded) != INTEGER_CST)
     156            0 :         continue;
     157              : 
     158            2 :       widest_int value = wi::to_widest (folded);
     159            2 :       if (wi::lts_p (value, INT32_MIN) || wi::gts_p (value, UINT32_MAX))
     160            1 :         rust_warning_at (discriminant.get_locus (), OPT_Woverflow,
     161              :                          "%<repr(C)%> enum discriminant does not fit into C "
     162              :                          "%<int%> nor into C %<unsigned int%>");
     163            2 :     }
     164              : }
     165              : 
     166        53933 : TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
     167              : 
     168              : TyTy::BaseType *
     169        29756 : TypeCheckItem::Resolve (HIR::Item &item)
     170              : {
     171              :   // is it already resolved?
     172        29756 :   auto context = TypeCheckContext::get ();
     173        29756 :   TyTy::BaseType *resolved = nullptr;
     174        29756 :   bool already_resolved
     175        29756 :     = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
     176        29756 :   if (already_resolved)
     177              :     {
     178         5215 :       bool function_body_pending = false;
     179         5215 :       if (auto fn = resolved->try_as<TyTy::FnType> ())
     180          185 :         function_body_pending = context->function_body_pending (fn->get_id ());
     181              : 
     182          185 :       if (!function_body_pending)
     183         5035 :         return resolved;
     184              :     }
     185              : 
     186        24721 :   rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
     187        24721 :   HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
     188              : 
     189        24721 :   TypeCheckItem resolver;
     190        24721 :   vis_item.accept_vis (resolver);
     191        24720 :   return resolver.infered;
     192        24720 : }
     193              : 
     194              : TyTy::FnType *
     195          180 : TypeCheckItem::ResolveFunctionSignature (HIR::Function &function)
     196              : {
     197          180 :   TypeCheckItem resolver;
     198          180 :   auto lifetime_pin = resolver.context->push_clean_lifetime_resolver ();
     199          180 :   TyTy::FnType *result = resolver.resolve_function_signature (function);
     200          180 :   if (result != nullptr)
     201          180 :     resolver.context->mark_function_body_pending (result->get_id ());
     202          360 :   return result;
     203          180 : }
     204              : 
     205              : TyTy::BaseType *
     206          409 : TypeCheckItem::ResolveTraitSignature (HIR::Trait &trait)
     207              : {
     208          409 :   TypeCheckItem resolver;
     209          409 :   return resolver.resolve_trait (trait, false);
     210          409 : }
     211              : 
     212              : TyTy::BaseType *
     213            1 : TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
     214              : {
     215            1 :   TypeCheckItem resolver;
     216            1 :   return resolver.resolve_impl_item (impl_block, item);
     217            1 : }
     218              : 
     219              : TyTy::BaseType *
     220        23363 : TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
     221              : {
     222        23363 :   TypeCheckItem resolver;
     223        23363 :   auto lifetime_pin = resolver.context->push_clean_lifetime_resolver (true);
     224              : 
     225        23363 :   bool failed_flag = false;
     226        23363 :   auto result
     227        23363 :     = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
     228        23363 :   if (failed_flag)
     229              :     {
     230            0 :       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     231              :     }
     232        23363 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     233        23363 :     = std::move (result.first);
     234        23363 :   TyTy::RegionConstraints region_constraints = std::move (result.second);
     235              : 
     236        23363 :   return resolver.resolve_impl_block_self (impl_block);
     237        23363 : }
     238              : 
     239              : TyTy::BaseType *
     240         3208 : TypeCheckItem::ResolveImplBlockSelfWithInference (
     241              :   HIR::ImplBlock &impl, location_t locus,
     242              :   TyTy::SubstitutionArgumentMappings *infer_arguments)
     243              : {
     244         3208 :   TypeCheckItem resolver;
     245         3208 :   auto lifetime_pin = resolver.context->push_clean_lifetime_resolver (true);
     246              : 
     247         3208 :   bool failed_flag = false;
     248         3208 :   auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
     249         3208 :   if (failed_flag)
     250              :     {
     251            1 :       return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
     252              :     }
     253         3207 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     254         3207 :     = std::move (result.first);
     255         3207 :   TyTy::RegionConstraints region_constraints = std::move (result.second);
     256              : 
     257              :   // now that we have the param mappings we need to query the self type
     258         3207 :   TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
     259              : 
     260              :   // nothing to do
     261         3207 :   if (substitutions.empty () || self->is_concrete ())
     262              :     return self;
     263              : 
     264              :   // generate inference variables for the subst-param-mappings
     265          780 :   std::vector<TyTy::SubstitutionArg> args;
     266         1594 :   for (auto &p : substitutions)
     267              :     {
     268          814 :       auto param = p.get_param_ty ();
     269          814 :       if (!p.needs_substitution ())
     270              :         {
     271            0 :           auto resolved = param->destructure ();
     272            0 :           args.emplace_back (&p, resolved);
     273              : 
     274            0 :           continue;
     275            0 :         }
     276              : 
     277          814 :       TyTy::BaseType *argument = nullptr;
     278          814 :       if (param->get_kind () == TyTy::TypeKind::CONST)
     279              :         {
     280           28 :           auto i = TyTy::TyVar::get_implicit_const_infer_var (locus);
     281           28 :           argument = i.get_tyty ();
     282              :         }
     283              :       else
     284              :         {
     285          786 :           auto i = TyTy::TyVar::get_implicit_infer_var (locus);
     286          786 :           argument = i.get_tyty ();
     287              :         }
     288          814 :       args.emplace_back (&p, argument);
     289              :     }
     290              : 
     291              :   // create argument mappings
     292          780 :   *infer_arguments = TyTy::SubstitutionArgumentMappings (
     293              :     std::move (args), {},
     294         1560 :     TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
     295              :       infer_arguments),
     296         1560 :     locus);
     297              : 
     298          780 :   TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
     299              : 
     300              :   // we only need to apply to the bounds manually on types which dont bind
     301              :   // generics
     302          780 :   if (!infer->has_substitutions_defined ())
     303              :     {
     304          693 :       for (auto &bound : infer->get_specified_bounds ())
     305          185 :         bound.handle_substitions (*infer_arguments);
     306              :     }
     307              : 
     308          780 :   return infer;
     309         3988 : }
     310              : 
     311              : std::vector<TyTy::SubstitutionParamMapping>
     312         2051 : TypeCheckItem::ResolveImplBlockSubstitutions (HIR::ImplBlock &impl_block,
     313              :                                               bool &failure_flag)
     314              : {
     315         2051 :   TypeCheckItem resolver;
     316         2051 :   auto result
     317         2051 :     = resolver.resolve_impl_block_substitutions (impl_block, failure_flag);
     318         2051 :   return std::move (result.first);
     319         2051 : }
     320              : 
     321              : void
     322         5357 : TypeCheckItem::validate_trait_impl_block (
     323              :   const TyTy::TypeBoundPredicate &specified_bound,
     324              :   std::vector<const TraitItemReference *> trait_item_refs,
     325              :   TraitReference *trait_reference, HIR::ImplBlock &impl_block,
     326              :   TyTy::BaseType *self,
     327              :   std::vector<TyTy::SubstitutionParamMapping> &substitutions)
     328              : {
     329         5357 :   bool impl_block_missing_trait_items
     330         5357 :     = !specified_bound.is_error ()
     331         5357 :       && trait_reference->size () != trait_item_refs.size ();
     332         1722 :   if (impl_block_missing_trait_items
     333         1722 :       && impl_block.get_polarity () == BoundPolarity::RegularBound)
     334              :     {
     335              :       // filter the missing impl_items
     336         1720 :       std::vector<std::reference_wrapper<const TraitItemReference>>
     337         1720 :         missing_trait_items;
     338         5435 :       for (const auto &trait_item_ref : trait_reference->get_trait_items ())
     339              :         {
     340         3715 :           bool found = false;
     341         5706 :           for (auto implemented_trait_item : trait_item_refs)
     342              :             {
     343         3539 :               std::string trait_item_name = trait_item_ref.get_identifier ();
     344         3539 :               std::string impl_item_name
     345         3539 :                 = implemented_trait_item->get_identifier ();
     346         3539 :               found = trait_item_name == impl_item_name;
     347         3539 :               if (found)
     348              :                 break;
     349         3539 :             }
     350              : 
     351         3715 :           bool is_required_trait_item = !trait_item_ref.is_optional ();
     352         3715 :           if (!found && is_required_trait_item)
     353            7 :             missing_trait_items.emplace_back (trait_item_ref);
     354              :         }
     355              : 
     356         1720 :       if (!missing_trait_items.empty ())
     357              :         {
     358            5 :           std::string missing_items_buf;
     359            5 :           rich_location r (line_table, impl_block.get_locus ());
     360           17 :           for (size_t i = 0; i < missing_trait_items.size (); i++)
     361              :             {
     362            7 :               bool has_more = (i + 1) < missing_trait_items.size ();
     363            7 :               const TraitItemReference &missing_trait_item
     364            7 :                 = missing_trait_items.at (i);
     365            7 :               missing_items_buf += missing_trait_item.get_identifier ()
     366           21 :                                    + (has_more ? ", " : "");
     367            7 :               r.add_range (missing_trait_item.get_locus ());
     368              :             }
     369              : 
     370            5 :           rust_error_at (r, ErrorCode::E0046,
     371              :                          "missing %s in implementation of trait %qs",
     372              :                          missing_items_buf.c_str (),
     373            5 :                          trait_reference->get_name ().c_str ());
     374            5 :         }
     375         1720 :     }
     376         5357 : }
     377              : 
     378              : void
     379           73 : TypeCheckItem::visit (HIR::TypeAlias &alias)
     380              : {
     381           73 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     382              : 
     383           73 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     384           73 :   if (alias.has_generics ())
     385           10 :     resolve_generic_params (HIR::Item::ItemKind::TypeAlias, alias.get_locus (),
     386           10 :                             alias.get_generic_params (), substitutions);
     387              : 
     388           73 :   TyTy::BaseType *actual_type
     389           73 :     = TypeCheckType::Resolve (alias.get_type_aliased ());
     390              : 
     391           73 :   context->insert_type (alias.get_mappings (), actual_type);
     392              : 
     393           73 :   TyTy::RegionConstraints region_constraints;
     394           73 :   ResolveWhereClauseItem::Resolve (alias.get_where_clause (),
     395              :                                    region_constraints);
     396           73 :   infered = actual_type;
     397           73 : }
     398              : 
     399              : void
     400         1030 : TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
     401              : {
     402         1030 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     403              : 
     404         1030 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     405         1030 :   if (struct_decl.has_generics ())
     406          312 :     resolve_generic_params (HIR::Item::ItemKind::Struct,
     407              :                             struct_decl.get_locus (),
     408          312 :                             struct_decl.get_generic_params (), substitutions);
     409              : 
     410         1030 :   TyTy::RegionConstraints region_constraints;
     411         1030 :   ResolveWhereClauseItem::Resolve (struct_decl.get_where_clause (),
     412              :                                    region_constraints);
     413              : 
     414              :   // Process #[repr(X)] attribute, if any
     415         1030 :   const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
     416         1030 :   TyTy::ADTType::ReprOptions repr
     417         1030 :     = parse_repr_options (attrs, struct_decl.get_locus ());
     418              : 
     419         1030 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     420         1030 :   CanonicalPath path
     421         1030 :     = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
     422         1030 :                                 Resolver2_0::Namespace::Types);
     423         1030 :   RustIdent ident{path, struct_decl.get_locus ()};
     424              : 
     425         1030 :   std::vector<TyTy::VariantDef *> variants;
     426         1030 :   auto *type = new TyTy::ADTType (
     427         1030 :     struct_decl.get_mappings ().get_defid (),
     428         1030 :     struct_decl.get_mappings ().get_hirid (),
     429         1030 :     struct_decl.get_mappings ().get_hirid (),
     430         1030 :     struct_decl.get_identifier ().as_string (), ident,
     431              :     TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
     432              :     std::move (substitutions), repr,
     433         2060 :     TyTy::SubstitutionArgumentMappings::empty (
     434         1030 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     435         4120 :     region_constraints);
     436         1030 :   context->insert_type (struct_decl.get_mappings (), type);
     437              : 
     438         1030 :   std::vector<TyTy::StructFieldType *> fields;
     439         1030 :   size_t idx = 0;
     440         2844 :   for (auto &field : struct_decl.get_fields ())
     441              :     {
     442         1814 :       TyTy::BaseType *field_type
     443         1814 :         = TypeCheckType::Resolve (field.get_field_type ());
     444         1814 :       auto *ty_field
     445         3628 :         = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
     446         1814 :                                      std::to_string (idx), field_type,
     447         1814 :                                      field.get_locus ());
     448         1814 :       fields.push_back (ty_field);
     449         1814 :       context->insert_type (field.get_mappings (), ty_field->get_field_type ());
     450         1814 :       idx++;
     451              :     }
     452              : 
     453         1030 :   if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
     454              :     {
     455           14 :       bool is_valid = validate_repr_simd (fields, struct_decl.get_locus ());
     456           14 :       if (!is_valid)
     457              :         return;
     458              :     }
     459              : 
     460              :   // its a single variant ADT
     461         1027 :   auto variant
     462         1027 :     = new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
     463         1027 :                             struct_decl.get_mappings ().get_defid (),
     464         1027 :                             struct_decl.get_identifier ().as_string (), ident,
     465         2054 :                             TyTy::VariantDef::VariantType::TUPLE, tl::nullopt,
     466         2054 :                             std::move (fields));
     467         1027 :   type->get_variants ().push_back (variant);
     468         1027 :   if (!validate_adt_size (type))
     469              :     {
     470            2 :       infered = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
     471            2 :       context->insert_type (struct_decl.get_mappings (), infered);
     472            2 :       return;
     473              :     }
     474         1025 :   infered = type;
     475              : 
     476         1025 :   context->get_variance_analysis_ctx ().add_type_constraints (*type);
     477         2060 : }
     478              : 
     479              : void
     480         1739 : TypeCheckItem::visit (HIR::StructStruct &struct_decl)
     481              : {
     482         1739 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     483         1739 :   auto &mappings = Analysis::Mappings::get ();
     484              : 
     485         1739 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     486         1739 :   CanonicalPath path
     487         1739 :     = nr_ctx.to_canonical_path (struct_decl.get_mappings ().get_nodeid (),
     488         1739 :                                 Resolver2_0::Namespace::Types);
     489         1739 :   RustIdent ident{path, struct_decl.get_locus ()};
     490              : 
     491         1739 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     492         1739 :   if (struct_decl.has_generics ())
     493          543 :     resolve_generic_params (HIR::Item::ItemKind::Struct,
     494              :                             struct_decl.get_locus (),
     495          543 :                             struct_decl.get_generic_params (), substitutions);
     496              : 
     497         1739 :   TyTy::RegionConstraints region_constraints;
     498         1739 :   ResolveWhereClauseItem::Resolve (struct_decl.get_where_clause (),
     499              :                                    region_constraints);
     500              : 
     501              :   // Process #[repr(X)] attribute, if any
     502         1739 :   const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
     503         1739 :   TyTy::ADTType::ReprOptions repr
     504         1739 :     = parse_repr_options (attrs, struct_decl.get_locus ());
     505              : 
     506         1739 :   std::vector<TyTy::VariantDef *> variants;
     507         1739 :   auto *type = new TyTy::ADTType (
     508         1739 :     struct_decl.get_mappings ().get_defid (),
     509         1739 :     struct_decl.get_mappings ().get_hirid (),
     510         1739 :     struct_decl.get_mappings ().get_hirid (),
     511         1739 :     struct_decl.get_identifier ().as_string (), ident,
     512              :     TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
     513              :     std::move (substitutions), repr,
     514         3478 :     TyTy::SubstitutionArgumentMappings::empty (
     515         1739 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     516         6956 :     region_constraints);
     517         1739 :   context->insert_type (struct_decl.get_mappings (), type);
     518              : 
     519         1739 :   std::vector<TyTy::StructFieldType *> fields;
     520         3756 :   for (auto &field : struct_decl.get_fields ())
     521              :     {
     522         2022 :       TyTy::BaseType *field_type
     523         2022 :         = TypeCheckType::Resolve (field.get_field_type ());
     524         2022 :       auto infer_type = field_type->contains_infer ();
     525         2022 :       if (infer_type)
     526              :         {
     527            5 :           rust_error_at (mappings.lookup_location (infer_type->get_ref ()),
     528              :                          "the placeholder %<_%> is not allowed within types on "
     529              :                          "item signatures for structs");
     530            5 :           infered
     531            5 :             = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
     532            5 :           context->insert_type (struct_decl.get_mappings (), infered);
     533            5 :           return;
     534              :         }
     535         2017 :       auto *ty_field
     536         2017 :         = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
     537         2017 :                                      field.get_field_name ().as_string (),
     538         4034 :                                      field_type, field.get_locus ());
     539         2017 :       fields.push_back (ty_field);
     540         2017 :       context->insert_type (field.get_mappings (), ty_field->get_field_type ());
     541              :     }
     542              : 
     543         1734 :   if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
     544              :     {
     545            0 :       bool is_valid = validate_repr_simd (fields, struct_decl.get_locus ());
     546            0 :       if (!is_valid)
     547              :         return;
     548              :     }
     549         1734 :   if (repr.repr_kind == TyTy::ADTType::ReprKind::TRANSPARENT)
     550              :     {
     551           26 :       size_t num_non_zst = 0;
     552           55 :       for (auto &field : fields)
     553              :         {
     554           29 :           if (!field->get_field_type ()->is_zero_sized ())
     555           26 :             num_non_zst++;
     556              :         }
     557           26 :       if (num_non_zst > 1)
     558              :         {
     559            1 :           rust_error_at (struct_decl.get_locus (), ErrorCode::E0690,
     560              :                          "transparent struct needs at most one field with "
     561              :                          "non-trivial size or alignment, but has %lu",
     562              :                          (unsigned long) num_non_zst);
     563            1 :           return;
     564              :         }
     565              :     }
     566              : 
     567              :   // its a single variant ADT
     568         1733 :   auto variant_type = struct_decl.is_unit_struct ()
     569         1733 :                         ? TyTy::VariantDef::VariantType::UNIT
     570         1122 :                         : TyTy::VariantDef::VariantType::STRUCT;
     571         1733 :   auto variant
     572         1733 :     = new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
     573         1733 :                             struct_decl.get_mappings ().get_defid (),
     574         1733 :                             struct_decl.get_identifier ().as_string (), ident,
     575         3466 :                             variant_type, tl::nullopt, std::move (fields));
     576         1733 :   type->get_variants ().push_back (variant);
     577         1733 :   if (!validate_adt_size (type))
     578              :     {
     579            3 :       infered = new TyTy::ErrorType (struct_decl.get_mappings ().get_hirid ());
     580            3 :       context->insert_type (struct_decl.get_mappings (), infered);
     581            3 :       return;
     582              :     }
     583         1730 :   infered = type;
     584              : 
     585         1730 :   context->get_variance_analysis_ctx ().add_type_constraints (*type);
     586         3478 : }
     587              : 
     588              : void
     589          574 : TypeCheckItem::visit (HIR::Enum &enum_decl)
     590              : {
     591          574 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     592          574 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     593          574 :   if (enum_decl.has_generics ())
     594          247 :     resolve_generic_params (HIR::Item::ItemKind::Enum, enum_decl.get_locus (),
     595          247 :                             enum_decl.get_generic_params (), substitutions);
     596              : 
     597          574 :   TyTy::RegionConstraints region_constraints;
     598          574 :   ResolveWhereClauseItem::Resolve (enum_decl.get_where_clause (),
     599              :                                    region_constraints);
     600              : 
     601          574 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     602          574 :   CanonicalPath canonical_path
     603          574 :     = nr_ctx.to_canonical_path (enum_decl.get_mappings ().get_nodeid (),
     604          574 :                                 Resolver2_0::Namespace::Types);
     605              : 
     606          574 :   RustIdent ident{canonical_path, enum_decl.get_locus ()};
     607              : 
     608              :   // Process #[repr(X)] attribute, if any
     609          574 :   const AST::AttrVec &attrs = enum_decl.get_outer_attrs ();
     610          574 :   TyTy::ADTType::ReprOptions repr
     611          574 :     = parse_repr_options (attrs, enum_decl.get_locus ());
     612              : 
     613          574 :   std::vector<TyTy::VariantDef *> variants;
     614          574 :   auto *type = new TyTy::ADTType (
     615          574 :     enum_decl.get_mappings ().get_defid (),
     616          574 :     enum_decl.get_mappings ().get_hirid (),
     617          574 :     enum_decl.get_mappings ().get_hirid (),
     618          574 :     enum_decl.get_identifier ().as_string (), ident,
     619              :     TyTy::ADTType::ADTKind::ENUM, std::move (variants),
     620              :     std::move (substitutions), repr,
     621         1148 :     TyTy::SubstitutionArgumentMappings::empty (
     622          574 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     623         2296 :     region_constraints);
     624          574 :   context->insert_type (enum_decl.get_mappings (), type);
     625              : 
     626          574 :   int64_t discriminant_value = 0;
     627         1898 :   for (auto &variant : enum_decl.get_variants ())
     628              :     {
     629         1324 :       TyTy::VariantDef *field_type
     630         1324 :         = TypeCheckEnumItem::Resolve (*variant, discriminant_value);
     631         1324 :       if (field_type)
     632              :         {
     633         1323 :           discriminant_value++;
     634         1323 :           type->get_variants ().push_back (field_type);
     635              :         }
     636              :     }
     637              : 
     638              :   // Check for zero-variant enum compatibility
     639          574 :   if (enum_decl.is_zero_variant ())
     640              :     {
     641           11 :       if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
     642           11 :           || repr.repr_kind == TyTy::ADTType::ReprKind::C)
     643              :         {
     644            2 :           rust_error_at (enum_decl.get_locus (),
     645              :                          "unsupported representation for zero-variant enum");
     646            2 :           return;
     647              :         }
     648              :     }
     649              : 
     650          572 :   if (!validate_adt_size (type))
     651              :     {
     652            0 :       infered = new TyTy::ErrorType (enum_decl.get_mappings ().get_hirid ());
     653            0 :       context->insert_type (enum_decl.get_mappings (), infered);
     654            0 :       return;
     655              :     }
     656          572 :   infered = type;
     657              : 
     658          572 :   context->get_variance_analysis_ctx ().add_type_constraints (*type);
     659              : 
     660          572 :   if (flag_unused_check_2_0)
     661            3 :     check_repr_c_enum_discriminants (Compile::Context::get (), type);
     662         1148 : }
     663              : 
     664              : void
     665          105 : TypeCheckItem::visit (HIR::Union &union_decl)
     666              : {
     667          105 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     668          105 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     669          105 :   if (union_decl.has_generics ())
     670           75 :     resolve_generic_params (HIR::Item::ItemKind::Union, union_decl.get_locus (),
     671           75 :                             union_decl.get_generic_params (), substitutions);
     672              : 
     673          105 :   TyTy::RegionConstraints region_constraints;
     674          105 :   ResolveWhereClauseItem::Resolve (union_decl.get_where_clause (),
     675              :                                    region_constraints);
     676              : 
     677          105 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     678          105 :   CanonicalPath canonical_path
     679          105 :     = nr_ctx.to_canonical_path (union_decl.get_mappings ().get_nodeid (),
     680          105 :                                 Resolver2_0::Namespace::Types);
     681              : 
     682          105 :   RustIdent ident{canonical_path, union_decl.get_locus ()};
     683              : 
     684              :   // Process #[repr(X)] attribute, if any
     685          105 :   const AST::AttrVec &attrs = union_decl.get_outer_attrs ();
     686          105 :   TyTy::ADTType::ReprOptions repr
     687          105 :     = parse_repr_options (attrs, union_decl.get_locus ());
     688              : 
     689          105 :   std::vector<TyTy::VariantDef *> variants;
     690          105 :   auto *type = new TyTy::ADTType (
     691          105 :     union_decl.get_mappings ().get_defid (),
     692          105 :     union_decl.get_mappings ().get_hirid (),
     693          105 :     union_decl.get_mappings ().get_hirid (),
     694          105 :     union_decl.get_identifier ().as_string (), ident,
     695              :     TyTy::ADTType::ADTKind::UNION, std::move (variants),
     696              :     std::move (substitutions), repr,
     697          210 :     TyTy::SubstitutionArgumentMappings::empty (
     698          105 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     699          420 :     region_constraints);
     700          105 :   context->insert_type (union_decl.get_mappings (), type);
     701              : 
     702          105 :   std::vector<TyTy::StructFieldType *> fields;
     703          409 :   for (auto &variant : union_decl.get_variants ())
     704              :     {
     705          304 :       TyTy::BaseType *variant_type
     706          304 :         = TypeCheckType::Resolve (variant.get_field_type ());
     707          304 :       auto *ty_variant
     708          304 :         = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
     709          304 :                                      variant.get_field_name ().as_string (),
     710          608 :                                      variant_type, variant.get_locus ());
     711          304 :       fields.push_back (ty_variant);
     712          304 :       context->insert_type (variant.get_mappings (),
     713              :                             ty_variant->get_field_type ());
     714              :     }
     715              : 
     716          105 :   auto variant
     717          105 :     = new TyTy::VariantDef (union_decl.get_mappings ().get_hirid (),
     718          105 :                             union_decl.get_mappings ().get_defid (),
     719          105 :                             union_decl.get_identifier ().as_string (), ident,
     720          210 :                             TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
     721          210 :                             std::move (fields));
     722          105 :   type->get_variants ().push_back (variant);
     723          105 :   if (!validate_adt_size (type))
     724              :     {
     725            0 :       infered = new TyTy::ErrorType (union_decl.get_mappings ().get_hirid ());
     726            0 :       context->insert_type (union_decl.get_mappings (), infered);
     727            0 :       return;
     728              :     }
     729              : 
     730          105 :   infered = type;
     731              : 
     732          105 :   context->get_variance_analysis_ctx ().add_type_constraints (*type);
     733          210 : }
     734              : 
     735              : void
     736           76 : TypeCheckItem::visit (HIR::StaticItem &var)
     737              : {
     738           76 :   TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
     739           76 :   TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
     740              : 
     741           76 :   TyTy::BaseType *unified
     742           76 :     = coercion_site (var.get_mappings ().get_hirid (),
     743           76 :                      TyTy::TyWithLocation (type, var.get_type ().get_locus ()),
     744              :                      TyTy::TyWithLocation (expr_type,
     745           76 :                                            var.get_expr ().get_locus ()),
     746              :                      var.get_locus ());
     747           76 :   context->insert_type (var.get_mappings (), unified);
     748           76 :   infered = unified;
     749           76 : }
     750              : 
     751              : void
     752          446 : TypeCheckItem::visit (HIR::ConstantItem &constant)
     753              : {
     754          446 :   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
     755          446 :   context->push_const_context ();
     756          446 :   TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
     757          446 :   context->pop_const_context ();
     758              : 
     759          892 :   TyTy::BaseType *unified = coercion_site (
     760          446 :     constant.get_mappings ().get_hirid (),
     761          446 :     TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
     762          446 :     TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
     763              :     constant.get_locus ());
     764          446 :   context->insert_type (constant.get_mappings (), unified);
     765          446 :   infered = unified;
     766          446 : }
     767              : 
     768              : void
     769         6417 : TypeCheckItem::visit (HIR::ImplBlock &impl_block)
     770              : {
     771         6417 :   if (impl_block.has_trait_ref ())
     772         5362 :     resolve_trait_impl_block (impl_block);
     773              :   else
     774         1055 :     resolve_impl_block (impl_block);
     775         6416 : }
     776              : 
     777              : void
     778         1055 : TypeCheckItem::resolve_impl_block (HIR::ImplBlock &impl_block)
     779              : {
     780         1055 :   auto binder_pin = context->push_clean_lifetime_resolver (true);
     781              : 
     782         1055 :   bool failed_flag = false;
     783         1055 :   auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
     784         1055 :   if (failed_flag)
     785              :     {
     786            3 :       infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     787            3 :       return;
     788              :     }
     789         1052 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     790         1052 :     = std::move (result.first);
     791         1052 :   TyTy::RegionConstraints region_constraints = std::move (result.second);
     792              : 
     793         1052 :   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
     794              : 
     795         4271 :   for (auto &impl_item : impl_block.get_impl_items ())
     796         3219 :     TypeCheckImplItem::Resolve (impl_block, *impl_item, self, substitutions);
     797         1055 : }
     798              : 
     799              : void
     800         5362 : TypeCheckItem::resolve_trait_impl_block (HIR::ImplBlock &impl_block)
     801              : {
     802         5362 :   auto binder_pin = context->push_clean_lifetime_resolver (true);
     803              : 
     804         5362 :   bool failed_flag = false;
     805         5362 :   auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
     806         5361 :   if (failed_flag)
     807              :     {
     808            1 :       infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     809            1 :       return;
     810              :     }
     811         5360 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     812         5360 :     = std::move (result.first);
     813         5360 :   TyTy::RegionConstraints region_constraints = std::move (result.second);
     814              : 
     815         5360 :   auto specified_bound = TyTy::TypeBoundPredicate::error ();
     816         5360 :   TraitReference *trait_reference = &TraitReference::error_node ();
     817         5360 :   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
     818              : 
     819         5360 :   HIR::TypePath &ref = impl_block.get_trait_ref ();
     820         5360 :   trait_reference = TraitResolver::Resolve (ref);
     821         5360 :   if (trait_reference->is_error ())
     822            3 :     return;
     823              : 
     824              :   // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
     825              :   // for example
     826        10714 :   specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
     827         5357 :                                               impl_block.get_polarity ());
     828              : 
     829              :   // need to check that if this specified bound has super traits does this
     830              :   // Self implement them?
     831         5357 :   specified_bound.validate_type_implements_super_traits (
     832         5357 :     *self, impl_block.get_type (), impl_block.get_trait_ref ());
     833              : 
     834         5357 :   std::map<DefId, AssocTypeEntry> assoc_types_by_trait_item;
     835         5357 :   std::vector<const TraitItemReference *> trait_item_refs;
     836         5357 :   ResolveImplTraitAssociatedTypes (context, impl_block, specified_bound, self,
     837              :                                    substitutions, assoc_types_by_trait_item,
     838              :                                    trait_item_refs);
     839              : 
     840         5357 :   ImplTraitContextFrame frame{trait_reference, self,
     841         5357 :                               std::move (assoc_types_by_trait_item)};
     842         5357 :   ImplTraitFrameGuard guard (frame);
     843        11557 :   for (auto &impl_item : impl_block.get_impl_items ())
     844              :     {
     845         6200 :       bool is_type_alias = impl_item->get_impl_item_type ()
     846         6200 :                            == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
     847         6200 :       if (is_type_alias)
     848         1430 :         continue;
     849              : 
     850         4770 :       auto trait_item_ref
     851         4770 :         = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
     852         4770 :                                                specified_bound, substitutions);
     853         4770 :       if (!trait_item_ref.is_error ())
     854         4765 :         trait_item_refs.push_back (trait_item_ref.get_raw_item ());
     855         4770 :     }
     856              : 
     857         5357 :   validate_trait_impl_block (specified_bound, trait_item_refs, trait_reference,
     858              :                              impl_block, self, substitutions);
     859              : 
     860         5357 :   AssociatedImplTrait associated (trait_reference, specified_bound, &impl_block,
     861         5357 :                                   self, frame);
     862         5357 :   context->insert_associated_trait_impl (
     863         5357 :     impl_block.get_mappings ().get_hirid (), std::move (associated));
     864         5357 :   context->insert_associated_impl_mapping (
     865         5357 :     trait_reference->get_mappings ().get_hirid (), self,
     866         5357 :     impl_block.get_mappings ().get_hirid ());
     867        10721 : }
     868              : 
     869              : void
     870         6784 : TypeCheckItem::ResolveImplTraitAssociatedTypes (
     871              :   TypeCheckContext *context, HIR::ImplBlock &impl_block,
     872              :   TyTy::TypeBoundPredicate &specified_bound, TyTy::BaseType *self,
     873              :   std::vector<TyTy::SubstitutionParamMapping> &substitutions,
     874              :   std::map<DefId, AssocTypeEntry> &assoc_types_by_trait_item,
     875              :   std::vector<const TraitItemReference *> &trait_item_refs)
     876              : {
     877        16778 :   for (auto &impl_item : impl_block.get_impl_items ())
     878              :     {
     879         9994 :       bool is_type_alias = impl_item->get_impl_item_type ()
     880         9994 :                            == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
     881         9994 :       if (!is_type_alias)
     882         7803 :         continue;
     883              : 
     884         2191 :       rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 1");
     885         2191 :       self->debug ();
     886         2191 :       auto trait_item_ref
     887         2191 :         = TypeCheckImplItemWithTrait::Resolve (impl_block, *impl_item, self,
     888         2191 :                                                specified_bound, substitutions);
     889         2191 :       rust_debug_loc (impl_item->get_locus (), "RESOLVE ITEM 2");
     890         2191 :       if (!trait_item_ref.is_error ())
     891              :         {
     892         2191 :           const TraitItemReference *tiref = trait_item_ref.get_raw_item ();
     893         2191 :           trait_item_refs.push_back (tiref);
     894              : 
     895         2191 :           DefId impl_item_defid = impl_item->get_impl_mappings ().get_defid ();
     896         2191 :           DefId trait_item_defid = tiref->get_mappings ().get_defid ();
     897         2191 :           TyTy::BaseType *impl_item_ty;
     898              : 
     899         2191 :           bool ok = context->lookup_type (
     900         2191 :             impl_item->get_impl_mappings ().get_hirid (), &impl_item_ty);
     901         2191 :           rust_assert (ok);
     902              : 
     903         2191 :           AssocTypeEntry entry
     904         2191 :             = {trait_item_defid, impl_item_defid, impl_item_ty};
     905         2191 :           assoc_types_by_trait_item[trait_item_defid] = std::move (entry);
     906              :         }
     907         2191 :     }
     908         6784 : }
     909              : 
     910              : TyTy::BaseType *
     911            1 : TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
     912              :                                   HIR::ImplItem &item)
     913              : {
     914            1 :   bool failed_flag = false;
     915            1 :   auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
     916            1 :   if (failed_flag)
     917              :     {
     918            1 :       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     919              :     }
     920              : 
     921            0 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     922            0 :     = std::move (result.first);
     923            0 :   TyTy::RegionConstraints region_constraints = std::move (result.second);
     924              : 
     925            0 :   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
     926              : 
     927            0 :   return TypeCheckImplItem::Resolve (impl_block, item, self, substitutions);
     928            1 : }
     929              : 
     930              : TyTy::FnType *
     931         7069 : TypeCheckItem::resolve_function_signature (HIR::Function &function)
     932              : {
     933         7069 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
     934         7069 :   if (function.has_generics ())
     935          688 :     resolve_generic_params (HIR::Item::ItemKind::Function,
     936              :                             function.get_locus (),
     937          688 :                             function.get_generic_params (), substitutions);
     938              : 
     939         7069 :   TyTy::RegionConstraints region_constraints;
     940         7069 :   ResolveWhereClauseItem::Resolve (function.get_where_clause (),
     941              :                                    region_constraints);
     942              : 
     943         7069 :   TyTy::BaseType *ret_type = nullptr;
     944         7069 :   if (!function.has_function_return_type ())
     945         3514 :     ret_type = TyTy::TupleType::get_unit_type ();
     946              :   else
     947              :     {
     948         3555 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
     949         3555 :       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
     950              :         return nullptr;
     951              : 
     952         3551 :       ret_type = resolved->clone ();
     953         3551 :       ret_type->set_ref (
     954         3551 :         function.get_return_type ().get_mappings ().get_hirid ());
     955              :     }
     956              : 
     957         7065 :   std::vector<TyTy::FnParam> params;
     958         9319 :   for (auto &param : function.get_function_params ())
     959              :     {
     960              :       // get the name as well required for later on
     961         2254 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     962         2254 :       context->insert_type (param.get_mappings (), param_tyty);
     963         2254 :       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     964         2254 :       params.emplace_back (param.get_param_name ().clone_pattern (),
     965              :                            param_tyty);
     966              :     }
     967              : 
     968         7065 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     969              : 
     970         7065 :   CanonicalPath path
     971         7065 :     = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
     972         7065 :                                 Resolver2_0::Namespace::Values);
     973              : 
     974         7065 :   RustIdent ident{path, function.get_locus ()};
     975              : 
     976         7065 :   auto fn_type = new TyTy::FnType (
     977         7065 :     function.get_mappings ().get_hirid (),
     978         7065 :     function.get_mappings ().get_defid (),
     979         7065 :     function.get_function_name ().as_string (), ident,
     980              :     TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
     981              :     std::move (substitutions),
     982        14130 :     TyTy::SubstitutionArgumentMappings::empty (
     983         7065 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     984        28260 :     region_constraints);
     985              : 
     986         7065 :   context->insert_type (function.get_mappings (), fn_type);
     987              : 
     988         7065 :   return fn_type;
     989        14134 : }
     990              : 
     991              : void
     992         7069 : TypeCheckItem::visit (HIR::Function &function)
     993              : {
     994         7069 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
     995              : 
     996         7069 :   TyTy::BaseType *resolved = nullptr;
     997         7069 :   TyTy::FnType *resolved_fn_type = nullptr;
     998         7069 :   if (context->lookup_type (function.get_mappings ().get_hirid (), &resolved))
     999              :     {
    1000          180 :       if (resolved->get_kind () != TyTy::TypeKind::FNDEF)
    1001              :         return;
    1002          180 :       resolved_fn_type = static_cast<TyTy::FnType *> (resolved);
    1003              :     }
    1004              :   else
    1005         6889 :     resolved_fn_type = resolve_function_signature (function);
    1006              : 
    1007         7069 :   if (resolved_fn_type == nullptr)
    1008              :     return;
    1009              : 
    1010              :   // Mark the body as claimed before resolving it.  Recursive queries from the
    1011              :   // body must reuse the cached signature rather than re-entering this body.
    1012         7065 :   context->clear_function_body_pending (resolved_fn_type->get_id ());
    1013              : 
    1014              :   // need to get the return type from this
    1015         7065 :   auto expected_ret_tyty = resolved_fn_type->get_return_type ();
    1016         7065 :   context->push_return_type (TypeCheckContextItem (&function),
    1017              :                              expected_ret_tyty);
    1018              : 
    1019         7065 :   context->switch_to_fn_body ();
    1020         7065 :   auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
    1021              : 
    1022              :   // emit check for
    1023              :   // error[E0121]: the type placeholder `_` is not allowed within types on item
    1024         7065 :   const auto placeholder = expected_ret_tyty->contains_infer ();
    1025         7065 :   if (placeholder != nullptr && function.has_return_type ())
    1026              :     {
    1027              :       // FIXME
    1028              :       // this will be a great place for the Default Hir Visitor we want to
    1029              :       // grab the locations of the placeholders (HIR::InferredType) their
    1030              :       // location, for now maybe we can use their hirid to lookup the location
    1031            3 :       location_t placeholder_locus
    1032            3 :         = mappings.lookup_location (placeholder->get_ref ());
    1033            3 :       location_t type_locus = function.get_return_type ().get_locus ();
    1034            3 :       rich_location r (line_table, placeholder_locus);
    1035              : 
    1036            3 :       bool have_expected_type
    1037            6 :         = block_expr_ty != nullptr && !block_expr_ty->is<TyTy::ErrorType> ();
    1038            3 :       if (!have_expected_type)
    1039              :         {
    1040            0 :           r.add_range (type_locus);
    1041              :         }
    1042              :       else
    1043              :         {
    1044            3 :           std::string fixit
    1045            3 :             = "replace with the correct type " + block_expr_ty->get_name ();
    1046            3 :           r.add_fixit_replace (type_locus, fixit.c_str ());
    1047            3 :         }
    1048              : 
    1049            3 :       rust_error_at (r, ErrorCode::E0121,
    1050              :                      "the type placeholder %<_%> is not allowed within types "
    1051              :                      "on item signatures");
    1052            3 :     }
    1053              : 
    1054         7065 :   location_t fn_return_locus = function.has_function_return_type ()
    1055         7065 :                                  ? function.get_return_type ().get_locus ()
    1056         3514 :                                  : function.get_locus ();
    1057        14130 :   coercion_site (function.get_definition ().get_mappings ().get_hirid (),
    1058         7065 :                  TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
    1059         7065 :                  TyTy::TyWithLocation (block_expr_ty),
    1060         7065 :                  function.get_definition ().get_locus ());
    1061              : 
    1062         7065 :   context->pop_return_type ();
    1063              : 
    1064         7065 :   infered = resolved_fn_type;
    1065         7069 : }
    1066              : 
    1067              : void
    1068         1257 : TypeCheckItem::visit (HIR::Module &module)
    1069              : {
    1070         5443 :   for (auto &item : module.get_items ())
    1071         4186 :     TypeCheckItem::Resolve (*item);
    1072         1257 : }
    1073              : 
    1074              : void
    1075         4229 : TypeCheckItem::visit (HIR::Trait &trait)
    1076              : {
    1077         4229 :   infered = resolve_trait (trait, true);
    1078         4229 : }
    1079              : 
    1080              : TyTy::BaseType *
    1081         4638 : TypeCheckItem::resolve_trait (HIR::Trait &trait, bool resolve_bodies)
    1082              : {
    1083         4638 :   auto lifetime_pin = context->push_clean_lifetime_resolver ();
    1084              : 
    1085         4638 :   if (trait.has_type_param_bounds ())
    1086              :     {
    1087         1733 :       for (auto &tp_bound : trait.get_type_param_bounds ())
    1088              :         {
    1089          942 :           if (tp_bound.get ()->get_bound_type ()
    1090              :               == HIR::TypeParamBound::BoundType::TRAITBOUND)
    1091              :             {
    1092          942 :               HIR::TraitBound &tb
    1093          942 :                 = static_cast<HIR::TraitBound &> (*tp_bound.get ());
    1094          942 :               if (tb.get_polarity () == BoundPolarity::AntiBound)
    1095              :                 {
    1096            1 :                   rust_error_at (tb.get_locus (),
    1097              :                                  "%<?Trait%> is not permitted in supertraits");
    1098              :                 }
    1099              :             }
    1100              :         }
    1101              :     }
    1102              : 
    1103         4638 :   TraitReference *trait_ref = TraitResolver::Resolve (trait);
    1104         4638 :   if (trait_ref->is_error ())
    1105              :     {
    1106            7 :       infered = new TyTy::ErrorType (trait.get_mappings ().get_hirid ());
    1107            7 :       return infered;
    1108              :     }
    1109              : 
    1110         4631 :   if (resolve_bodies)
    1111         4223 :     trait_ref->resolve_default_function_bodies ();
    1112              : 
    1113         4631 :   RustIdent ident{CanonicalPath::create_empty (), trait.get_locus ()};
    1114         4631 :   return new TyTy::DynamicObjectType (
    1115         4631 :     trait.get_mappings ().get_hirid (), ident,
    1116              :     {TyTy::TypeBoundPredicate (*trait_ref, BoundPolarity::RegularBound,
    1117         9262 :                                trait.get_locus ())});
    1118         4638 : }
    1119              : 
    1120              : void
    1121         1706 : TypeCheckItem::visit (HIR::ExternBlock &extern_block)
    1122              : {
    1123         4392 :   for (auto &item : extern_block.get_extern_items ())
    1124              :     {
    1125         2686 :       TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
    1126              :     }
    1127         1706 : }
    1128              : 
    1129              : void
    1130            0 : TypeCheckItem::visit (HIR::ExternCrate &extern_crate)
    1131              : {
    1132            0 :   if (extern_crate.references_self ())
    1133              :     return;
    1134              : 
    1135            0 :   auto &crate_mappings = Analysis::Mappings::get ().crate;
    1136            0 :   CrateNum num
    1137            0 :     = crate_mappings.lookup_crate_name (extern_crate.get_referenced_crate ())
    1138            0 :         .value ();
    1139            0 :   HIR::Crate &crate = mappings.get_hir_crate (num);
    1140              : 
    1141            0 :   CrateNum saved_crate_num = crate_mappings.get_current_crate ();
    1142            0 :   crate_mappings.set_current_crate (num);
    1143            0 :   for (auto &item : crate.get_items ())
    1144            0 :     TypeCheckItem::Resolve (*item);
    1145            0 :   crate_mappings.set_current_crate (saved_crate_num);
    1146              : }
    1147              : 
    1148              : std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
    1149        35040 : TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
    1150              :                                                  bool &failure_flag)
    1151              : {
    1152        35040 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
    1153        35040 :   if (impl_block.has_generics ())
    1154         4864 :     resolve_generic_params (HIR::Item::ItemKind::Impl, impl_block.get_locus (),
    1155         4864 :                             impl_block.get_generic_params (), substitutions);
    1156              : 
    1157        35040 :   TyTy::RegionConstraints region_constraints;
    1158        35040 :   ResolveWhereClauseItem::Resolve (impl_block.get_where_clause (),
    1159              :                                    region_constraints);
    1160              : 
    1161        35040 :   auto specified_bound = TyTy::TypeBoundPredicate::error ();
    1162        35040 :   TraitReference *trait_reference = &TraitReference::error_node ();
    1163        35040 :   if (impl_block.has_trait_ref ())
    1164              :     {
    1165        23452 :       auto &ref = impl_block.get_trait_ref ();
    1166        23452 :       trait_reference = TraitResolver::Resolve (ref);
    1167        23452 :       if (!trait_reference->is_error ())
    1168              :         {
    1169              :           // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
    1170              :           // for example
    1171        23449 :           specified_bound
    1172        46897 :             = get_predicate_from_bound (ref, impl_block.get_type (),
    1173        23448 :                                         impl_block.get_polarity ());
    1174              :         }
    1175              :     }
    1176              : 
    1177        35039 :   TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
    1178        35039 :   if (self->is<TyTy::ErrorType> ())
    1179              :     {
    1180              :       // we cannot check for unconstrained type arguments when the Self type is
    1181              :       // not resolved it will just add extra errors that dont help as well as
    1182              :       // the case where this could just be a recursive type query that should
    1183              :       // fail and will work later on anyway
    1184            1 :       return {substitutions, region_constraints};
    1185              :     }
    1186              : 
    1187              :   // inherit the bounds
    1188        35038 :   if (!specified_bound.is_error ())
    1189        23445 :     self->inherit_bound (specified_bound);
    1190              : 
    1191              :   // check for any unconstrained type-params
    1192        35038 :   const TyTy::SubstitutionArgumentMappings trait_constraints
    1193        35038 :     = specified_bound.get_substitution_arguments ();
    1194        35038 :   const TyTy::SubstitutionArgumentMappings impl_constraints
    1195        35038 :     = GetUsedSubstArgs::From (self);
    1196              : 
    1197        35038 :   failure_flag = check_for_unconstrained (substitutions, trait_constraints,
    1198              :                                           impl_constraints, self);
    1199              : 
    1200        35038 :   return {substitutions, region_constraints};
    1201        70078 : }
    1202              : 
    1203              : TyTy::BaseType *
    1204        32982 : TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
    1205              : {
    1206        32982 :   return TypeCheckType::Resolve (impl_block.get_type ());
    1207              : }
    1208              : 
    1209              : bool
    1210           14 : TypeCheckItem::validate_repr_simd (
    1211              :   const std::vector<TyTy::StructFieldType *> &fields, location_t locus)
    1212              : {
    1213           14 :   if (fields.empty ())
    1214              :     {
    1215            0 :       rust_error_at (locus, ErrorCode::E0075, "SIMD vector cannot be empty");
    1216            0 :       return false;
    1217              :     }
    1218              : 
    1219              :   // in 1.49, repr simd assumes all fields are same type with its size
    1220              :   // being power-of-two.
    1221              :   //
    1222              :   // TODO update this typecheck to make repr simd take in a single field
    1223              :   // of an array instead when we move past 1.49. Relevant Rust github
    1224              :   // issues/PRs:
    1225              :   // - https://github.com/rust-lang/compiler-team/issues/621
    1226              :   // - https://github.com/rust-lang/rust/pull/78863 (implemented
    1227              :   //   for 1.50.0)
    1228              : 
    1229           14 :   TyTy::BaseType *first_field_ty = fields.at (0)->get_field_type ();
    1230           14 :   TyTy::TypeKind ty_kind = first_field_ty->get_kind ();
    1231           14 :   bool fields_are_same_type = true;
    1232              : 
    1233           14 :   switch (ty_kind)
    1234              :     {
    1235            4 :     case TyTy::TypeKind::INT:
    1236            4 :       {
    1237            4 :         auto int_ty = static_cast<TyTy::IntType *> (first_field_ty);
    1238            4 :         auto int_kind = int_ty->get_int_kind ();
    1239           22 :         for (const auto field : fields)
    1240              :           {
    1241           18 :             if (field->get_field_type ()->get_kind () != ty_kind)
    1242              :               {
    1243              :                 fields_are_same_type = false;
    1244              :                 break;
    1245              :               }
    1246           18 :             auto field_int_ty
    1247           18 :               = static_cast<TyTy::IntType *> (field->get_field_type ());
    1248           18 :             if (field_int_ty->get_int_kind () != int_kind)
    1249              :               {
    1250              :                 fields_are_same_type = false;
    1251              :                 break;
    1252              :               }
    1253              :           }
    1254              :         break;
    1255              :       }
    1256            1 :     case TyTy::TypeKind::UINT:
    1257            1 :       {
    1258            1 :         auto uint_ty = static_cast<TyTy::UintType *> (first_field_ty);
    1259            1 :         auto uint_kind = uint_ty->get_uint_kind ();
    1260            5 :         for (const auto field : fields)
    1261              :           {
    1262            4 :             if (field->get_field_type ()->get_kind () != ty_kind)
    1263              :               {
    1264              :                 fields_are_same_type = false;
    1265              :                 break;
    1266              :               }
    1267            4 :             auto field_uint_ty
    1268            4 :               = static_cast<TyTy::UintType *> (field->get_field_type ());
    1269            4 :             if (field_uint_ty->get_uint_kind () != uint_kind)
    1270              :               {
    1271              :                 fields_are_same_type = false;
    1272              :                 break;
    1273              :               }
    1274              :           }
    1275              :         break;
    1276              :       }
    1277            8 :     case TyTy::TypeKind::FLOAT:
    1278            8 :       {
    1279            8 :         auto float_ty = static_cast<TyTy::FloatType *> (first_field_ty);
    1280            8 :         auto float_kind = float_ty->get_float_kind ();
    1281           54 :         for (const auto field : fields)
    1282              :           {
    1283           47 :             if (field->get_field_type ()->get_kind () != ty_kind)
    1284              :               {
    1285              :                 fields_are_same_type = false;
    1286              :                 break;
    1287              :               }
    1288           46 :             auto field_float_ty
    1289           46 :               = static_cast<TyTy::FloatType *> (field->get_field_type ());
    1290           46 :             if (field_float_ty->get_float_kind () != float_kind)
    1291              :               {
    1292              :                 fields_are_same_type = false;
    1293              :                 break;
    1294              :               }
    1295              :           }
    1296              :         break;
    1297              :       }
    1298            1 :     default:
    1299            1 :       rust_error_at (locus, ErrorCode::E0077,
    1300              :                      "SIMD vector element type should be a primitive scalar");
    1301            1 :       return false;
    1302              :     }
    1303              : 
    1304           13 :   if (!fields_are_same_type)
    1305              :     {
    1306            1 :       rust_error_at (locus, "SIMD struct fields should be of the same type");
    1307            1 :       return false;
    1308              :     }
    1309              : 
    1310              :   // check whether field count is power of 2
    1311           12 :   size_t field_count = fields.size ();
    1312           12 :   if ((field_count & (field_count - 1)) != 0)
    1313              :     {
    1314            1 :       rust_error_at (locus, "Size of SIMD struct must be a power of 2");
    1315            1 :       return false;
    1316              :     }
    1317              :   return true;
    1318              : }
    1319              : 
    1320              : } // namespace Resolver
    1321              : } // namespace Rust
        

Generated by: LCOV version 2.5.0-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.