LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-subst.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 17 17
Test Date: 2024-04-20 14:03:02 Functions: 100.0 % 4 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2024 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                 :             : #ifndef RUST_TYTY_SUBST_H
      20                 :             : #define RUST_TYTY_SUBST_H
      21                 :             : 
      22                 :             : #include "rust-system.h"
      23                 :             : #include "rust-location.h"
      24                 :             : #include "rust-hir-full-decls.h"
      25                 :             : #include "rust-tyty-bounds.h"
      26                 :             : #include "rust-tyty-region.h"
      27                 :             : 
      28                 :             : #include <optional.h>
      29                 :             : 
      30                 :             : namespace Rust {
      31                 :             : namespace TyTy {
      32                 :             : 
      33                 :             : class ParamType;
      34                 :             : 
      35                 :    12098245 : struct RegionConstraints
      36                 :             : {
      37                 :             :   /** 'a: 'b */
      38                 :             :   std::vector<std::pair<Region, Region>> region_region;
      39                 :             :   /** T: 'a */
      40                 :             :   std::vector<std::pair<ParamType *, Region>> type_region;
      41                 :             : };
      42                 :             : 
      43                 :             : class BaseType;
      44                 :             : class SubstitutionArgumentMappings;
      45                 :             : class SubstitutionParamMapping
      46                 :             : {
      47                 :             : public:
      48                 :             :   SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
      49                 :             : 
      50                 :             :   SubstitutionParamMapping (const SubstitutionParamMapping &other);
      51                 :             : 
      52                 :             :   std::string as_string () const;
      53                 :             : 
      54                 :             :   bool fill_param_ty (SubstitutionArgumentMappings &subst_mappings,
      55                 :             :                       location_t locus);
      56                 :             : 
      57                 :             :   SubstitutionParamMapping clone () const;
      58                 :             : 
      59                 :             :   ParamType *get_param_ty ();
      60                 :             : 
      61                 :             :   const ParamType *get_param_ty () const;
      62                 :             : 
      63                 :             :   const HIR::TypeParam &get_generic_param () const;
      64                 :             : 
      65                 :             :   // this is used for the backend to override the HirId ref of the param to
      66                 :             :   // what the concrete type is for the rest of the context
      67                 :             :   void override_context ();
      68                 :             : 
      69                 :             :   bool needs_substitution () const;
      70                 :             : 
      71                 :             :   location_t get_param_locus () const;
      72                 :             : 
      73                 :             :   bool param_has_default_ty () const;
      74                 :             : 
      75                 :             :   BaseType *get_default_ty () const;
      76                 :             : 
      77                 :             :   bool need_substitution () const;
      78                 :             : 
      79                 :             : private:
      80                 :             :   const HIR::TypeParam &generic;
      81                 :             :   ParamType *param;
      82                 :             : };
      83                 :             : 
      84                 :             : /**
      85                 :             :  * Represents the part of the parameter list that contains lifetime
      86                 :             :  * parameters.
      87                 :             :  *
      88                 :             :  * ```
      89                 :             :  * Foo<'a, 'b, i32, 8>
      90                 :             :  *     ^^^^^^
      91                 :             :  * ```
      92                 :             :  *
      93                 :             :  * It has fixed size based on the number of lifetime parameters and they are
      94                 :             :  * indexed based on their order.
      95                 :             :  *
      96                 :             :  * All regions are initially set to unresolved. When type instantiation is
      97                 :             :  * encountered, all explicitly mentioned lifetimes are resolved to bound
      98                 :             :  * lifetimes. The remaining unresolved lifetimes are set to anonymous. During
      99                 :             :  * BIR construction, all lifetimes are replaced with free region variables.
     100                 :             :  * Inference of anonymous regions happens automatically using BIR subtyping
     101                 :             :  * pass.
     102                 :             :  */
     103                 :    71583864 : class RegionParamList
     104                 :             : {
     105                 :             :   std::vector<Region> regions;
     106                 :             : 
     107                 :             : public:
     108                 :    11948430 :   RegionParamList (size_t num_regions) : regions (num_regions) {}
     109                 :             : 
     110                 :             :   Region *begin () { return regions.data (); }
     111                 :             :   Region *end () { return regions.data () + regions.size (); }
     112                 :             :   Region &operator[] (size_t index) { return regions.at (index); }
     113                 :             :   const Region &operator[] (size_t index) const { return regions.at (index); }
     114                 :             :   WARN_UNUSED_RESULT const Region *begin () const { return regions.data (); }
     115                 :             :   WARN_UNUSED_RESULT const Region *end () const
     116                 :             :   {
     117                 :             :     return regions.data () + regions.size ();
     118                 :             :   }
     119                 :        4794 :   size_t size () const { return regions.size (); }
     120                 :             : 
     121                 :             :   /**
     122                 :             :    * Takes regions from the `subst` parameter and fills the rest with anonymous
     123                 :             :    * regions.
     124                 :             :    */
     125                 :        4565 :   static RegionParamList from_subst (size_t num_regions,
     126                 :             :                                      std::vector<Region> subst)
     127                 :             :   {
     128                 :        4565 :     RegionParamList list (num_regions);
     129                 :        4573 :     for (size_t i = 0; i < subst.size (); i++)
     130                 :          16 :       list.regions.at (i) = subst.at (i);
     131                 :        4567 :     for (size_t i = subst.size (); i < num_regions; i++)
     132                 :             :       {
     133                 :           2 :         list.regions.at (i) = Region::make_anonymous ();
     134                 :             :       }
     135                 :        4565 :     return list;
     136                 :             :   }
     137                 :             : };
     138                 :             : 
     139                 :             : class SubstitutionArg
     140                 :             : {
     141                 :             : public:
     142                 :             :   SubstitutionArg (const SubstitutionParamMapping *param, BaseType *argument);
     143                 :             : 
     144                 :             :   // FIXME
     145                 :             :   // the copy constructors need removed - they are unsafe see
     146                 :             :   // TypeBoundPredicate
     147                 :             :   SubstitutionArg (const SubstitutionArg &other);
     148                 :             : 
     149                 :             :   SubstitutionArg &operator= (const SubstitutionArg &other);
     150                 :             : 
     151                 :             :   BaseType *get_tyty ();
     152                 :             : 
     153                 :             :   const BaseType *get_tyty () const;
     154                 :             : 
     155                 :             :   const SubstitutionParamMapping *get_param_mapping () const;
     156                 :             : 
     157                 :             :   const ParamType *get_param_ty () const;
     158                 :             : 
     159                 :             :   static SubstitutionArg error ();
     160                 :             : 
     161                 :             :   bool is_error () const;
     162                 :             : 
     163                 :             :   bool is_conrete () const;
     164                 :             : 
     165                 :             :   std::string as_string () const;
     166                 :             : 
     167                 :             : private:
     168                 :             :   const SubstitutionParamMapping *param;
     169                 :             :   const ParamType *original_param;
     170                 :             :   BaseType *argument;
     171                 :             : };
     172                 :             : 
     173                 :             : typedef std::function<void (const ParamType &, const SubstitutionArg &)>
     174                 :             :   ParamSubstCb;
     175                 :             : class SubstitutionArgumentMappings
     176                 :             : {
     177                 :             : public:
     178                 :             :   SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings,
     179                 :             :                                 std::map<std::string, BaseType *> binding_args,
     180                 :             :                                 RegionParamList regions, location_t locus,
     181                 :             :                                 ParamSubstCb param_subst_cb = nullptr,
     182                 :             :                                 bool trait_item_flag = false,
     183                 :             :                                 bool error_flag = false);
     184                 :             : 
     185                 :             :   SubstitutionArgumentMappings (const SubstitutionArgumentMappings &other);
     186                 :             :   SubstitutionArgumentMappings &
     187                 :             :   operator= (const SubstitutionArgumentMappings &other);
     188                 :             : 
     189                 :       44953 :   SubstitutionArgumentMappings (SubstitutionArgumentMappings &&other) = default;
     190                 :    11880053 :   SubstitutionArgumentMappings &operator= (SubstitutionArgumentMappings &&other)
     191                 :             :     = default;
     192                 :             : 
     193                 :             :   static SubstitutionArgumentMappings error ();
     194                 :             : 
     195                 :             :   /** Creates empty substitution argument mappings with unresolved regions */
     196                 :             :   static SubstitutionArgumentMappings empty (size_t num_regions = 0);
     197                 :             : 
     198                 :             :   static RegionParamList
     199                 :        2601 :   regions_from_nullable_args (SubstitutionArgumentMappings *args)
     200                 :             :   {
     201                 :        2601 :     if (args == nullptr)
     202                 :        1882 :       return RegionParamList (0);
     203                 :             : 
     204                 :         719 :     return args->get_regions ();
     205                 :             :   }
     206                 :             : 
     207                 :             :   bool is_error () const;
     208                 :             : 
     209                 :             :   bool get_argument_for_symbol (const ParamType *param_to_find,
     210                 :             :                                 SubstitutionArg *argument) const;
     211                 :             : 
     212                 :             :   /** Return type parameter index for symbol */
     213                 :             :   tl::optional<size_t> find_symbol (const ParamType &param_to_find) const;
     214                 :             : 
     215                 :             :   bool get_argument_at (size_t index, SubstitutionArg *argument);
     216                 :             : 
     217                 :             :   // is_concrete means if the used args is non error, ie: non empty this will
     218                 :             :   // verify if actual real types have been put in place of are they still
     219                 :             :   // ParamTy
     220                 :             :   bool is_concrete () const;
     221                 :             : 
     222                 :             :   location_t get_locus () const;
     223                 :             : 
     224                 :             :   size_t size () const;
     225                 :             : 
     226                 :             :   bool is_empty () const;
     227                 :             : 
     228                 :             :   std::vector<SubstitutionArg> &get_mappings ();
     229                 :             : 
     230                 :             :   const std::vector<SubstitutionArg> &get_mappings () const;
     231                 :             : 
     232                 :             :   std::map<std::string, BaseType *> &get_binding_args ();
     233                 :             : 
     234                 :             :   const std::map<std::string, BaseType *> &get_binding_args () const;
     235                 :             : 
     236                 :             :   const RegionParamList &get_regions () const;
     237                 :             :   RegionParamList &get_mut_regions ();
     238                 :             : 
     239                 :             :   std::string as_string () const;
     240                 :             : 
     241                 :             :   void on_param_subst (const ParamType &p, const SubstitutionArg &a) const;
     242                 :             : 
     243                 :             :   ParamSubstCb get_subst_cb () const;
     244                 :             : 
     245                 :             :   bool trait_item_mode () const;
     246                 :             : 
     247                 :             : private:
     248                 :             :   std::vector<SubstitutionArg> mappings;
     249                 :             :   std::map<std::string, BaseType *> binding_args;
     250                 :             :   RegionParamList regions;
     251                 :             :   location_t locus;
     252                 :             :   ParamSubstCb param_subst_cb;
     253                 :             :   bool trait_item_flag;
     254                 :             :   bool error_flag;
     255                 :             : };
     256                 :             : 
     257                 :             : class SubstitutionRef
     258                 :             : {
     259                 :             : public:
     260                 :             :   SubstitutionRef (std::vector<SubstitutionParamMapping> substitutions,
     261                 :             :                    SubstitutionArgumentMappings arguments,
     262                 :             :                    RegionConstraints region_constraints);
     263                 :             : 
     264                 :             :   bool has_substitutions () const;
     265                 :             : 
     266                 :             :   std::string subst_as_string () const;
     267                 :             : 
     268                 :             :   bool supports_associated_bindings () const;
     269                 :             : 
     270                 :             :   // this is overridden in TypeBoundPredicate
     271                 :             :   // which support bindings we don't add them directly to the SubstitutionRef
     272                 :             :   // base class because this class represents the fn<X: Foo, Y: Bar>. The only
     273                 :             :   // construct which supports associated types
     274                 :             :   virtual size_t get_num_associated_bindings () const;
     275                 :             : 
     276                 :             :   // this is overridden in TypeBoundPredicate
     277                 :             :   virtual TypeBoundPredicateItem
     278                 :             :   lookup_associated_type (const std::string &search);
     279                 :             : 
     280                 :             :   size_t get_num_substitutions () const;
     281                 :             : 
     282                 :             :   size_t get_num_lifetime_params () const;
     283                 :             : 
     284                 :             :   size_t get_num_type_params () const;
     285                 :             : 
     286                 :             :   std::vector<SubstitutionParamMapping> &get_substs ();
     287                 :             : 
     288                 :             :   const std::vector<SubstitutionParamMapping> &get_substs () const;
     289                 :             : 
     290                 :             :   std::vector<SubstitutionParamMapping> clone_substs () const;
     291                 :             : 
     292                 :             :   void override_context ();
     293                 :             : 
     294                 :             :   bool needs_substitution () const;
     295                 :             : 
     296                 :             :   bool was_substituted () const;
     297                 :             : 
     298                 :             :   SubstitutionArgumentMappings &get_substitution_arguments ();
     299                 :             :   const SubstitutionArgumentMappings &get_substitution_arguments () const;
     300                 :             : 
     301                 :             :   // this is the count of type params that are not substituted fuly
     302                 :             :   size_t num_required_substitutions () const;
     303                 :             : 
     304                 :             :   // this is the count of type params that need substituted taking into account
     305                 :             :   // possible defaults
     306                 :             :   size_t min_required_substitutions () const;
     307                 :             : 
     308                 :             :   // We are trying to subst <i32, f32> into Struct Foo<X,Y> {}
     309                 :             :   // in the case of Foo<i32,f32>{...}
     310                 :             :   //
     311                 :             :   // the substitions we have here define X,Y but the arguments have no bindings
     312                 :             :   // so its a matter of ordering
     313                 :             :   SubstitutionArgumentMappings
     314                 :             :   get_mappings_from_generic_args (HIR::GenericArgs &args,
     315                 :             :                                   const std::vector<Region> &regions);
     316                 :             : 
     317                 :             :   // Recursive substitutions
     318                 :             :   // Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
     319                 :             :   //
     320                 :             :   // we have bindings for X Y Z and need to propagate the binding Y,Z into Foo
     321                 :             :   // Which binds to A,B
     322                 :             :   SubstitutionArgumentMappings
     323                 :             :   adjust_mappings_for_this (SubstitutionArgumentMappings &mappings);
     324                 :             : 
     325                 :             :   // Are the mappings here actually bound to this type. For example imagine the
     326                 :             :   // case:
     327                 :             :   //
     328                 :             :   // struct Foo<T>(T);
     329                 :             :   // impl<T> Foo<T> {
     330                 :             :   //   fn test(self) { ... }
     331                 :             :   // }
     332                 :             :   //
     333                 :             :   // In this case we have a generic ADT of Foo and an impl block of a generic T
     334                 :             :   // on Foo for the Self type. When we it comes to path resolution we can have:
     335                 :             :   //
     336                 :             :   // Foo::<i32>::test()
     337                 :             :   //
     338                 :             :   // This means the first segment of Foo::<i32> returns the ADT Foo<i32> not the
     339                 :             :   // Self ADT bound to the T from the impl block. This means when it comes to
     340                 :             :   // the next segment of test which resolves to the function we need to check
     341                 :             :   // wether the arguments in the struct definition of foo can be bound here
     342                 :             :   // before substituting the previous segments type here. This functions acts as
     343                 :             :   // a guard for the solve_mappings_from_receiver_for_self to handle the case
     344                 :             :   // where arguments are not bound. This is important for this next case:
     345                 :             :   //
     346                 :             :   // struct Baz<A, B>(A, B);
     347                 :             :   // impl Baz<i32, f32> {
     348                 :             :   //   fn test<X>(a: X) -> X {
     349                 :             :   //       a
     350                 :             :   //   }
     351                 :             :   // }
     352                 :             :   //
     353                 :             :   // In this case Baz has been already substituted for the impl's Self to become
     354                 :             :   // ADT<i32, f32> so that the function test only has 1 generic argument of X.
     355                 :             :   // The path for this will be:
     356                 :             :   //
     357                 :             :   // Baz::test::<_>(123)
     358                 :             :   //
     359                 :             :   // So the first segment here will be Baz<_, _> to try and infer the arguments
     360                 :             :   // which will be taken from the impl's Self type in this case since it is
     361                 :             :   // already substituted and like the previous case the check to see if we need
     362                 :             :   // to inherit the previous segments generic arguments takes place but the
     363                 :             :   // generic arguments are not bound to this type as they have already been
     364                 :             :   // substituted.
     365                 :             :   //
     366                 :             :   // Its important to remember from the first example the FnType actually looks
     367                 :             :   // like:
     368                 :             :   //
     369                 :             :   // fn <T>test(self :Foo<T>(T))
     370                 :             :   //
     371                 :             :   // As the generic parameters are "bound" to each of the items in the impl
     372                 :             :   // block. So this check is about wether the arguments we have here can
     373                 :             :   // actually be bound to this type.
     374                 :             :   bool are_mappings_bound (SubstitutionArgumentMappings &mappings);
     375                 :             : 
     376                 :             :   // struct Foo<A, B>(A, B);
     377                 :             :   //
     378                 :             :   // impl<T> Foo<T, f32>;
     379                 :             :   //     -> fn test<X>(self, a: X) -> X
     380                 :             :   //
     381                 :             :   // We might invoke this via:
     382                 :             :   //
     383                 :             :   // a = Foo(123, 456f32);
     384                 :             :   // b = a.test::<bool>(false);
     385                 :             :   //
     386                 :             :   // we need to figure out relevant generic arguemts for self to apply to the
     387                 :             :   // fntype
     388                 :             :   SubstitutionArgumentMappings solve_mappings_from_receiver_for_self (
     389                 :             :     SubstitutionArgumentMappings &mappings) const;
     390                 :             : 
     391                 :             :   // Given a type such as:
     392                 :             :   //
     393                 :             :   //   fn<X,Y>(a:&X, b:Y) -> (...)
     394                 :             :   //
     395                 :             :   // This function will inject implicit inference variables for the type
     396                 :             :   // parameters X and Y
     397                 :             :   BaseType *infer_substitions (location_t locus);
     398                 :             : 
     399                 :             :   // this clears any possible projections from higher ranked trait bounds which
     400                 :             :   // could be hanging around from a previous resolution
     401                 :             :   void prepare_higher_ranked_bounds ();
     402                 :             : 
     403                 :             :   // FIXME
     404                 :             :   // this is bad name for this, i think it should be something like
     405                 :             :   // compute-higher-ranked-bounds
     406                 :             :   bool monomorphize ();
     407                 :             : 
     408                 :             :   // TODO comment
     409                 :             :   virtual BaseType *handle_substitions (SubstitutionArgumentMappings &mappings)
     410                 :             :     = 0;
     411                 :             : 
     412                 :             :   WARN_UNUSED_RESULT const SubstitutionArgumentMappings &
     413                 :             :   get_used_arguments () const;
     414                 :             : 
     415                 :             :   WARN_UNUSED_RESULT tl::optional<SubstitutionArg> get_arg_at (size_t i) const;
     416                 :             : 
     417                 :             :   const RegionConstraints &get_region_constraints () const;
     418                 :             : 
     419                 :             : protected:
     420                 :             :   std::vector<SubstitutionParamMapping> substitutions;
     421                 :             :   SubstitutionArgumentMappings used_arguments;
     422                 :             :   RegionConstraints region_constraints;
     423                 :             : };
     424                 :             : 
     425                 :             : } // namespace TyTy
     426                 :             : } // namespace Rust
     427                 :             : #endif // RUST_TYTY_SUBST_H
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.