LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-implitem.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.8 % 368 334
Test Date: 2026-07-11 15:47:05 Functions: 94.1 % 17 16
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-implitem.h"
      20              : #include "rust-diagnostics.h"
      21              : #include "rust-hir-full-decls.h"
      22              : #include "rust-hir-pattern.h"
      23              : #include "rust-hir-type-check-base.h"
      24              : #include "rust-hir-type-check-intrinsic.h"
      25              : #include "rust-hir-type-check-type.h"
      26              : #include "rust-hir-type-check-expr.h"
      27              : #include "rust-hir-type-check-pattern.h"
      28              : #include "rust-rib.h"
      29              : #include "rust-type-util.h"
      30              : #include "rust-tyty.h"
      31              : #include "rust-finalized-name-resolution-context.h"
      32              : 
      33              : namespace Rust {
      34              : namespace Resolver {
      35              : 
      36         2544 : TypeCheckTopLevelExternItem::TypeCheckTopLevelExternItem (
      37         2544 :   const HIR::ExternBlock &parent)
      38         2544 :   : TypeCheckBase (), parent (parent)
      39         2544 : {}
      40              : 
      41              : TyTy::BaseType *
      42         2594 : TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem &item,
      43              :                                       const HIR::ExternBlock &parent)
      44              : {
      45              :   // is it already resolved?
      46         2594 :   auto context = TypeCheckContext::get ();
      47         2594 :   TyTy::BaseType *resolved = nullptr;
      48         2594 :   bool already_resolved
      49         2594 :     = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
      50         2594 :   if (already_resolved)
      51           50 :     return resolved;
      52              : 
      53         2544 :   TypeCheckTopLevelExternItem resolver (parent);
      54         2544 :   item.accept_vis (resolver);
      55         2544 :   return resolver.resolved;
      56         2544 : }
      57              : 
      58              : void
      59            1 : TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem &item)
      60              : {
      61            1 :   TyTy::BaseType *actual_type = TypeCheckType::Resolve (item.get_item_type ());
      62              : 
      63            1 :   context->insert_type (item.get_mappings (), actual_type);
      64            1 :   resolved = actual_type;
      65            1 : }
      66              : 
      67              : void
      68         2543 : TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
      69              : {
      70         2543 :   auto binder_pin = context->push_clean_lifetime_resolver ();
      71              : 
      72         2543 :   std::vector<TyTy::SubstitutionParamMapping> substitutions;
      73         2543 :   if (function.has_generics ())
      74              :     {
      75          978 :       resolve_generic_params (HIR::Item::ItemKind::Function,
      76              :                               function.get_locus (),
      77          978 :                               function.get_generic_params (), substitutions,
      78          978 :                               true /*is_foreign*/, parent.get_abi ());
      79              :     }
      80              : 
      81         2543 :   TyTy::RegionConstraints region_constraints;
      82         2543 :   if (function.has_where_clause ())
      83              :     {
      84            0 :       for (auto &where_clause_item : function.get_where_clause ().get_items ())
      85              :         {
      86            0 :           ResolveWhereClauseItem::Resolve (*where_clause_item,
      87              :                                            region_constraints);
      88              :         }
      89              :     }
      90              : 
      91         2543 :   TyTy::BaseType *ret_type = nullptr;
      92         2543 :   if (!function.has_return_type ())
      93         1212 :     ret_type = TyTy::TupleType::get_unit_type ();
      94              :   else
      95              :     {
      96         1331 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
      97         1331 :       if (resolved == nullptr)
      98              :         {
      99            0 :           rust_error_at (function.get_locus (),
     100              :                          "failed to resolve return type");
     101            0 :           return;
     102              :         }
     103              : 
     104         1331 :       ret_type = resolved->clone ();
     105         1331 :       ret_type->set_ref (
     106         1331 :         function.get_return_type ().get_mappings ().get_hirid ());
     107              :     }
     108              : 
     109         2543 :   std::vector<TyTy::FnParam> params;
     110         5432 :   for (auto &param : function.get_function_params ())
     111              :     {
     112              :       // get the name as well required for later on
     113         2889 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     114              : 
     115              :       // these are implicit mappings and not used
     116         2889 :       auto crate_num = mappings.get_current_crate ();
     117         5778 :       Analysis::NodeMapping mapping (crate_num, mappings.get_next_node_id (),
     118         2889 :                                      mappings.get_next_hir_id (crate_num),
     119         2889 :                                      UNKNOWN_LOCAL_DEFID);
     120              : 
     121         2889 :       auto param_pattern = std::make_unique<HIR::IdentifierPattern> (
     122         2889 :         HIR::IdentifierPattern (mapping, param.get_param_name (),
     123              :                                 UNDEF_LOCATION, false, Mutability::Imm,
     124         5778 :                                 std::unique_ptr<HIR::Pattern> (nullptr)));
     125              : 
     126         2889 :       params.emplace_back (std::move (param_pattern), param_tyty);
     127              : 
     128         2889 :       context->insert_type (param.get_mappings (), param_tyty);
     129              : 
     130              :       // FIXME do we need error checking for patterns here?
     131              :       // see https://github.com/Rust-GCC/gccrs/issues/995
     132         2889 :     }
     133              : 
     134         2543 :   uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
     135         2543 :   if (function.is_variadic ())
     136              :     {
     137          849 :       flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
     138          849 :       if (parent.get_abi () != Rust::ABI::C)
     139              :         {
     140            1 :           rust_error_at (
     141              :             function.get_locus (), ErrorCode::E0045,
     142              :             "C-variadic function must have C or cdecl calling convention");
     143              :         }
     144              :     }
     145              : 
     146         2543 :   RustIdent ident{
     147         5086 :     CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
     148         2543 :                             function.get_item_name ().as_string ()),
     149         2543 :     function.get_locus ()};
     150              : 
     151         2543 :   auto fnType = new TyTy::FnType (
     152         2543 :     function.get_mappings ().get_hirid (),
     153         5086 :     function.get_mappings ().get_defid (),
     154         2543 :     function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
     155              :     std::move (params), ret_type, std::move (substitutions),
     156         5086 :     TyTy::SubstitutionArgumentMappings::empty (
     157         2543 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     158        10172 :     region_constraints);
     159              : 
     160         2543 :   context->insert_type (function.get_mappings (), fnType);
     161              : 
     162         2543 :   if (parent.get_abi () == Rust::ABI::INTRINSIC
     163         2543 :       && IntrinsicChecker::check (fnType) == IntrinsicCheckResult::Invalid)
     164           14 :     return;
     165              : 
     166         2529 :   resolved = fnType;
     167         5086 : }
     168              : 
     169              : void
     170            0 : TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
     171              : {
     172            0 :   rust_sorry_at (type.get_locus (), "extern types are not supported yet");
     173              :   // TODO
     174            0 : }
     175              : 
     176         8182 : TypeCheckImplItem::TypeCheckImplItem (
     177              :   HIR::ImplBlock &parent, TyTy::BaseType *self,
     178         8182 :   std::vector<TyTy::SubstitutionParamMapping> substitutions)
     179         8182 :   : TypeCheckBase (), parent (parent), self (self),
     180         8182 :     substitutions (substitutions)
     181         8182 : {}
     182              : 
     183              : TyTy::BaseType *
     184        11842 : TypeCheckImplItem::Resolve (
     185              :   HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
     186              :   std::vector<TyTy::SubstitutionParamMapping> substitutions)
     187              : {
     188              :   // is it already resolved?
     189        11842 :   auto context = TypeCheckContext::get ();
     190        11842 :   TyTy::BaseType *resolved = nullptr;
     191        11842 :   bool already_resolved
     192        11842 :     = context->lookup_type (item.get_impl_mappings ().get_hirid (), &resolved);
     193        11842 :   if (already_resolved)
     194         3660 :     return resolved;
     195              : 
     196              :   // resolve
     197         8182 :   TypeCheckImplItem resolver (parent, self, substitutions);
     198         8182 :   resolver.context->block_context ().enter (
     199         8182 :     TypeCheckBlockContextItem (&parent));
     200         8182 :   item.accept_vis (resolver);
     201         8182 :   resolver.context->block_context ().exit ();
     202              : 
     203         8182 :   return resolver.result;
     204         8182 : }
     205              : 
     206              : void
     207         6929 : TypeCheckImplItem::visit (HIR::Function &function)
     208              : {
     209         6929 :   auto binder_pin = context->push_lifetime_binder ();
     210              : 
     211         6929 :   if (function.has_generics ())
     212          112 :     resolve_generic_params (HIR::Item::ItemKind::Function,
     213              :                             function.get_locus (),
     214          112 :                             function.get_generic_params (), substitutions);
     215              : 
     216         6929 :   TyTy::RegionConstraints region_constraints;
     217         6930 :   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     218              :     {
     219            1 :       ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
     220              :                                        region_constraints);
     221              :     }
     222              : 
     223         6929 :   TyTy::BaseType *ret_type = nullptr;
     224         6929 :   if (!function.has_function_return_type ())
     225          423 :     ret_type = TyTy::TupleType::get_unit_type ();
     226              :   else
     227              :     {
     228         6506 :       auto resolved = TypeCheckType::Resolve (function.get_return_type ());
     229         6506 :       if (resolved == nullptr)
     230              :         {
     231            0 :           rust_error_at (function.get_locus (),
     232              :                          "failed to resolve return type");
     233            0 :           return;
     234              :         }
     235              : 
     236         6506 :       ret_type = resolved->clone ();
     237         6506 :       ret_type->set_ref (
     238         6506 :         function.get_return_type ().get_mappings ().get_hirid ());
     239              :     }
     240              : 
     241         6929 :   std::vector<TyTy::FnParam> params;
     242         6929 :   if (function.is_method ())
     243              :     {
     244              :       // these are implicit mappings and not used
     245         5811 :       auto crate_num = mappings.get_current_crate ();
     246        11622 :       Analysis::NodeMapping mapping (crate_num, mappings.get_next_node_id (),
     247         5811 :                                      mappings.get_next_hir_id (crate_num),
     248         5811 :                                      UNKNOWN_LOCAL_DEFID);
     249              : 
     250              :       // add the synthetic self param at the front, this is a placeholder for
     251              :       // compilation to know parameter names. The types are ignored but we
     252              :       // reuse the HIR identifier pattern which requires it
     253         5811 :       HIR::SelfParam &self_param = function.get_self_param_unchecked ();
     254              :       // FIXME: which location should be used for Rust::Identifier for `self`?
     255         5811 :       std::unique_ptr<HIR::Pattern> self_pattern
     256         5811 :         = std::make_unique<HIR::IdentifierPattern> (
     257        11622 :           HIR::IdentifierPattern (mapping, {"self"}, self_param.get_locus (),
     258         5811 :                                   self_param.is_ref (), self_param.get_mut (),
     259        29055 :                                   std::unique_ptr<HIR::Pattern> (nullptr)));
     260              : 
     261              :       // might have a specified type
     262         5811 :       TyTy::BaseType *self_type = nullptr;
     263         5811 :       if (self_param.has_type ())
     264              :         {
     265            1 :           auto &specified_type = self_param.get_type ();
     266            1 :           self_type = TypeCheckType::Resolve (specified_type);
     267              :         }
     268              :       else
     269              :         {
     270         5810 :           switch (self_param.get_self_kind ())
     271              :             {
     272         2542 :             case HIR::SelfParam::IMM:
     273         2542 :             case HIR::SelfParam::MUT:
     274         2542 :               self_type = self->clone ();
     275         2542 :               break;
     276              : 
     277         3102 :             case HIR::SelfParam::IMM_REF:
     278         3102 :               {
     279         3102 :                 tl::optional<TyTy::Region> region;
     280         3102 :                 if (self_param.has_lifetime ())
     281              :                   {
     282         5684 :                     region = context->lookup_and_resolve_lifetime (
     283         2842 :                       self_param.get_lifetime ());
     284         2842 :                     if (!region.has_value ())
     285              :                       {
     286            1 :                         rust_inform (self_param.get_locus (),
     287              :                                      "failed to resolve lifetime");
     288            1 :                         return;
     289              :                       }
     290              :                   }
     291              :                 else
     292              :                   {
     293          260 :                     region = TyTy::Region::make_anonymous ();
     294              :                   }
     295         6202 :                 self_type = new TyTy::ReferenceType (
     296         6202 :                   self_param.get_mappings ().get_hirid (),
     297         3101 :                   TyTy::TyVar (self->get_ref ()), Mutability::Imm,
     298         6202 :                   region.value ());
     299              :               }
     300         3101 :               break;
     301              : 
     302          166 :             case HIR::SelfParam::MUT_REF:
     303          166 :               {
     304          166 :                 tl::optional<TyTy::Region> region;
     305          166 :                 if (self_param.has_lifetime ())
     306              :                   {
     307          332 :                     region = context->lookup_and_resolve_lifetime (
     308          166 :                       self_param.get_lifetime ());
     309          166 :                     if (!region.has_value ())
     310              :                       {
     311            0 :                         rust_error_at (self_param.get_locus (),
     312              :                                        "failed to resolve lifetime");
     313            0 :                         return;
     314              :                       }
     315              :                   }
     316              :                 else
     317              :                   {
     318            0 :                     region = TyTy::Region::make_anonymous ();
     319              :                   }
     320          332 :                 self_type = new TyTy::ReferenceType (
     321          332 :                   self_param.get_mappings ().get_hirid (),
     322          166 :                   TyTy::TyVar (self->get_ref ()), Mutability::Mut,
     323          332 :                   region.value ());
     324              :               }
     325          166 :               break;
     326              : 
     327            0 :             default:
     328            0 :               rust_unreachable ();
     329              :               return;
     330              :             }
     331              :         }
     332              : 
     333         5810 :       context->insert_type (self_param.get_mappings (), self_type);
     334         5810 :       params.emplace_back (std::move (self_pattern), self_type);
     335         5811 :     }
     336              : 
     337        11329 :   for (auto &param : function.get_function_params ())
     338              :     {
     339              :       // get the name as well required for later on
     340         4401 :       auto param_tyty = TypeCheckType::Resolve (param.get_type ());
     341              : 
     342         4401 :       context->insert_type (param.get_mappings (), param_tyty);
     343         4401 :       TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
     344              : 
     345         4401 :       params.emplace_back (param.get_param_name ().clone_pattern (),
     346              :                            param_tyty);
     347              :     }
     348              : 
     349         6928 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     350              : 
     351         6928 :   CanonicalPath canonical_path
     352         6928 :     = nr_ctx.to_canonical_path (function.get_mappings ().get_nodeid (),
     353         6928 :                                 Resolver2_0::Namespace::Types);
     354              : 
     355        13856 :   RustIdent ident{canonical_path, function.get_locus ()};
     356         6928 :   auto fnType = new TyTy::FnType (
     357         6928 :     function.get_mappings ().get_hirid (),
     358         6928 :     function.get_mappings ().get_defid (),
     359         6928 :     function.get_function_name ().as_string (), ident,
     360         6928 :     function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
     361              :                           : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     362         6928 :     ABI::RUST, std::move (params), ret_type, std::move (substitutions),
     363        13856 :     TyTy::SubstitutionArgumentMappings::empty (
     364         6928 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     365        34640 :     region_constraints);
     366              : 
     367         6928 :   context->insert_type (function.get_mappings (), fnType);
     368         6928 :   result = fnType;
     369              : 
     370              :   // need to get the return type from this
     371         6928 :   TyTy::FnType *resolve_fn_type = fnType;
     372         6928 :   auto expected_ret_tyty = resolve_fn_type->get_return_type ();
     373         6928 :   context->push_return_type (TypeCheckContextItem (parent, &function),
     374              :                              expected_ret_tyty);
     375              : 
     376         6928 :   auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
     377              : 
     378         6928 :   location_t fn_return_locus = function.has_function_return_type ()
     379         6928 :                                  ? function.get_return_type ().get_locus ()
     380          423 :                                  : function.get_locus ();
     381              : 
     382        13856 :   coercion_site (function.get_definition ().get_mappings ().get_hirid (),
     383         6928 :                  TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
     384         6928 :                  TyTy::TyWithLocation (block_expr_ty),
     385         6928 :                  function.get_definition ().get_locus ());
     386              : 
     387         6928 :   context->pop_return_type ();
     388        13858 : }
     389              : 
     390              : void
     391           70 : TypeCheckImplItem::visit (HIR::ConstantItem &constant)
     392              : {
     393           70 :   TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
     394           70 :   TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
     395              : 
     396          140 :   TyTy::BaseType *unified = unify_site (
     397           70 :     constant.get_mappings ().get_hirid (),
     398           70 :     TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
     399           70 :     TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
     400              :     constant.get_locus ());
     401              : 
     402           70 :   if (substitutions.empty ())
     403              :     {
     404           41 :       context->insert_type (constant.get_mappings (), unified);
     405           41 :       result = unified;
     406           41 :       return;
     407              :     }
     408              : 
     409              :   // special case when this is a generic constant
     410           29 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     411              :   // TODO: Is Values the correct NS?
     412           29 :   CanonicalPath canonical_path
     413           29 :     = nr_ctx.to_canonical_path (constant.get_mappings ().get_nodeid (),
     414           29 :                                 Resolver2_0::Namespace::Values);
     415           29 :   RustIdent ident{canonical_path, constant.get_locus ()};
     416           29 :   auto fnType = new TyTy::FnType (
     417           29 :     constant.get_mappings ().get_hirid (),
     418           29 :     constant.get_mappings ().get_defid (),
     419           29 :     constant.get_identifier ().as_string (), ident,
     420              :     TyTy::FnType::FNTYPE_IS_SYN_CONST_FLAG, ABI::RUST, {}, unified,
     421           29 :     std::move (substitutions),
     422           58 :     TyTy::SubstitutionArgumentMappings::empty (
     423           29 :       context->get_lifetime_resolver ().get_num_bound_regions ()),
     424          116 :     {});
     425              : 
     426           29 :   context->insert_type (constant.get_mappings (), fnType);
     427           29 :   result = fnType;
     428           29 : }
     429              : 
     430              : void
     431         1183 : TypeCheckImplItem::visit (HIR::TypeAlias &alias)
     432              : {
     433         1183 :   auto binder_pin = context->push_lifetime_binder ();
     434              : 
     435         1183 :   if (alias.has_generics ())
     436           15 :     resolve_generic_params (HIR::Item::ItemKind::TypeAlias, alias.get_locus (),
     437           15 :                             alias.get_generic_params (), substitutions);
     438              : 
     439         1183 :   TyTy::BaseType *actual_type
     440         1183 :     = TypeCheckType::Resolve (alias.get_type_aliased ());
     441              : 
     442         1183 :   context->insert_type (alias.get_mappings (), actual_type);
     443         1183 :   result = actual_type;
     444         1183 :   TyTy::RegionConstraints region_constraints;
     445         1183 :   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     446              :     {
     447            0 :       ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
     448              :                                        region_constraints);
     449              :     }
     450         1183 : }
     451              : 
     452         6083 : TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
     453              :   HIR::ImplBlock &parent, TyTy::BaseType *self,
     454              :   TyTy::TypeBoundPredicate &trait_reference,
     455         6083 :   std::vector<TyTy::SubstitutionParamMapping> substitutions)
     456         6083 :   : TypeCheckBase (), trait_reference (trait_reference),
     457         6083 :     resolved_trait_item (TyTy::TypeBoundPredicateItem::error ()),
     458         6083 :     parent (parent), self (self), substitutions (substitutions)
     459              : {
     460         6083 :   rust_assert (is_trait_impl_block ());
     461         6083 : }
     462              : 
     463              : TyTy::TypeBoundPredicateItem
     464         6083 : TypeCheckImplItemWithTrait::Resolve (
     465              :   HIR::ImplBlock &parent, HIR::ImplItem &item, TyTy::BaseType *self,
     466              :   TyTy::TypeBoundPredicate &trait_reference,
     467              :   std::vector<TyTy::SubstitutionParamMapping> substitutions)
     468              : {
     469         6083 :   TypeCheckImplItemWithTrait resolver (parent, self, trait_reference,
     470         6083 :                                        substitutions);
     471         6083 :   item.accept_vis (resolver);
     472         6083 :   return resolver.resolved_trait_item;
     473         6083 : }
     474              : 
     475              : void
     476           31 : TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
     477              : {
     478              :   // normal resolution of the item
     479           31 :   TyTy::BaseType *lookup
     480           31 :     = TypeCheckImplItem::Resolve (parent, constant, self, substitutions);
     481              : 
     482              :   // map the impl item to the associated trait item
     483           31 :   const auto tref = trait_reference.get ();
     484           31 :   const TraitItemReference *raw_trait_item = nullptr;
     485           31 :   bool found
     486           31 :     = tref->lookup_trait_item_by_type (constant.get_identifier ().as_string (),
     487              :                                        TraitItemReference::TraitItemType::CONST,
     488              :                                        &raw_trait_item);
     489              : 
     490              :   // unknown trait item - https://doc.rust-lang.org/error_codes/E0323.html
     491           31 :   if (!found || raw_trait_item->is_error ())
     492              :     {
     493            1 :       rich_location r (line_table, constant.get_locus ());
     494            1 :       r.add_range (trait_reference.get_locus ());
     495            1 :       rust_error_at (r, ErrorCode::E0323,
     496              :                      "item %qs is an associated const, which does not match "
     497              :                      "its trait %qs",
     498            2 :                      constant.get_identifier ().as_string ().c_str (),
     499            1 :                      trait_reference.get_name ().c_str ());
     500            1 :       return;
     501            1 :     }
     502              : 
     503              :   // get the item from the predicate
     504           30 :   resolved_trait_item
     505           30 :     = trait_reference.lookup_associated_item (raw_trait_item).value ();
     506              : 
     507              :   // merge the attributes
     508           30 :   const HIR::TraitItem *hir_trait_item
     509           30 :     = resolved_trait_item.get_raw_item ()->get_hir_trait_item ();
     510           30 :   merge_attributes (constant.get_outer_attrs (), *hir_trait_item);
     511              : 
     512              :   // check the types are compatible
     513           30 :   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
     514           30 :   if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
     515           30 :                          TyTy::TyWithLocation (lookup), constant.get_locus (),
     516              :                          true /*emit_errors*/))
     517              :     {
     518            0 :       rich_location r (line_table, constant.get_locus ());
     519            0 :       r.add_range (resolved_trait_item.get_locus ());
     520              : 
     521            0 :       rust_error_at (r, "constant %qs has an incompatible type for trait %qs",
     522            0 :                      constant.get_identifier ().as_string ().c_str (),
     523            0 :                      trait_reference.get_name ().c_str ());
     524            0 :     }
     525              : }
     526              : 
     527              : void
     528         1853 : TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
     529              : {
     530         1853 :   auto binder_pin = context->push_lifetime_binder ();
     531              : 
     532         1853 :   if (type.has_generics ())
     533           15 :     resolve_generic_params (HIR::Item::ItemKind::TypeAlias, type.get_locus (),
     534           15 :                             type.get_generic_params (), substitutions);
     535              : 
     536              :   // normal resolution of the item
     537         1853 :   TyTy::BaseType *lookup
     538         1853 :     = TypeCheckImplItem::Resolve (parent, type, self, substitutions);
     539              : 
     540              :   // map the impl item to the associated trait item
     541         1853 :   const auto tref = trait_reference.get ();
     542         1853 :   const TraitItemReference *raw_trait_item = nullptr;
     543         1853 :   bool found
     544         1853 :     = tref->lookup_trait_item_by_type (type.get_new_type_name ().as_string (),
     545              :                                        TraitItemReference::TraitItemType::TYPE,
     546              :                                        &raw_trait_item);
     547              : 
     548              :   // unknown trait item
     549         1853 :   if (!found || raw_trait_item->is_error ())
     550              :     {
     551            0 :       rich_location r (line_table, type.get_locus ());
     552            0 :       r.add_range (trait_reference.get_locus ());
     553            0 :       rust_error_at (r, "type alias %qs is not a member of trait %qs",
     554            0 :                      type.get_new_type_name ().as_string ().c_str (),
     555            0 :                      trait_reference.get_name ().c_str ());
     556            0 :       return;
     557            0 :     }
     558              : 
     559              :   // get the item from the predicate
     560         1853 :   resolved_trait_item
     561         1853 :     = trait_reference.lookup_associated_item (raw_trait_item).value ();
     562              : 
     563              :   // merge the attributes
     564         1853 :   const HIR::TraitItem *hir_trait_item
     565         1853 :     = resolved_trait_item.get_raw_item ()->get_hir_trait_item ();
     566         1853 :   merge_attributes (type.get_outer_attrs (), *hir_trait_item);
     567              : 
     568              :   // unwrap a ProjectionType that already wraps a concrete
     569         1853 :   if (auto *p = lookup->try_as<TyTy::ProjectionType> ())
     570         1413 :     if (!p->is_trait_position () && p->get () != nullptr
     571         1413 :         && p->get ()->get_kind () != TyTy::TypeKind::PROJECTION)
     572          670 :       lookup = p->get ();
     573              : 
     574              :   // The impl alias is itself a projection so the substitution machinery has a
     575              :   // handle to bind the impl's generic arguments to the alias body.
     576         1853 :   auto projection
     577         1853 :     = new TyTy::ProjectionType (type.get_mappings ().get_hirid (), lookup, tref,
     578         1853 :                                 raw_trait_item->get_mappings ().get_defid (),
     579         5559 :                                 substitutions, self);
     580              : 
     581              :   // check the types are compatible
     582         1853 :   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
     583         1853 :   if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
     584         1853 :                          TyTy::TyWithLocation (projection), type.get_locus (),
     585              :                          true /*emit_errors*/))
     586              :     {
     587            0 :       rich_location r (line_table, type.get_locus ());
     588            0 :       r.add_range (resolved_trait_item.get_locus ());
     589              : 
     590            0 :       rust_error_at (r, "type alias %qs has an incompatible type for trait %qs",
     591            0 :                      type.get_new_type_name ().as_string ().c_str (),
     592            0 :                      trait_reference.get_name ().c_str ());
     593            0 :     }
     594              : 
     595         1853 :   context->insert_type (type.get_mappings (), projection);
     596         1853 : }
     597              : 
     598              : void
     599         4199 : TypeCheckImplItemWithTrait::visit (HIR::Function &function)
     600              : {
     601              :   // normal resolution of the item
     602         4199 :   TyTy::BaseType *lookup
     603         4199 :     = TypeCheckImplItem::Resolve (parent, function, self, substitutions);
     604         4199 :   if (lookup == nullptr)
     605            4 :     return;
     606              : 
     607              :   // map the impl item to the associated trait item
     608         4198 :   const auto tref = trait_reference.get ();
     609         4198 :   const TraitItemReference *raw_trait_item = nullptr;
     610         4198 :   bool found = tref->lookup_trait_item_by_type (
     611         4198 :     function.get_function_name ().as_string (),
     612              :     TraitItemReference::TraitItemType::FN, &raw_trait_item);
     613              : 
     614              :   // unknown trait item
     615         4198 :   if (!found || raw_trait_item->is_error ())
     616              :     {
     617            3 :       rich_location r (line_table, function.get_locus ());
     618            3 :       r.add_range (trait_reference.get_locus ());
     619            3 :       rust_error_at (r, "method %qs is not a member of trait %qs",
     620            6 :                      function.get_function_name ().as_string ().c_str (),
     621            3 :                      trait_reference.get_name ().c_str ());
     622            3 :       return;
     623            3 :     }
     624              : 
     625              :   // get the item from the predicate
     626         4195 :   resolved_trait_item
     627         4195 :     = trait_reference.lookup_associated_item (raw_trait_item).value ();
     628              : 
     629              :   // merge the attributes
     630         4195 :   const HIR::TraitItem *hir_trait_item
     631         4195 :     = resolved_trait_item.get_raw_item ()->get_hir_trait_item ();
     632         4195 :   merge_attributes (function.get_outer_attrs (), *hir_trait_item);
     633              : 
     634              :   // check the types are compatible
     635         4195 :   auto trait_item_type = resolved_trait_item.get_tyty_for_receiver (self);
     636         4195 :   if (!types_compatable (TyTy::TyWithLocation (trait_item_type),
     637         4195 :                          TyTy::TyWithLocation (lookup), function.get_locus (),
     638              :                          true /*emit_errors*/))
     639              :     {
     640            5 :       rich_location r (line_table, function.get_locus ());
     641            5 :       r.add_range (resolved_trait_item.get_locus ());
     642              : 
     643            5 :       rust_error_at (r, ErrorCode::E0053,
     644              :                      "method %qs has an incompatible type for trait %qs",
     645           10 :                      function.get_function_name ().as_string ().c_str (),
     646            5 :                      trait_reference.get_name ().c_str ());
     647            5 :     }
     648              : }
     649              : 
     650              : void
     651         6078 : TypeCheckImplItemWithTrait::merge_attributes (AST::AttrVec &impl_item_attrs,
     652              :                                               const HIR::TraitItem &trait_item)
     653              : {
     654        20310 :   for (const auto &attr : trait_item.get_outer_attrs ())
     655              :     {
     656        14232 :       impl_item_attrs.push_back (attr);
     657              :     }
     658         6078 : }
     659              : 
     660              : bool
     661         6083 : TypeCheckImplItemWithTrait::is_trait_impl_block () const
     662              : {
     663         6083 :   return !trait_reference.is_error ();
     664              : }
     665              : 
     666              : } // namespace Resolver
     667              : } // 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.