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