(root)/
gcc-13.2.0/
gcc/
rust/
typecheck/
rust-hir-trait-reference.h
       1  // Copyright (C) 2021-2023 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_HIR_TRAIT_REF_H
      20  #define RUST_HIR_TRAIT_REF_H
      21  
      22  #include "rust-hir-full.h"
      23  #include "rust-hir-type-check-util.h"
      24  #include "rust-tyty-visitor.h"
      25  
      26  namespace Rust {
      27  namespace Resolver {
      28  
      29  // Data Objects for the associated trait items in a structure we can work with
      30  // https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/associated-constants.html
      31  class TypeCheckContext;
      32  class TraitItemReference
      33  {
      34  public:
      35    enum TraitItemType
      36    {
      37      FN,
      38      CONST,
      39      TYPE,
      40      ERROR
      41    };
      42  
      43    TraitItemReference (std::string identifier, bool optional, TraitItemType type,
      44  		      HIR::TraitItem *hir_trait_item, TyTy::BaseType *self,
      45  		      std::vector<TyTy::SubstitutionParamMapping> substitutions,
      46  		      Location locus);
      47  
      48    TraitItemReference (TraitItemReference const &other);
      49  
      50    TraitItemReference &operator= (TraitItemReference const &other);
      51  
      52    static TraitItemReference error ()
      53    {
      54      return TraitItemReference ("", false, ERROR, nullptr, nullptr, {},
      55  			       Location ());
      56    }
      57  
      58    static TraitItemReference &error_node ()
      59    {
      60      static TraitItemReference error = TraitItemReference::error ();
      61      return error;
      62    }
      63  
      64    bool is_error () const;
      65  
      66    std::string as_string () const;
      67  
      68    static std::string trait_item_type_as_string (TraitItemType ty)
      69    {
      70      switch (ty)
      71        {
      72        case FN:
      73  	return "FN";
      74        case CONST:
      75  	return "CONST";
      76        case TYPE:
      77  	return "TYPE";
      78        case ERROR:
      79  	return "ERROR";
      80        }
      81      return "ERROR";
      82    }
      83  
      84    bool is_optional () const;
      85  
      86    std::string get_identifier () const;
      87  
      88    TraitItemType get_trait_item_type () const;
      89  
      90    HIR::TraitItem *get_hir_trait_item () const;
      91  
      92    Location get_locus () const;
      93  
      94    const Analysis::NodeMapping get_mappings () const;
      95  
      96    TyTy::BaseType *get_tyty () const;
      97  
      98    Analysis::NodeMapping get_parent_trait_mappings () const;
      99  
     100    // this is called when the trait is completed resolution and gives the items
     101    // a chance to run their specific type resolution passes. If we call their
     102    // resolution on construction it can lead to a case where the trait being
     103    // resolved recursively trying to resolve the trait itself infinitely since
     104    // the trait will not be stored in its own map yet
     105    void on_resolved ();
     106  
     107    void associated_type_set (TyTy::BaseType *ty) const;
     108  
     109    void associated_type_reset (bool only_projections) const;
     110  
     111    bool is_object_safe () const;
     112  
     113  private:
     114    TyTy::ErrorType *get_error () const;
     115  
     116    TyTy::BaseType *get_type_from_typealias (/*const*/
     117  					   HIR::TraitItemType &type) const;
     118  
     119    TyTy::BaseType *
     120    get_type_from_constant (/*const*/ HIR::TraitItemConst &constant) const;
     121  
     122    TyTy::BaseType *get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const;
     123  
     124    bool is_item_resolved () const;
     125    void resolve_item (HIR::TraitItemType &type);
     126    void resolve_item (HIR::TraitItemConst &constant);
     127    void resolve_item (HIR::TraitItemFunc &func);
     128  
     129    std::string identifier;
     130    bool optional_flag;
     131    TraitItemType type;
     132    HIR::TraitItem *hir_trait_item;
     133    std::vector<TyTy::SubstitutionParamMapping> inherited_substitutions;
     134    Location locus;
     135  
     136    TyTy::BaseType
     137      *self; // this is the implict Self TypeParam required for methods
     138    Resolver::TypeCheckContext *context;
     139  };
     140  
     141  // this wraps up the HIR::Trait so we can do analysis on it
     142  
     143  class TraitReference
     144  {
     145  public:
     146    TraitReference (const HIR::Trait *hir_trait_ref,
     147  		  std::vector<TraitItemReference> item_refs,
     148  		  std::vector<const TraitReference *> super_traits,
     149  		  std::vector<TyTy::SubstitutionParamMapping> substs);
     150  
     151    TraitReference (TraitReference const &other);
     152  
     153    TraitReference &operator= (TraitReference const &other);
     154  
     155    TraitReference (TraitReference &&other) = default;
     156    TraitReference &operator= (TraitReference &&other) = default;
     157  
     158    static TraitReference error ()
     159    {
     160      return TraitReference (nullptr, {}, {}, {});
     161    }
     162  
     163    bool is_error () const;
     164  
     165    static TraitReference &error_node ()
     166    {
     167      static TraitReference trait_error_node = TraitReference::error ();
     168      return trait_error_node;
     169    }
     170  
     171    Location get_locus () const;
     172  
     173    std::string get_name () const;
     174  
     175    std::string as_string () const;
     176  
     177    const HIR::Trait *get_hir_trait_ref () const;
     178  
     179    const Analysis::NodeMapping &get_mappings () const;
     180  
     181    DefId get_defid () const;
     182  
     183    bool lookup_hir_trait_item (const HIR::TraitItem &item,
     184  			      TraitItemReference **ref);
     185  
     186    bool lookup_trait_item (const std::string &ident, TraitItemReference **ref);
     187  
     188    bool lookup_trait_item_by_type (const std::string &ident,
     189  				  TraitItemReference::TraitItemType type,
     190  				  TraitItemReference **ref);
     191  
     192    bool lookup_trait_item_by_type (const std::string &ident,
     193  				  TraitItemReference::TraitItemType type,
     194  				  const TraitItemReference **ref) const;
     195  
     196    bool lookup_hir_trait_item (const HIR::TraitItem &item,
     197  			      const TraitItemReference **ref) const;
     198  
     199    bool lookup_trait_item (const std::string &ident,
     200  			  const TraitItemReference **ref) const;
     201  
     202    const TraitItemReference *
     203    lookup_trait_item (const std::string &ident,
     204  		     TraitItemReference::TraitItemType type) const;
     205  
     206    size_t size () const;
     207  
     208    const std::vector<TraitItemReference> &get_trait_items () const;
     209  
     210    void get_trait_items_and_supers (
     211      std::vector<const TraitItemReference *> &result) const;
     212  
     213    void on_resolved ();
     214  
     215    void clear_associated_types () const;
     216  
     217    void clear_associated_type_projections () const;
     218  
     219    bool is_equal (const TraitReference &other) const;
     220  
     221    const std::vector<const TraitReference *> get_super_traits () const;
     222  
     223    bool is_object_safe (bool emit_error, Location locus) const;
     224  
     225    bool trait_has_generics () const;
     226  
     227    std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const;
     228  
     229    bool satisfies_bound (const TraitReference &reference) const;
     230  
     231  private:
     232    const HIR::Trait *hir_trait_ref;
     233    std::vector<TraitItemReference> item_refs;
     234    std::vector<const TraitReference *> super_traits;
     235    std::vector<TyTy::SubstitutionParamMapping> trait_substs;
     236  };
     237  
     238  class AssociatedImplTrait
     239  {
     240  public:
     241    AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl,
     242  		       TyTy::BaseType *self,
     243  		       Resolver::TypeCheckContext *context);
     244  
     245    TraitReference *get_trait ();
     246  
     247    HIR::ImplBlock *get_impl_block ();
     248  
     249    TyTy::BaseType *get_self ();
     250    const TyTy::BaseType *get_self () const;
     251  
     252    TyTy::BaseType *
     253    setup_associated_types (const TyTy::BaseType *self,
     254  			  const TyTy::TypeBoundPredicate &bound);
     255  
     256    void reset_associated_types ();
     257  
     258  private:
     259    TraitReference *trait;
     260    HIR::ImplBlock *impl;
     261    TyTy::BaseType *self;
     262    Resolver::TypeCheckContext *context;
     263  };
     264  
     265  } // namespace Resolver
     266  } // namespace Rust
     267  
     268  #endif // RUST_HIR_TRAIT_REF_H