LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.3 % 150 143
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
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.h"
      20              : #include "rust-hir-full.h"
      21              : #include "rust-hir-inherent-impl-overlap.h"
      22              : #include "rust-hir-pattern.h"
      23              : #include "rust-hir-type-check-expr.h"
      24              : #include "rust-hir-type-check-item.h"
      25              : #include "rust-hir-type-check-pattern.h"
      26              : #include "rust-hir-type-check-struct-field.h"
      27              : #include "rust-immutable-name-resolution-context.h"
      28              : 
      29              : extern bool saw_errors (void);
      30              : 
      31              : namespace Rust {
      32              : namespace Resolver {
      33              : 
      34              : tl::optional<TyTy::Region>
      35        29413 : TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
      36              : {
      37        29413 :   if (placeholder.is_static ())
      38           89 :     return TyTy::Region::make_static ();
      39              : 
      40        29324 :   if (placeholder == Lifetime::anonymous_lifetime ())
      41        29055 :     return TyTy::Region::make_anonymous ();
      42              : 
      43          311 :   for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
      44              :     {
      45          311 :       if (it->first == placeholder)
      46              :         {
      47          269 :           if (it->second.scope <= ITEM_SCOPE)
      48              :             {
      49              :               // It is useful to have the static lifetime and named
      50              :               // lifetimed disjoint so we add the +1 here.
      51          233 :               return (is_body)
      52          233 :                        ? TyTy::Region::make_named (it->second.index + 1)
      53          233 :                        : TyTy::Region::make_early_bound (it->second.index);
      54              :             }
      55              :           else
      56              :             {
      57           36 :               return TyTy::Region::make_late_bound (get_current_scope ()
      58           36 :                                                       - it->second.scope,
      59           36 :                                                     it->second.index);
      60              :             }
      61              :         }
      62              :     }
      63              : 
      64            0 :   return tl::nullopt;
      65              : }
      66              : 
      67              : void
      68         4301 : TypeResolution::Resolve (HIR::Crate &crate)
      69              : {
      70        21825 :   for (auto &it : crate.get_items ())
      71        17525 :     TypeCheckItem::Resolve (*it);
      72              : 
      73         4300 :   if (saw_errors ())
      74              :     return;
      75              : 
      76         4130 :   OverlappingImplItemPass::go ();
      77         4130 :   if (saw_errors ())
      78              :     return;
      79              : 
      80         4129 :   auto context = TypeCheckContext::get ();
      81         4129 :   context->compute_inference_variables (true);
      82              : }
      83              : 
      84              : // rust-hir-trait-ref.h
      85              : 
      86         6934 : TraitItemReference::TraitItemReference (
      87              :   std::string identifier, bool optional, TraitItemType type,
      88              :   HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
      89         6934 :   std::vector<TyTy::SubstitutionParamMapping> substitutions, location_t locus)
      90         6934 :   : identifier (identifier), optional_flag (optional), type (type),
      91         6934 :     hir_trait_item (hir_trait_item),
      92         6934 :     inherited_substitutions (std::move (substitutions)), locus (locus),
      93         6934 :     self (self), context (TypeCheckContext::get ())
      94         6934 : {}
      95              : 
      96        15148 : TraitItemReference::TraitItemReference (TraitItemReference const &other)
      97        15148 :   : identifier (other.identifier), optional_flag (other.optional_flag),
      98        15148 :     type (other.type), hir_trait_item (other.hir_trait_item),
      99        15148 :     locus (other.locus), self (other.self), context (TypeCheckContext::get ())
     100              : {
     101        15148 :   inherited_substitutions.clear ();
     102        15148 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     103        37008 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     104        43720 :     inherited_substitutions.push_back (
     105        21860 :       other.inherited_substitutions.at (i).clone ());
     106        15148 : }
     107              : 
     108              : TraitItemReference &
     109         3310 : TraitItemReference::operator= (TraitItemReference const &other)
     110              : {
     111         3310 :   identifier = other.identifier;
     112         3310 :   optional_flag = other.optional_flag;
     113         3310 :   type = other.type;
     114         3310 :   hir_trait_item = other.hir_trait_item;
     115         3310 :   self = other.self;
     116         3310 :   locus = other.locus;
     117         3310 :   context = other.context;
     118              : 
     119         3310 :   inherited_substitutions.clear ();
     120         3310 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     121         8045 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     122         9470 :     inherited_substitutions.push_back (
     123         4735 :       other.inherited_substitutions.at (i).clone ());
     124              : 
     125         3310 :   return *this;
     126              : }
     127              : 
     128              : TyTy::BaseType *
     129        21251 : TraitItemReference::get_type_from_typealias (/*const*/
     130              :                                              HIR::TraitItemType &type) const
     131              : {
     132        21251 :   TyTy::TyVar var (get_mappings ().get_hirid ());
     133        21251 :   return var.get_tyty ();
     134              : }
     135              : 
     136              : TyTy::BaseType *
     137           31 : TraitItemReference::get_type_from_constant (
     138              :   /*const*/ HIR::TraitItemConst &constant) const
     139              : {
     140           31 :   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
     141           31 :   if (constant.has_expr ())
     142              :     {
     143            7 :       TyTy::BaseType *expr = TypeCheckExpr::Resolve (constant.get_expr ());
     144              : 
     145           14 :       return unify_site (constant.get_mappings ().get_hirid (),
     146            7 :                          TyTy::TyWithLocation (type),
     147            7 :                          TyTy::TyWithLocation (expr), constant.get_locus ());
     148              :     }
     149              :   return type;
     150              : }
     151              : 
     152              : TyTy::BaseType *
     153        24737 : TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     154              : {
     155        24737 :   auto binder_pin = context->push_clean_lifetime_resolver ();
     156              : 
     157        24737 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     158        24737 :     = inherited_substitutions;
     159              : 
     160        24737 :   TyTy::RegionConstraints region_constraints;
     161        24737 :   HIR::TraitFunctionDecl &function = fn.get_decl ();
     162        24737 :   if (function.has_generics ())
     163              :     {
     164           43 :       TypeCheckBase::ResolveGenericParams (HIR::Item::ItemKind::Function,
     165              :                                            fn.get_locus (),
     166           43 :                                            function.get_generic_params (),
     167              :                                            substitutions, false /*is_foreign*/,
     168              :                                            ABI::RUST);
     169              :     }
     170              : 
     171        24737 :   if (function.has_where_clause ())
     172              :     {
     173            0 :       for (auto &where_clause_item : function.get_where_clause ().get_items ())
     174            0 :         ResolveWhereClauseItem::Resolve (*where_clause_item,
     175              :                                          region_constraints);
     176              :     }
     177              : 
     178        24737 :   TyTy::BaseType *ret_type = nullptr;
     179        24737 :   if (!function.has_return_type ())
     180         1378 :     ret_type = TyTy::TupleType::get_unit_type ();
     181              :   else
     182              :     {
     183        23359 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
     184        23359 :       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
     185              :         {
     186            2 :           rust_error_at (fn.get_locus (), "failed to resolve return type");
     187            2 :           return get_error ();
     188              :         }
     189              : 
     190        23357 :       ret_type = resolved->clone ();
     191        23357 :       ret_type->set_ref (
     192        23357 :         function.get_return_type ().get_mappings ().get_hirid ());
     193              :     }
     194              : 
     195        24735 :   std::vector<TyTy::FnParam> params;
     196              : 
     197        24735 :   if (function.is_method ())
     198              :     {
     199              :       // these are implicit mappings and not used
     200        23791 :       auto &mappings = Analysis::Mappings::get ();
     201        23791 :       auto crate_num = mappings.get_current_crate ();
     202        23791 :       Analysis::NodeMapping mapping (crate_num, mappings.get_next_node_id (),
     203              :                                      mappings.get_next_hir_id (crate_num),
     204        23791 :                                      UNKNOWN_LOCAL_DEFID);
     205              : 
     206              :       // add the synthetic self param at the front, this is a placeholder
     207              :       // for compilation to know parameter names. The types are ignored
     208              :       // but we reuse the HIR identifier pattern which requires it
     209        23791 :       HIR::SelfParam &self_param = function.get_self_unchecked ();
     210        23791 :       std::unique_ptr<HIR::Pattern> self_pattern
     211        23791 :         = std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
     212        23791 :           mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
     213        23791 :           self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
     214       118955 :           std::unique_ptr<HIR::Pattern> (nullptr)));
     215              :       // might have a specified type
     216        23791 :       TyTy::BaseType *self_type = nullptr;
     217        23791 :       if (self_param.has_type ())
     218              :         {
     219            0 :           HIR::Type &specified_type = self_param.get_type ();
     220            0 :           self_type = TypeCheckType::Resolve (specified_type);
     221              :         }
     222              :       else
     223              :         {
     224        23791 :           switch (self_param.get_self_kind ())
     225              :             {
     226         1726 :             case HIR::SelfParam::IMM:
     227         1726 :             case HIR::SelfParam::MUT:
     228         1726 :               self_type = self->clone ();
     229         1726 :               break;
     230              : 
     231        22065 :             case HIR::SelfParam::IMM_REF:
     232        22065 :             case HIR::SelfParam::MUT_REF:
     233        22065 :               {
     234        22065 :                 auto mutability
     235        22065 :                   = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
     236        22065 :                       ? Mutability::Imm
     237        22065 :                       : Mutability::Mut;
     238        22065 :                 rust_assert (self_param.has_lifetime ());
     239              : 
     240        22065 :                 auto region = TyTy::Region::make_anonymous ();
     241        22065 :                 auto maybe_region = context->lookup_and_resolve_lifetime (
     242        22065 :                   self_param.get_lifetime ());
     243        22065 :                 if (maybe_region.has_value ())
     244        22064 :                   region = maybe_region.value ();
     245              :                 else
     246              :                   {
     247            1 :                     rust_error_at (self_param.get_locus (),
     248              :                                    "failed to resolve lifetime");
     249              :                   }
     250              : 
     251        44130 :                 self_type = new TyTy::ReferenceType (
     252        22065 :                   self_param.get_mappings ().get_hirid (),
     253        22065 :                   TyTy::TyVar (self->get_ref ()), mutability, region);
     254              :               }
     255        22065 :               break;
     256              : 
     257            0 :             default:
     258            0 :               rust_unreachable ();
     259              :               return nullptr;
     260              :             }
     261              :         }
     262              : 
     263        23791 :       context->insert_type (self_param.get_mappings (), self_type);
     264        23791 :       params.emplace_back (std::move (self_pattern), self_type);
     265        23791 :     }
     266              : 
     267        44228 :   for (auto &param : function.get_function_params ())
     268              :     {
     269              :       // get the name as well required for later on
     270        19493 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     271        19493 :       context->insert_type (param.get_mappings (), param_tyty);
     272        19493 :       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     273              :       // FIXME: Should we take the name ? Use a shared pointer instead ?
     274        19493 :       params.emplace_back (param.get_param_name ().clone_pattern (),
     275              :                            param_tyty);
     276              :     }
     277              : 
     278        24735 :   auto &nr_ctx
     279        24735 :     = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     280              : 
     281        24735 :   CanonicalPath canonical_path
     282        24735 :     = nr_ctx.to_canonical_path (fn.get_mappings ().get_nodeid ());
     283              : 
     284        49470 :   RustIdent ident{canonical_path, fn.get_locus ()};
     285        24735 :   auto resolved = new TyTy::FnType (
     286        49470 :     fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
     287        24735 :     function.get_function_name ().as_string (), ident,
     288        24735 :     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
     289              :                           : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     290              :     ABI::RUST, std::move (params), ret_type, substitutions,
     291        49470 :     TyTy::SubstitutionArgumentMappings::empty (
     292        24735 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     293       123675 :     region_constraints);
     294        24735 :   context->insert_type (fn.get_mappings (), resolved);
     295        24735 :   return resolved;
     296        49472 : }
     297              : 
     298              : } // namespace Resolver
     299              : } // 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.