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