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: 88.5 % 165 146
Test Date: 2025-03-08 13:07:09 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-type-check-expr.h"
      23                 :             : #include "rust-hir-type-check-item.h"
      24                 :             : #include "rust-hir-type-check-pattern.h"
      25                 :             : #include "rust-hir-type-check-struct-field.h"
      26                 :             : 
      27                 :             : extern bool
      28                 :             : saw_errors (void);
      29                 :             : 
      30                 :             : namespace Rust {
      31                 :             : namespace Resolver {
      32                 :             : 
      33                 :             : tl::optional<TyTy::Region>
      34                 :        6206 : TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
      35                 :             : {
      36                 :        6206 :   if (placeholder.is_static ())
      37                 :          12 :     return TyTy::Region::make_static ();
      38                 :             : 
      39                 :        6194 :   if (placeholder == Lifetime::anonymous_lifetime ())
      40                 :        5977 :     return TyTy::Region::make_anonymous ();
      41                 :             : 
      42                 :         247 :   for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
      43                 :             :     {
      44                 :         247 :       if (it->first == placeholder)
      45                 :             :         {
      46                 :         217 :           if (it->second.scope <= ITEM_SCOPE)
      47                 :             :             {
      48                 :             :               // It is useful to have the static lifetime and named
      49                 :             :               // lifetimed disjoint so we add the +1 here.
      50                 :         181 :               return (is_body)
      51                 :         181 :                        ? TyTy::Region::make_named (it->second.index + 1)
      52                 :         181 :                        : TyTy::Region::make_early_bound (it->second.index);
      53                 :             :             }
      54                 :             :           else
      55                 :             :             {
      56                 :          36 :               return TyTy::Region::make_late_bound (get_current_scope ()
      57                 :          36 :                                                       - it->second.scope,
      58                 :          36 :                                                     it->second.index);
      59                 :             :             }
      60                 :             :         }
      61                 :             :     }
      62                 :             : 
      63                 :           0 :   return tl::nullopt;
      64                 :             : }
      65                 :             : 
      66                 :             : void
      67                 :        3480 : TypeResolution::Resolve (HIR::Crate &crate)
      68                 :             : {
      69                 :       16632 :   for (auto &it : crate.get_items ())
      70                 :       13155 :     TypeCheckItem::Resolve (*it);
      71                 :             : 
      72                 :        3477 :   if (saw_errors ())
      73                 :             :     return;
      74                 :             : 
      75                 :        3373 :   OverlappingImplItemPass::go ();
      76                 :        3373 :   if (saw_errors ())
      77                 :             :     return;
      78                 :             : 
      79                 :        3372 :   auto context = TypeCheckContext::get ();
      80                 :        3372 :   context->compute_inference_variables (true);
      81                 :             : }
      82                 :             : 
      83                 :             : // rust-hir-trait-ref.h
      84                 :             : 
      85                 :        3167 : TraitItemReference::TraitItemReference (
      86                 :             :   std::string identifier, bool optional, TraitItemType type,
      87                 :             :   HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
      88                 :        3167 :   std::vector<TyTy::SubstitutionParamMapping> substitutions, location_t locus)
      89                 :        3167 :   : identifier (identifier), optional_flag (optional), type (type),
      90                 :        3167 :     hir_trait_item (hir_trait_item),
      91                 :        3167 :     inherited_substitutions (std::move (substitutions)), locus (locus),
      92                 :        3167 :     self (self), context (TypeCheckContext::get ())
      93                 :        3167 : {}
      94                 :             : 
      95                 :        6813 : TraitItemReference::TraitItemReference (TraitItemReference const &other)
      96                 :        6813 :   : identifier (other.identifier), optional_flag (other.optional_flag),
      97                 :        6813 :     type (other.type), hir_trait_item (other.hir_trait_item),
      98                 :        6813 :     locus (other.locus), self (other.self), context (TypeCheckContext::get ())
      99                 :             : {
     100                 :        6813 :   inherited_substitutions.clear ();
     101                 :        6813 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     102                 :       16336 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     103                 :       19046 :     inherited_substitutions.push_back (
     104                 :        9523 :       other.inherited_substitutions.at (i).clone ());
     105                 :        6813 : }
     106                 :             : 
     107                 :             : TraitItemReference &
     108                 :        1521 : TraitItemReference::operator= (TraitItemReference const &other)
     109                 :             : {
     110                 :        1521 :   identifier = other.identifier;
     111                 :        1521 :   optional_flag = other.optional_flag;
     112                 :        1521 :   type = other.type;
     113                 :        1521 :   hir_trait_item = other.hir_trait_item;
     114                 :        1521 :   self = other.self;
     115                 :        1521 :   locus = other.locus;
     116                 :        1521 :   context = other.context;
     117                 :             : 
     118                 :        1521 :   inherited_substitutions.clear ();
     119                 :        1521 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     120                 :        3641 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     121                 :        4240 :     inherited_substitutions.push_back (
     122                 :        2120 :       other.inherited_substitutions.at (i).clone ());
     123                 :             : 
     124                 :        1521 :   return *this;
     125                 :             : }
     126                 :             : 
     127                 :             : TyTy::BaseType *
     128                 :        5986 : TraitItemReference::get_type_from_typealias (/*const*/
     129                 :             :                                              HIR::TraitItemType &type) const
     130                 :             : {
     131                 :        5986 :   TyTy::TyVar var (get_mappings ().get_hirid ());
     132                 :        5986 :   return var.get_tyty ();
     133                 :             : }
     134                 :             : 
     135                 :             : TyTy::BaseType *
     136                 :          29 : TraitItemReference::get_type_from_constant (
     137                 :             :   /*const*/ HIR::TraitItemConst &constant) const
     138                 :             : {
     139                 :          29 :   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
     140                 :          29 :   if (constant.has_expr ())
     141                 :             :     {
     142                 :           7 :       TyTy::BaseType *expr
     143                 :           7 :         = TypeCheckExpr::Resolve (constant.get_expr ().get ());
     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                 :        5321 : TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     154                 :             : {
     155                 :        5321 :   auto binder_pin = context->push_clean_lifetime_resolver ();
     156                 :             : 
     157                 :        5321 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     158                 :        5321 :     = inherited_substitutions;
     159                 :             : 
     160                 :        5321 :   TyTy::RegionConstraints region_constraints;
     161                 :        5321 :   HIR::TraitFunctionDecl &function = fn.get_decl ();
     162                 :        5321 :   if (function.has_generics ())
     163                 :             :     {
     164                 :          28 :       for (auto &generic_param : function.get_generic_params ())
     165                 :             :         {
     166                 :          14 :           switch (generic_param.get ()->get_kind ())
     167                 :             :             {
     168                 :           0 :               case HIR::GenericParam::GenericKind::LIFETIME: {
     169                 :           0 :                 auto lifetime_param
     170                 :           0 :                   = static_cast<HIR::LifetimeParam &> (*generic_param);
     171                 :             : 
     172                 :           0 :                 context->intern_and_insert_lifetime (
     173                 :           0 :                   lifetime_param.get_lifetime ());
     174                 :             :                 // TODO: Handle lifetime bounds
     175                 :           0 :               }
     176                 :           0 :               break;
     177                 :             :             case HIR::GenericParam::GenericKind::CONST:
     178                 :             :               // FIXME: Skipping Lifetime and Const completely until better
     179                 :             :               // handling.
     180                 :             :               break;
     181                 :             : 
     182                 :          14 :               case HIR::GenericParam::GenericKind::TYPE: {
     183                 :          14 :                 auto param_type
     184                 :          14 :                   = TypeResolveGenericParam::Resolve (generic_param.get ());
     185                 :          14 :                 context->insert_type (generic_param->get_mappings (),
     186                 :             :                                       param_type);
     187                 :             : 
     188                 :          14 :                 substitutions.push_back (TyTy::SubstitutionParamMapping (
     189                 :          14 :                   static_cast<HIR::TypeParam &> (*generic_param), param_type));
     190                 :             :               }
     191                 :          14 :               break;
     192                 :             :             }
     193                 :             :         }
     194                 :             :     }
     195                 :             : 
     196                 :        5321 :   if (function.has_where_clause ())
     197                 :             :     {
     198                 :           0 :       for (auto &where_clause_item : function.get_where_clause ().get_items ())
     199                 :           0 :         ResolveWhereClauseItem::Resolve (*where_clause_item,
     200                 :             :                                          region_constraints);
     201                 :             :     }
     202                 :             : 
     203                 :        5321 :   TyTy::BaseType *ret_type = nullptr;
     204                 :        5321 :   if (!function.has_return_type ())
     205                 :         560 :     ret_type = TyTy::TupleType::get_unit_type (fn.get_mappings ().get_hirid ());
     206                 :             :   else
     207                 :             :     {
     208                 :        4761 :       auto resolved
     209                 :        4761 :         = TypeCheckType::Resolve (function.get_return_type ().get ());
     210                 :        4761 :       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
     211                 :             :         {
     212                 :           0 :           rust_error_at (fn.get_locus (), "failed to resolve return type");
     213                 :           0 :           return get_error ();
     214                 :             :         }
     215                 :             : 
     216                 :        4761 :       ret_type = resolved->clone ();
     217                 :        4761 :       ret_type->set_ref (
     218                 :        9522 :         function.get_return_type ()->get_mappings ().get_hirid ());
     219                 :             :     }
     220                 :             : 
     221                 :       10642 :   std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
     222                 :        5321 :   if (function.is_method ())
     223                 :             :     {
     224                 :             :       // these are implicit mappings and not used
     225                 :        4743 :       auto mappings = Analysis::Mappings::get ();
     226                 :        4743 :       auto crate_num = mappings->get_current_crate ();
     227                 :        4743 :       Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id (),
     228                 :             :                                      mappings->get_next_hir_id (crate_num),
     229                 :        4743 :                                      UNKNOWN_LOCAL_DEFID);
     230                 :             : 
     231                 :             :       // add the synthetic self param at the front, this is a placeholder
     232                 :             :       // for compilation to know parameter names. The types are ignored
     233                 :             :       // but we reuse the HIR identifier pattern which requires it
     234                 :        4743 :       HIR::SelfParam &self_param = function.get_self ();
     235                 :        4743 :       HIR::IdentifierPattern *self_pattern = new HIR::IdentifierPattern (
     236                 :        4743 :         mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
     237                 :        4743 :         self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
     238                 :        9308 :         std::unique_ptr<HIR::Pattern> (nullptr));
     239                 :             :       // might have a specified type
     240                 :        4743 :       TyTy::BaseType *self_type = nullptr;
     241                 :        4743 :       if (self_param.has_type ())
     242                 :             :         {
     243                 :           0 :           std::unique_ptr<HIR::Type> &specified_type = self_param.get_type ();
     244                 :           0 :           self_type = TypeCheckType::Resolve (specified_type.get ());
     245                 :             :         }
     246                 :             :       else
     247                 :             :         {
     248                 :        4743 :           switch (self_param.get_self_kind ())
     249                 :             :             {
     250                 :        1577 :             case HIR::SelfParam::IMM:
     251                 :        1577 :             case HIR::SelfParam::MUT:
     252                 :        1577 :               self_type = self->clone ();
     253                 :        1577 :               break;
     254                 :             : 
     255                 :        3166 :             case HIR::SelfParam::IMM_REF:
     256                 :        3166 :               case HIR::SelfParam::MUT_REF: {
     257                 :        3166 :                 auto mutability
     258                 :        3166 :                   = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
     259                 :        3166 :                       ? Mutability::Imm
     260                 :        3166 :                       : Mutability::Mut;
     261                 :        3166 :                 rust_assert (self_param.has_lifetime ());
     262                 :             : 
     263                 :        3166 :                 auto maybe_region = context->lookup_and_resolve_lifetime (
     264                 :        3166 :                   self_param.get_lifetime ());
     265                 :             : 
     266                 :        3166 :                 if (!maybe_region.has_value ())
     267                 :             :                   {
     268                 :           0 :                     rust_error_at (self_param.get_locus (),
     269                 :             :                                    "failed to resolve lifetime");
     270                 :           0 :                     return get_error ();
     271                 :             :                   }
     272                 :        6332 :                 self_type = new TyTy::ReferenceType (
     273                 :        6332 :                   self_param.get_mappings ().get_hirid (),
     274                 :        3166 :                   TyTy::TyVar (self->get_ref ()), mutability,
     275                 :        6332 :                   maybe_region.value ());
     276                 :             :               }
     277                 :        3166 :               break;
     278                 :             : 
     279                 :           0 :             default:
     280                 :           0 :               rust_unreachable ();
     281                 :             :               return nullptr;
     282                 :             :             }
     283                 :             :         }
     284                 :             : 
     285                 :        4743 :       context->insert_type (self_param.get_mappings (), self_type);
     286                 :        4743 :       params.push_back (
     287                 :        4743 :         std::pair<HIR::Pattern *, TyTy::BaseType *> (self_pattern, self_type));
     288                 :             :     }
     289                 :             : 
     290                 :        7286 :   for (auto &param : function.get_function_params ())
     291                 :             :     {
     292                 :             :       // get the name as well required for later on
     293                 :        1965 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
     294                 :        1965 :       params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
     295                 :        1965 :         param.get_param_name ().get (), param_tyty));
     296                 :             : 
     297                 :        1965 :       context->insert_type (param.get_mappings (), param_tyty);
     298                 :        1965 :       TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
     299                 :             :     }
     300                 :             : 
     301                 :        5321 :   auto mappings = Analysis::Mappings::get ();
     302                 :        5321 :   const CanonicalPath *canonical_path = nullptr;
     303                 :        5321 :   bool ok = mappings->lookup_canonical_path (fn.get_mappings ().get_nodeid (),
     304                 :             :                                              &canonical_path);
     305                 :           0 :   rust_assert (ok);
     306                 :             : 
     307                 :       10642 :   RustIdent ident{*canonical_path, fn.get_locus ()};
     308                 :        5321 :   auto resolved = new TyTy::FnType (
     309                 :       10642 :     fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
     310                 :        5321 :     function.get_function_name ().as_string (), ident,
     311                 :        5321 :     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
     312                 :             :                           : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     313                 :             :     ABI::RUST, std::move (params), ret_type, substitutions,
     314                 :       10642 :     TyTy::SubstitutionArgumentMappings::empty (
     315                 :        5321 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     316                 :       21284 :     region_constraints);
     317                 :        5321 :   context->insert_type (fn.get_mappings (), resolved);
     318                 :        5321 :   return resolved;
     319                 :        5321 : }
     320                 :             : 
     321                 :             : } // namespace Resolver
     322                 :             : } // 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.