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: 98.1 % 155 152
Test Date: 2026-10-03 16:17:38 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         9802 : TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
      37              : {
      38         9802 :   if (placeholder.is_static ())
      39           91 :     return TyTy::Region::make_static ();
      40              : 
      41         9711 :   if (placeholder == Lifetime::anonymous_lifetime ())
      42         9428 :     return TyTy::Region::make_anonymous ();
      43              : 
      44          327 :   for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
      45              :     {
      46          327 :       if (it->first == placeholder)
      47              :         {
      48          283 :           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          253 :               return (is_body)
      53          253 :                        ? TyTy::Region::make_named (it->second.index + 1)
      54          253 :                        : TyTy::Region::make_early_bound (it->second.index);
      55              :             }
      56              :           else
      57              :             {
      58           30 :               return TyTy::Region::make_late_bound (get_current_scope ()
      59           30 :                                                       - it->second.scope,
      60           30 :                                                     it->second.index);
      61              :             }
      62              :         }
      63              :     }
      64              : 
      65            0 :   return tl::nullopt;
      66              : }
      67              : 
      68              : void
      69         4707 : TypeResolution::Resolve (HIR::Crate &crate)
      70              : {
      71        24489 :   for (auto &it : crate.get_items ())
      72        19783 :     TypeCheckItem::Resolve (*it);
      73              : 
      74         4706 :   if (saw_errors ())
      75              :     return;
      76              : 
      77         4506 :   OverlappingImplItemPass::go ();
      78         4506 :   if (saw_errors ())
      79              :     return;
      80              : 
      81         4505 :   auto context = TypeCheckContext::get ();
      82         4505 :   context->compute_inference_variables (true);
      83              : }
      84              : 
      85              : // rust-hir-trait-ref.h
      86              : 
      87         7218 : TraitItemReference::TraitItemReference (
      88              :   std::string identifier, bool optional, TraitItemType type,
      89              :   HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
      90              :   std::vector<TyTy::SubstitutionParamMapping> substitutions, location_t locus)
      91         7218 :   : identifier (identifier), optional_flag (optional), type (type),
      92         7218 :     hir_trait_item (hir_trait_item),
      93         7218 :     inherited_substitutions (std::move (substitutions)), locus (locus),
      94         7218 :     self (self), context (TypeCheckContext::get ())
      95         7218 : {}
      96              : 
      97        16469 : TraitItemReference::TraitItemReference (TraitItemReference const &other)
      98        16469 :   : identifier (other.identifier), optional_flag (other.optional_flag),
      99        16469 :     type (other.type), hir_trait_item (other.hir_trait_item),
     100        16469 :     locus (other.locus), self (other.self), context (TypeCheckContext::get ())
     101              : {
     102        16469 :   inherited_substitutions.clear ();
     103        16469 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     104        56529 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     105        47182 :     inherited_substitutions.push_back (
     106        23591 :       other.inherited_substitutions.at (i).clone ());
     107        16469 : }
     108              : 
     109              : TraitItemReference &
     110         3602 : TraitItemReference::operator= (TraitItemReference const &other)
     111              : {
     112         3602 :   identifier = other.identifier;
     113         3602 :   optional_flag = other.optional_flag;
     114         3602 :   type = other.type;
     115         3602 :   hir_trait_item = other.hir_trait_item;
     116         3602 :   self = other.self;
     117         3602 :   locus = other.locus;
     118         3602 :   context = other.context;
     119              : 
     120         3602 :   inherited_substitutions.clear ();
     121         3602 :   inherited_substitutions.reserve (other.inherited_substitutions.size ());
     122        12325 :   for (size_t i = 0; i < other.inherited_substitutions.size (); i++)
     123        10242 :     inherited_substitutions.push_back (
     124         5121 :       other.inherited_substitutions.at (i).clone ());
     125              : 
     126         3602 :   return *this;
     127              : }
     128              : 
     129              : TyTy::BaseType *
     130         8437 : TraitItemReference::get_type_from_typealias (/*const*/
     131              :                                              HIR::TraitItemType &type) const
     132              : {
     133         8437 :   TyTy::TyVar var (get_mappings ().get_hirid ());
     134         8437 :   return var.get_tyty ();
     135              : }
     136              : 
     137              : TyTy::BaseType *
     138           32 : TraitItemReference::get_type_from_constant (
     139              :   /*const*/ HIR::TraitItemConst &constant) const
     140              : {
     141           32 :   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
     142           32 :   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         2748 : TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
     155              : {
     156         2748 :   auto binder_pin = context->push_clean_lifetime_resolver ();
     157              : 
     158         2748 :   auto &mappings = Analysis::Mappings::get ();
     159         2748 :   auto *trait
     160         2748 :     = mappings.lookup_trait_item_mapping (get_mappings ().get_hirid ());
     161         2748 :   rust_assert (trait != nullptr);
     162         6678 :   for (auto &param : trait->get_generic_params ())
     163         3930 :     if (param->get_kind () == HIR::GenericParam::GenericKind::LIFETIME)
     164              :       {
     165            9 :         auto &lifetime_param = static_cast<HIR::LifetimeParam &> (*param);
     166            9 :         context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
     167              :       }
     168              : 
     169         2748 :   std::vector<TyTy::SubstitutionParamMapping> substitutions
     170         2748 :     = inherited_substitutions;
     171              : 
     172         2748 :   HIR::TraitFunctionDecl &function = fn.get_decl ();
     173         2748 :   if (function.has_generics ())
     174              :     {
     175           29 :       TypeCheckBase::ResolveGenericParams (HIR::Item::ItemKind::Function,
     176              :                                            fn.get_locus (),
     177           29 :                                            function.get_generic_params (),
     178              :                                            substitutions, false /*is_foreign*/,
     179              :                                            ABI::RUST);
     180              :     }
     181              : 
     182         2748 :   TyTy::RegionConstraints region_constraints;
     183         2748 :   ResolveWhereClauseItem::Resolve (function.get_where_clause (),
     184              :                                    region_constraints);
     185              : 
     186         2748 :   TyTy::BaseType *ret_type = nullptr;
     187         2748 :   if (!function.has_return_type ())
     188          465 :     ret_type = TyTy::TupleType::get_unit_type ();
     189              :   else
     190              :     {
     191         2283 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
     192         2283 :       if (resolved->get_kind () == TyTy::TypeKind::ERROR)
     193              :         {
     194            2 :           rust_error_at (fn.get_locus (), "failed to resolve return type");
     195            2 :           return get_error ();
     196              :         }
     197              : 
     198         2281 :       ret_type = resolved->clone ();
     199         2281 :       ret_type->set_ref (
     200         2281 :         function.get_return_type ().get_mappings ().get_hirid ());
     201              :     }
     202              : 
     203         2746 :   std::vector<TyTy::FnParam> params;
     204              : 
     205         2746 :   if (function.is_method ())
     206              :     {
     207              :       // these are implicit mappings and not used
     208         2409 :       auto &mappings = Analysis::Mappings::get ();
     209         2409 :       auto crate_num = mappings.get_current_crate ();
     210         2409 :       Analysis::NodeMapping mapping (crate_num, mappings.get_next_node_id (),
     211              :                                      mappings.get_next_hir_id (crate_num),
     212         2409 :                                      UNKNOWN_LOCAL_DEFID);
     213              : 
     214              :       // add the synthetic self param at the front, this is a placeholder
     215              :       // for compilation to know parameter names. The types are ignored
     216              :       // but we reuse the HIR identifier pattern which requires it
     217         2409 :       HIR::SelfParam &self_param = function.get_self_unchecked ();
     218         2409 :       std::unique_ptr<HIR::Pattern> self_pattern
     219         2409 :         = std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern (
     220         2409 :           mapping, {"self"}, self_param.get_locus (), self_param.is_ref (),
     221         2409 :           self_param.is_mut () ? Mutability::Mut : Mutability::Imm,
     222        11806 :           std::unique_ptr<HIR::Pattern> (nullptr)));
     223              :       // might have a specified type
     224         2409 :       TyTy::BaseType *self_type = nullptr;
     225         2409 :       if (self_param.has_type ())
     226              :         {
     227            1 :           HIR::Type &specified_type = self_param.get_type ();
     228            1 :           self_type = TypeCheckType::Resolve (specified_type);
     229              :         }
     230              :       else
     231              :         {
     232         2408 :           switch (self_param.get_self_kind ())
     233              :             {
     234          615 :             case HIR::SelfParam::IMM:
     235          615 :             case HIR::SelfParam::MUT:
     236          615 :               self_type = self->clone ();
     237          615 :               break;
     238              : 
     239         1793 :             case HIR::SelfParam::IMM_REF:
     240         1793 :             case HIR::SelfParam::MUT_REF:
     241         1793 :               {
     242         1793 :                 auto mutability
     243         1793 :                   = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
     244         1793 :                       ? Mutability::Imm
     245         1793 :                       : Mutability::Mut;
     246         1793 :                 rust_assert (self_param.has_lifetime ());
     247              : 
     248         1793 :                 auto region = TyTy::Region::make_anonymous ();
     249         1793 :                 auto maybe_region = context->lookup_and_resolve_lifetime (
     250         1793 :                   self_param.get_lifetime ());
     251         1793 :                 if (maybe_region.has_value ())
     252         1792 :                   region = maybe_region.value ();
     253              :                 else
     254              :                   {
     255            1 :                     rust_error_at (self_param.get_locus (),
     256              :                                    "failed to resolve lifetime");
     257              :                   }
     258              : 
     259         3586 :                 self_type = new TyTy::ReferenceType (
     260         1793 :                   self_param.get_mappings ().get_hirid (),
     261         1793 :                   TyTy::TyVar (self->get_ref ()), mutability, region);
     262              :               }
     263         1793 :               break;
     264              : 
     265            0 :             default:
     266            0 :               rust_unreachable ();
     267              :               return nullptr;
     268              :             }
     269              :         }
     270              : 
     271         2409 :       context->insert_type (self_param.get_mappings (), self_type);
     272         2409 :       params.emplace_back (std::move (self_pattern), self_type);
     273         2409 :     }
     274              : 
     275         4484 :   for (auto &param : function.get_function_params ())
     276              :     {
     277              :       // get the name as well required for later on
     278         1738 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     279         1738 :       context->insert_type (param.get_mappings (), param_tyty);
     280         1738 :       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     281              :       // FIXME: Should we take the name ? Use a shared pointer instead ?
     282         1738 :       params.emplace_back (param.get_param_name ().clone_pattern (),
     283              :                            param_tyty);
     284              :     }
     285              : 
     286         2746 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     287              : 
     288         2746 :   CanonicalPath canonical_path
     289         2746 :     = nr_ctx.to_canonical_path (fn.get_mappings ().get_nodeid (),
     290         2746 :                                 Resolver2_0::Namespace::Types);
     291              : 
     292         5492 :   RustIdent ident{canonical_path, fn.get_locus ()};
     293         2746 :   auto resolved = new TyTy::FnType (
     294         5492 :     fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
     295         2746 :     function.get_function_name ().as_string (), ident,
     296         2746 :     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
     297              :                           : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     298              :     ABI::RUST, std::move (params), ret_type, substitutions,
     299         5492 :     TyTy::SubstitutionArgumentMappings::empty (
     300         2746 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     301        13730 :     region_constraints);
     302         2746 :   context->insert_type (fn.get_mappings (), resolved);
     303         2746 :   return resolved;
     304         5494 : }
     305              : 
     306              : } // namespace Resolver
     307              : } // 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.