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