LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-substitution-mapper.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 64.3 % 244 157
Test Date: 2026-02-28 14:20:25 Functions: 56.9 % 51 29
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-substitution-mapper.h"
      20              : #include "rust-hir-type-check.h"
      21              : 
      22              : namespace Rust {
      23              : namespace Resolver {
      24              : 
      25         9513 : SubstMapper::SubstMapper (HirId ref, HIR::GenericArgs *generics,
      26              :                           const std::vector<TyTy::Region> &regions,
      27         9513 :                           location_t locus)
      28         9513 :   : resolved (new TyTy::ErrorType (ref)), generics (generics),
      29         9513 :     regions (regions), locus (locus)
      30         9513 : {}
      31              : 
      32              : TyTy::BaseType *
      33         9516 : SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
      34              :                       HIR::GenericArgs *generics,
      35              :                       const std::vector<TyTy::Region> &regions)
      36              : {
      37         9516 :   if (!valid_type (base))
      38              :     {
      39            3 :       rich_location r (line_table, locus);
      40            3 :       r.add_fixit_remove (generics->get_locus ());
      41            3 :       rust_error_at (r, ErrorCode::E0109,
      42              :                      "generic arguments are not allowed for this type");
      43            3 :       return base;
      44            3 :     }
      45              : 
      46         9513 :   SubstMapper mapper (base->get_ref (), generics, regions, locus);
      47         9513 :   base->accept_vis (mapper);
      48         9513 :   rust_assert (mapper.resolved != nullptr);
      49              :   return mapper.resolved;
      50              : }
      51              : 
      52              : TyTy::BaseType *
      53         6541 : SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
      54              : {
      55         6541 :   return SubstMapper::Resolve (base, locus, nullptr, {});
      56              : }
      57              : 
      58              : bool
      59         9516 : SubstMapper::valid_type (TyTy::BaseType *base)
      60              : {
      61         9516 :   bool is_fn = base->is<TyTy::FnType> ();
      62         9516 :   bool is_adt = base->is<TyTy::ADTType> ();
      63         9516 :   bool is_placeholder = base->is<TyTy::PlaceholderType> ();
      64         9516 :   bool is_projection = base->is<TyTy::ProjectionType> ();
      65              : 
      66         9516 :   return is_fn || is_adt || is_placeholder || is_projection;
      67              : }
      68              : 
      69              : bool
      70         9513 : SubstMapper::have_generic_args () const
      71              : {
      72         9513 :   return generics != nullptr;
      73              : }
      74              : 
      75              : void
      76         4707 : SubstMapper::visit (TyTy::FnType &type)
      77              : {
      78         4707 :   TyTy::FnType *concrete = nullptr;
      79         4707 :   if (!have_generic_args ())
      80              :     {
      81         4076 :       TyTy::BaseType *substs = type.infer_substitions (locus);
      82         4076 :       rust_assert (substs->get_kind () == TyTy::TypeKind::FNDEF);
      83              :       concrete = static_cast<TyTy::FnType *> (substs);
      84              :     }
      85              :   else
      86              :     {
      87          631 :       TyTy::SubstitutionArgumentMappings mappings
      88          631 :         = type.get_mappings_from_generic_args (*generics, regions);
      89          631 :       if (mappings.is_error ())
      90            1 :         return;
      91              : 
      92          630 :       concrete = type.handle_substitions (mappings);
      93          631 :     }
      94              : 
      95          630 :   if (concrete != nullptr)
      96         4706 :     resolved = concrete;
      97              : }
      98              : 
      99              : void
     100         4799 : SubstMapper::visit (TyTy::ADTType &type)
     101              : {
     102         4799 :   TyTy::ADTType *concrete = nullptr;
     103         4799 :   if (!have_generic_args ())
     104              :     {
     105         2465 :       TyTy::BaseType *substs = type.infer_substitions (locus);
     106         2465 :       rust_assert (substs->get_kind () == TyTy::TypeKind::ADT);
     107              :       concrete = static_cast<TyTy::ADTType *> (substs);
     108              :     }
     109              :   else
     110              :     {
     111         2334 :       TyTy::SubstitutionArgumentMappings mappings
     112         2334 :         = type.get_mappings_from_generic_args (*generics, regions);
     113         2334 :       if (mappings.is_error ())
     114            8 :         return;
     115              : 
     116         2326 :       concrete = type.handle_substitions (mappings);
     117         2334 :     }
     118              : 
     119         2326 :   if (concrete != nullptr)
     120         4791 :     resolved = concrete;
     121              : }
     122              : 
     123              : void
     124            0 : SubstMapper::visit (TyTy::PlaceholderType &type)
     125              : {
     126            0 :   if (!type.can_resolve ())
     127              :     {
     128            0 :       resolved = &type;
     129            0 :       return;
     130              :     }
     131              : 
     132            0 :   resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
     133              : }
     134              : 
     135              : void
     136            7 : SubstMapper::visit (TyTy::ProjectionType &type)
     137              : {
     138            7 :   TyTy::ProjectionType *concrete = nullptr;
     139            7 :   if (!have_generic_args ())
     140              :     {
     141            0 :       TyTy::BaseType *substs = type.infer_substitions (locus);
     142            0 :       rust_assert (substs->get_kind () == TyTy::TypeKind::PROJECTION);
     143              :       concrete = static_cast<TyTy::ProjectionType *> (substs);
     144              :     }
     145              :   else
     146              :     {
     147            7 :       TyTy::SubstitutionArgumentMappings mappings
     148            7 :         = type.get_mappings_from_generic_args (*generics, regions);
     149            7 :       if (mappings.is_error ())
     150            0 :         return;
     151              : 
     152            7 :       concrete = type.handle_substitions (mappings);
     153            7 :     }
     154              : 
     155            7 :   if (concrete != nullptr)
     156            7 :     resolved = concrete;
     157              : }
     158              : 
     159        84843 : SubstMapperInternal::SubstMapperInternal (
     160        84843 :   HirId ref, TyTy::SubstitutionArgumentMappings &mappings)
     161        84843 :   : resolved (new TyTy::ErrorType (ref)), mappings (mappings)
     162        84843 : {}
     163              : 
     164              : TyTy::BaseType *
     165        84843 : SubstMapperInternal::Resolve (TyTy::BaseType *base,
     166              :                               TyTy::SubstitutionArgumentMappings &mappings)
     167              : {
     168        84843 :   auto context = TypeCheckContext::get ();
     169              : 
     170        84843 :   SubstMapperInternal mapper (base->get_ref (), mappings);
     171        84843 :   base->accept_vis (mapper);
     172        84843 :   rust_assert (mapper.resolved != nullptr);
     173              : 
     174              :   // insert these new implict types into the context
     175        84843 :   TyTy::BaseType *unused = nullptr;
     176        84843 :   bool is_ty_available
     177        84843 :     = context->lookup_type (mapper.resolved->get_ty_ref (), &unused);
     178        84843 :   if (!is_ty_available)
     179              :     {
     180        24291 :       context->insert_type (
     181        24291 :         Analysis::NodeMapping (0, 0, mapper.resolved->get_ty_ref (), 0),
     182              :         mapper.resolved);
     183              :     }
     184        84843 :   bool is_ref_available
     185        84843 :     = context->lookup_type (mapper.resolved->get_ref (), &unused);
     186        84843 :   if (!is_ref_available)
     187              :     {
     188        45257 :       context->insert_type (Analysis::NodeMapping (0, 0,
     189              :                                                    mapper.resolved->get_ref (),
     190        45257 :                                                    0),
     191              :                             mapper.resolved);
     192              :     }
     193              : 
     194        84843 :   return mapper.resolved;
     195              : }
     196              : 
     197              : bool
     198            0 : SubstMapperInternal::mappings_are_bound (
     199              :   TyTy::BaseType *tyseg, TyTy::SubstitutionArgumentMappings &mappings)
     200              : {
     201            0 :   if (tyseg->get_kind () == TyTy::TypeKind::ADT)
     202              :     {
     203            0 :       TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyseg);
     204            0 :       return adt->are_mappings_bound (mappings);
     205              :     }
     206            0 :   else if (tyseg->get_kind () == TyTy::TypeKind::FNDEF)
     207              :     {
     208            0 :       TyTy::FnType *fn = static_cast<TyTy::FnType *> (tyseg);
     209            0 :       return fn->are_mappings_bound (mappings);
     210              :     }
     211              : 
     212              :   return false;
     213              : }
     214              : 
     215              : void
     216         6591 : SubstMapperInternal::visit (TyTy::FnType &type)
     217              : {
     218         6591 :   TyTy::SubstitutionArgumentMappings adjusted
     219         6591 :     = type.adjust_mappings_for_this (mappings);
     220         6591 :   if (adjusted.is_error () && !mappings.trait_item_mode ())
     221            0 :     return;
     222         6591 :   if (adjusted.is_error () && mappings.trait_item_mode ())
     223            0 :     adjusted = mappings;
     224              : 
     225         6591 :   TyTy::BaseType *concrete = type.handle_substitions (adjusted);
     226         6591 :   if (concrete != nullptr)
     227         6591 :     resolved = concrete;
     228         6591 : }
     229              : 
     230              : void
     231         3356 : SubstMapperInternal::visit (TyTy::ADTType &type)
     232              : {
     233         3356 :   TyTy::SubstitutionArgumentMappings adjusted
     234         3356 :     = type.adjust_mappings_for_this (mappings);
     235         3356 :   if (adjusted.is_error () && !mappings.trait_item_mode ())
     236            0 :     return;
     237         3356 :   if (adjusted.is_error () && mappings.trait_item_mode ())
     238            8 :     adjusted = mappings;
     239              : 
     240         3356 :   TyTy::BaseType *concrete = type.handle_substitions (adjusted);
     241         3356 :   if (concrete != nullptr)
     242         3356 :     resolved = concrete;
     243         3356 : }
     244              : 
     245              : // these don't support generic arguments but might contain a type param
     246              : void
     247          264 : SubstMapperInternal::visit (TyTy::TupleType &type)
     248              : {
     249          264 :   resolved = type.handle_substitions (mappings);
     250          264 : }
     251              : 
     252              : void
     253         9957 : SubstMapperInternal::visit (TyTy::ReferenceType &type)
     254              : {
     255         9957 :   resolved = type.handle_substitions (mappings);
     256         9957 : }
     257              : 
     258              : void
     259         2930 : SubstMapperInternal::visit (TyTy::PointerType &type)
     260              : {
     261         2930 :   resolved = type.handle_substitions (mappings);
     262         2930 : }
     263              : 
     264              : void
     265        59064 : SubstMapperInternal::visit (TyTy::ParamType &type)
     266              : {
     267        59064 :   resolved = type.handle_substitions (mappings);
     268        59064 : }
     269              : 
     270              : void
     271           57 : SubstMapperInternal::visit (TyTy::ConstParamType &type)
     272              : {
     273           57 :   resolved = type.handle_substitions (mappings);
     274           57 : }
     275              : 
     276              : void
     277            0 : SubstMapperInternal::visit (TyTy::ConstValueType &type)
     278              : {
     279            0 :   resolved = type.clone ();
     280            0 : }
     281              : 
     282              : void
     283            0 : SubstMapperInternal::visit (TyTy::ConstInferType &type)
     284              : {
     285            0 :   resolved = type.clone ();
     286            0 : }
     287              : 
     288              : void
     289            0 : SubstMapperInternal::visit (TyTy::ConstErrorType &type)
     290              : {
     291            0 :   resolved = type.clone ();
     292            0 : }
     293              : 
     294              : void
     295          481 : SubstMapperInternal::visit (TyTy::PlaceholderType &type)
     296              : {
     297          481 :   rust_assert (type.can_resolve ());
     298          481 :   if (mappings.trait_item_mode ())
     299              :     {
     300          479 :       resolved = type.resolve ();
     301              :     }
     302              :   else
     303              :     {
     304            2 :       resolved = SubstMapperInternal::Resolve (type.resolve (), mappings);
     305              :     }
     306          481 : }
     307              : 
     308              : void
     309          745 : SubstMapperInternal::visit (TyTy::ProjectionType &type)
     310              : {
     311          745 :   resolved = type.handle_substitions (mappings);
     312          745 : }
     313              : 
     314              : void
     315            0 : SubstMapperInternal::visit (TyTy::ClosureType &type)
     316              : {
     317            0 :   resolved = type.handle_substitions (mappings);
     318            0 : }
     319              : 
     320              : void
     321           57 : SubstMapperInternal::visit (TyTy::ArrayType &type)
     322              : {
     323           57 :   resolved = type.handle_substitions (mappings);
     324           57 : }
     325              : 
     326              : void
     327         1128 : SubstMapperInternal::visit (TyTy::SliceType &type)
     328              : {
     329         1128 :   resolved = type.handle_substitions (mappings);
     330         1128 : }
     331              : void
     332            8 : SubstMapperInternal::visit (TyTy::FnPtr &type)
     333              : {
     334            8 :   resolved = type.handle_substitions (mappings);
     335            8 : }
     336              : 
     337              : // nothing to do for these
     338              : void
     339            0 : SubstMapperInternal::visit (TyTy::InferType &type)
     340              : {
     341            0 :   resolved = type.clone ();
     342            0 : }
     343              : void
     344            0 : SubstMapperInternal::visit (TyTy::BoolType &type)
     345              : {
     346            0 :   resolved = type.clone ();
     347            0 : }
     348              : void
     349            1 : SubstMapperInternal::visit (TyTy::IntType &type)
     350              : {
     351            1 :   resolved = type.clone ();
     352            1 : }
     353              : void
     354           73 : SubstMapperInternal::visit (TyTy::UintType &type)
     355              : {
     356           73 :   resolved = type.clone ();
     357           73 : }
     358              : void
     359            0 : SubstMapperInternal::visit (TyTy::FloatType &type)
     360              : {
     361            0 :   resolved = type.clone ();
     362            0 : }
     363              : void
     364           75 : SubstMapperInternal::visit (TyTy::USizeType &type)
     365              : {
     366           75 :   resolved = type.clone ();
     367           75 : }
     368              : void
     369           56 : SubstMapperInternal::visit (TyTy::ISizeType &type)
     370              : {
     371           56 :   resolved = type.clone ();
     372           56 : }
     373              : void
     374            0 : SubstMapperInternal::visit (TyTy::ErrorType &type)
     375              : {
     376            0 :   resolved = type.clone ();
     377            0 : }
     378              : void
     379            0 : SubstMapperInternal::visit (TyTy::CharType &type)
     380              : {
     381            0 :   resolved = type.clone ();
     382            0 : }
     383              : void
     384            0 : SubstMapperInternal::visit (TyTy::StrType &type)
     385              : {
     386            0 :   resolved = type.clone ();
     387            0 : }
     388              : void
     389            0 : SubstMapperInternal::visit (TyTy::NeverType &type)
     390              : {
     391            0 :   resolved = type.clone ();
     392            0 : }
     393              : void
     394            0 : SubstMapperInternal::visit (TyTy::DynamicObjectType &type)
     395              : {
     396            0 :   resolved = type.clone ();
     397            0 : }
     398              : void
     399            0 : SubstMapperInternal::visit (TyTy::OpaqueType &type)
     400              : {
     401            0 :   resolved = type.clone ();
     402            0 : }
     403              : 
     404              : // SubstMapperFromExisting
     405              : 
     406            0 : SubstMapperFromExisting::SubstMapperFromExisting (TyTy::BaseType *concrete,
     407            0 :                                                   TyTy::BaseType *receiver)
     408            0 :   : concrete (concrete), receiver (receiver), resolved (nullptr)
     409            0 : {}
     410              : 
     411              : TyTy::BaseType *
     412            0 : SubstMapperFromExisting::Resolve (TyTy::BaseType *concrete,
     413              :                                   TyTy::BaseType *receiver)
     414              : {
     415            0 :   rust_assert (concrete->get_kind () == receiver->get_kind ());
     416              : 
     417            0 :   SubstMapperFromExisting mapper (concrete, receiver);
     418            0 :   concrete->accept_vis (mapper);
     419            0 :   return mapper.resolved;
     420              : }
     421              : 
     422              : void
     423            0 : SubstMapperFromExisting::visit (TyTy::FnType &type)
     424              : {
     425            0 :   rust_assert (type.was_substituted ());
     426              : 
     427            0 :   TyTy::FnType *to_sub = static_cast<TyTy::FnType *> (receiver);
     428            0 :   resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
     429            0 : }
     430              : 
     431              : void
     432            0 : SubstMapperFromExisting::visit (TyTy::ADTType &type)
     433              : {
     434            0 :   rust_assert (type.was_substituted ());
     435              : 
     436            0 :   TyTy::ADTType *to_sub = static_cast<TyTy::ADTType *> (receiver);
     437            0 :   resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
     438            0 : }
     439              : 
     440              : void
     441            0 : SubstMapperFromExisting::visit (TyTy::ClosureType &type)
     442              : {
     443            0 :   rust_assert (type.was_substituted ());
     444              : 
     445            0 :   TyTy::ClosureType *to_sub = static_cast<TyTy::ClosureType *> (receiver);
     446            0 :   resolved = to_sub->handle_substitions (type.get_substitution_arguments ());
     447            0 : }
     448              : 
     449              : // GetUsedSubstArgs
     450              : 
     451        42965 : GetUsedSubstArgs::GetUsedSubstArgs ()
     452        42965 :   : args (TyTy::SubstitutionArgumentMappings::error ())
     453        42965 : {}
     454              : 
     455              : TyTy::SubstitutionArgumentMappings
     456        42965 : GetUsedSubstArgs::From (const TyTy::BaseType *from)
     457              : {
     458        42965 :   GetUsedSubstArgs mapper;
     459        42965 :   from->accept_vis (mapper);
     460        42965 :   return mapper.args;
     461        42965 : }
     462              : 
     463              : void
     464            0 : GetUsedSubstArgs::visit (const TyTy::FnType &type)
     465              : {
     466            0 :   args = type.get_substitution_arguments ();
     467            0 : }
     468              : 
     469              : void
     470        11026 : GetUsedSubstArgs::visit (const TyTy::ADTType &type)
     471              : {
     472        11026 :   args = type.get_substitution_arguments ();
     473        11026 : }
     474              : 
     475              : void
     476            0 : GetUsedSubstArgs::visit (const TyTy::ClosureType &type)
     477              : {
     478            0 :   args = type.get_substitution_arguments ();
     479            0 : }
     480              : 
     481              : } // namespace Resolver
     482              : } // 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.