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: 94.0 % 151 142
Test Date: 2025-08-30 13:27:53 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 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                 :       29235 : TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
      36                 :             : {
      37                 :       29235 :   if (placeholder.is_static ())
      38                 :          87 :     return TyTy::Region::make_static ();
      39                 :             : 
      40                 :       29148 :   if (placeholder == Lifetime::anonymous_lifetime ())
      41                 :       28888 :     return TyTy::Region::make_anonymous ();
      42                 :             : 
      43                 :         302 :   for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
      44                 :             :     {
      45                 :         302 :       if (it->first == placeholder)
      46                 :             :         {
      47                 :         260 :           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                 :         224 :               return (is_body)
      52                 :         224 :                        ? TyTy::Region::make_named (it->second.index + 1)
      53                 :         224 :                        : 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                 :        4118 : TypeResolution::Resolve (HIR::Crate &crate)
      69                 :             : {
      70                 :       21172 :   for (auto &it : crate.get_items ())
      71                 :       17055 :     TypeCheckItem::Resolve (*it);
      72                 :             : 
      73                 :        4117 :   if (saw_errors ())
      74                 :             :     return;
      75                 :             : 
      76                 :        3962 :   OverlappingImplItemPass::go ();
      77                 :        3962 :   if (saw_errors ())
      78                 :             :     return;
      79                 :             : 
      80                 :        3961 :   auto context = TypeCheckContext::get ();
      81                 :        3961 :   context->compute_inference_variables (true);
      82                 :             : }
      83                 :             : 
      84                 :             : // rust-hir-trait-ref.h
      85                 :             : 
      86                 :        6868 : TraitItemReference::TraitItemReference (
      87                 :             :   std::string identifier, bool optional, TraitItemType type,
      88                 :             :   HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
      89                 :        6868 :   std::vector<TyTy::SubstitutionParamMapping> substitutions, location_t locus)
      90                 :        6868 :   : identifier (identifier), optional_flag (optional), type (type),
      91                 :        6868 :     hir_trait_item (hir_trait_item),
      92                 :        6868 :     inherited_substitutions (std::move (substitutions)), locus (locus),
      93                 :        6868 :     self (self), context (TypeCheckContext::get ())
      94                 :        6868 : {}
      95                 :             : 
      96                 :       15013 : TraitItemReference::TraitItemReference (TraitItemReference const &other)
      97                 :       15013 :   : identifier (other.identifier), optional_flag (other.optional_flag),
      98                 :       15013 :     type (other.type), hir_trait_item (other.hir_trait_item),
      99                 :       15013 :     locus (other.locus), self (other.self), context (TypeCheckContext::get ())
     100                 :             : {
     101                 :       15013 :   inherited_substitutions.clear ();
     102                 :       15013 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     103                 :       36693 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     104                 :       43360 :     inherited_substitutions.push_back (
     105                 :       21680 :       other.inherited_substitutions.at (i).clone ());
     106                 :       15013 : }
     107                 :             : 
     108                 :             : TraitItemReference &
     109                 :        3278 : TraitItemReference::operator= (TraitItemReference const &other)
     110                 :             : {
     111                 :        3278 :   identifier = other.identifier;
     112                 :        3278 :   optional_flag = other.optional_flag;
     113                 :        3278 :   type = other.type;
     114                 :        3278 :   hir_trait_item = other.hir_trait_item;
     115                 :        3278 :   self = other.self;
     116                 :        3278 :   locus = other.locus;
     117                 :        3278 :   context = other.context;
     118                 :             : 
     119                 :        3278 :   inherited_substitutions.clear ();
     120                 :        3278 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     121                 :        7971 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     122                 :        9386 :     inherited_substitutions.push_back (
     123                 :        4693 :       other.inherited_substitutions.at (i).clone ());
     124                 :             : 
     125                 :        3278 :   return *this;
     126                 :             : }
     127                 :             : 
     128                 :             : TyTy::BaseType *
     129                 :        6938 : TraitItemReference::get_type_from_typealias (/*const*/
     130                 :             :                                              HIR::TraitItemType &type) const
     131                 :             : {
     132                 :        6938 :   TyTy::TyVar var (get_mappings ().get_hirid ());
     133                 :        6938 :   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                 :       24605 : TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     154                 :             : {
     155                 :       24605 :   auto binder_pin = context->push_clean_lifetime_resolver ();
     156                 :             : 
     157                 :       24605 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     158                 :       24605 :     = inherited_substitutions;
     159                 :             : 
     160                 :       24605 :   TyTy::RegionConstraints region_constraints;
     161                 :       24605 :   HIR::TraitFunctionDecl &function = fn.get_decl ();
     162                 :       24605 :   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                 :       24605 :   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                 :       24605 :   TyTy::BaseType *ret_type = nullptr;
     179                 :       24605 :   if (!function.has_return_type ())
     180                 :        1371 :     ret_type = TyTy::TupleType::get_unit_type ();
     181                 :             :   else
     182                 :             :     {
     183                 :       23234 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
     184                 :       23234 :       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                 :       23232 :       ret_type = resolved->clone ();
     191                 :       23232 :       ret_type->set_ref (
     192                 :       23232 :         function.get_return_type ().get_mappings ().get_hirid ());
     193                 :             :     }
     194                 :             : 
     195                 :       24603 :   std::vector<TyTy::FnParam> params;
     196                 :             : 
     197                 :       24603 :   if (function.is_method ())
     198                 :             :     {
     199                 :             :       // these are implicit mappings and not used
     200                 :       23662 :       auto &mappings = Analysis::Mappings::get ();
     201                 :       23662 :       auto crate_num = mappings.get_current_crate ();
     202                 :       23662 :       Analysis::NodeMapping mapping (crate_num, mappings.get_next_node_id (),
     203                 :             :                                      mappings.get_next_hir_id (crate_num),
     204                 :       23662 :                                      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                 :       23662 :       HIR::SelfParam &self_param = function.get_self_unchecked ();
     210                 :       23662 :       std::unique_ptr<HIR::Pattern> self_pattern
     211                 :       23662 :         = std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
     212                 :       23662 :           mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
     213                 :       23662 :           self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
     214                 :      118310 :           std::unique_ptr<HIR::Pattern> (nullptr)));
     215                 :             :       // might have a specified type
     216                 :       23662 :       TyTy::BaseType *self_type = nullptr;
     217                 :       23662 :       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                 :       23662 :           switch (self_param.get_self_kind ())
     225                 :             :             {
     226                 :        1723 :             case HIR::SelfParam::IMM:
     227                 :        1723 :             case HIR::SelfParam::MUT:
     228                 :        1723 :               self_type = self->clone ();
     229                 :        1723 :               break;
     230                 :             : 
     231                 :       21939 :             case HIR::SelfParam::IMM_REF:
     232                 :       21939 :             case HIR::SelfParam::MUT_REF:
     233                 :       21939 :               {
     234                 :       21939 :                 auto mutability
     235                 :       21939 :                   = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
     236                 :       21939 :                       ? Mutability::Imm
     237                 :       21939 :                       : Mutability::Mut;
     238                 :       21939 :                 rust_assert (self_param.has_lifetime ());
     239                 :             : 
     240                 :       21939 :                 auto maybe_region = context->lookup_and_resolve_lifetime (
     241                 :       21939 :                   self_param.get_lifetime ());
     242                 :             : 
     243                 :       21939 :                 if (!maybe_region.has_value ())
     244                 :             :                   {
     245                 :           0 :                     rust_error_at (self_param.get_locus (),
     246                 :             :                                    "failed to resolve lifetime");
     247                 :           0 :                     return get_error ();
     248                 :             :                   }
     249                 :       43878 :                 self_type = new TyTy::ReferenceType (
     250                 :       43878 :                   self_param.get_mappings ().get_hirid (),
     251                 :       21939 :                   TyTy::TyVar (self->get_ref ()), mutability,
     252                 :       43878 :                   maybe_region.value ());
     253                 :             :               }
     254                 :       21939 :               break;
     255                 :             : 
     256                 :           0 :             default:
     257                 :           0 :               rust_unreachable ();
     258                 :             :               return nullptr;
     259                 :             :             }
     260                 :             :         }
     261                 :             : 
     262                 :       23662 :       context->insert_type (self_param.get_mappings (), self_type);
     263                 :       23662 :       params.push_back (TyTy::FnParam (std::move (self_pattern), self_type));
     264                 :       23662 :     }
     265                 :             : 
     266                 :       43983 :   for (auto &param : function.get_function_params ())
     267                 :             :     {
     268                 :             :       // get the name as well required for later on
     269                 :       19380 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     270                 :       19380 :       context->insert_type (param.get_mappings (), param_tyty);
     271                 :       19380 :       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     272                 :             :       // FIXME: Should we take the name ? Use a shared pointer instead ?
     273                 :       38760 :       params.push_back (
     274                 :       38760 :         TyTy::FnParam (param.get_param_name ().clone_pattern (), param_tyty));
     275                 :             :     }
     276                 :             : 
     277                 :       24603 :   auto &nr_ctx
     278                 :       24603 :     = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
     279                 :             : 
     280                 :       24603 :   CanonicalPath canonical_path
     281                 :       49206 :     = nr_ctx.to_canonical_path (fn.get_mappings ().get_nodeid ());
     282                 :             : 
     283                 :       49206 :   RustIdent ident{canonical_path, fn.get_locus ()};
     284                 :       24603 :   auto resolved = new TyTy::FnType (
     285                 :       49206 :     fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
     286                 :       24603 :     function.get_function_name ().as_string (), ident,
     287                 :       24603 :     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
     288                 :             :                           : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     289                 :             :     ABI::RUST, std::move (params), ret_type, substitutions,
     290                 :       49206 :     TyTy::SubstitutionArgumentMappings::empty (
     291                 :       24603 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     292                 :      123015 :     region_constraints);
     293                 :       24603 :   context->insert_type (fn.get_mappings (), resolved);
     294                 :       24603 :   return resolved;
     295                 :       49208 : }
     296                 :             : 
     297                 :             : } // namespace Resolver
     298                 :             : } // namespace Rust
        

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