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