(root)/
gcc-13.2.0/
gcc/
rust/
typecheck/
rust-hir-path-probe.h
       1  // Copyright (C) 2020-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_PATH_PROBE_H
      20  #define RUST_HIR_PATH_PROBE_H
      21  
      22  #include "rust-hir-type-check-base.h"
      23  #include "rust-hir-full.h"
      24  #include "rust-tyty.h"
      25  #include "rust-substitution-mapper.h"
      26  #include "rust-hir-type-bounds.h"
      27  
      28  namespace Rust {
      29  namespace Resolver {
      30  
      31  struct PathProbeCandidate
      32  {
      33    enum CandidateType
      34    {
      35      ERROR,
      36  
      37      ENUM_VARIANT,
      38  
      39      IMPL_CONST,
      40      IMPL_TYPE_ALIAS,
      41      IMPL_FUNC,
      42  
      43      TRAIT_ITEM_CONST,
      44      TRAIT_TYPE_ALIAS,
      45      TRAIT_FUNC,
      46    };
      47  
      48    struct EnumItemCandidate
      49    {
      50      const TyTy::ADTType *parent;
      51      const TyTy::VariantDef *variant;
      52    };
      53  
      54    struct ImplItemCandidate
      55    {
      56      HIR::ImplItem *impl_item;
      57      HIR::ImplBlock *parent;
      58    };
      59  
      60    struct TraitItemCandidate
      61    {
      62      const TraitReference *trait_ref;
      63      const TraitItemReference *item_ref;
      64      HIR::ImplBlock *impl;
      65    };
      66  
      67    CandidateType type;
      68    TyTy::BaseType *ty;
      69    Location locus;
      70    union Candidate
      71    {
      72      EnumItemCandidate enum_field;
      73      ImplItemCandidate impl;
      74      TraitItemCandidate trait;
      75  
      76      Candidate (EnumItemCandidate enum_field);
      77      Candidate (ImplItemCandidate impl);
      78      Candidate (TraitItemCandidate trait);
      79    } item;
      80  
      81    PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
      82  		      EnumItemCandidate enum_field);
      83  
      84    PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
      85  		      ImplItemCandidate impl);
      86  
      87    PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
      88  		      TraitItemCandidate trait);
      89  
      90    std::string as_string () const;
      91  
      92    bool is_enum_candidate () const;
      93  
      94    bool is_impl_candidate () const;
      95  
      96    bool is_trait_candidate () const;
      97  
      98    bool is_full_trait_item_candidate () const;
      99  
     100    static PathProbeCandidate get_error ();
     101  
     102    bool is_error () const;
     103  
     104    DefId get_defid () const;
     105  
     106    bool operator< (const PathProbeCandidate &c) const;
     107  };
     108  
     109  class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor
     110  {
     111  public:
     112    static std::set<PathProbeCandidate>
     113    Probe (const TyTy::BaseType *receiver,
     114  	 const HIR::PathIdentSegment &segment_name, bool probe_impls,
     115  	 bool probe_bounds, bool ignore_mandatory_trait_items,
     116  	 DefId specific_trait_id = UNKNOWN_DEFID);
     117  
     118    void visit (HIR::TypeAlias &alias) override;
     119    void visit (HIR::ConstantItem &constant) override;
     120    void visit (HIR::Function &function) override;
     121  
     122  protected:
     123    void process_enum_item_for_candiates (const TyTy::ADTType *adt);
     124  
     125    void process_impl_items_for_candidates ();
     126  
     127    void process_impl_item_candidate (HirId id, HIR::ImplItem *item,
     128  				    HIR::ImplBlock *impl);
     129  
     130    void
     131    process_associated_trait_for_candidates (const TraitReference *trait_ref,
     132  					   HIR::ImplBlock *impl,
     133  					   bool ignore_mandatory_trait_items);
     134  
     135    void
     136    process_predicate_for_candidates (const TyTy::TypeBoundPredicate &predicate,
     137  				    bool ignore_mandatory_trait_items);
     138  
     139  protected:
     140    PathProbeType (const TyTy::BaseType *receiver,
     141  		 const HIR::PathIdentSegment &query, DefId specific_trait_id);
     142  
     143    std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
     144    union_bounds (
     145      const std::vector<std::pair</*const*/ TraitReference *, HIR::ImplBlock *>>
     146        a,
     147      const std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>> b)
     148      const;
     149  
     150    bool is_reciever_generic () const;
     151  
     152    const TyTy::BaseType *receiver;
     153    const HIR::PathIdentSegment &search;
     154    std::set<PathProbeCandidate> candidates;
     155    HIR::ImplBlock *current_impl;
     156    DefId specific_trait_id;
     157  };
     158  
     159  class ReportMultipleCandidateError : private TypeCheckBase
     160  {
     161  public:
     162    static void Report (std::set<PathProbeCandidate> &candidates,
     163  		      const HIR::PathIdentSegment &query, Location query_locus)
     164    {
     165      RichLocation r (query_locus);
     166      for (auto &c : candidates)
     167        r.add_range (c.locus);
     168  
     169      rust_error_at (r, "multiple applicable items in scope for: %s",
     170  		   query.as_string ().c_str ());
     171    }
     172  };
     173  
     174  class PathProbeImplTrait : public PathProbeType
     175  {
     176  public:
     177    static std::set<PathProbeCandidate>
     178    Probe (const TyTy::BaseType *receiver,
     179  	 const HIR::PathIdentSegment &segment_name,
     180  	 const TraitReference *trait_reference);
     181  
     182  private:
     183    PathProbeImplTrait (const TyTy::BaseType *receiver,
     184  		      const HIR::PathIdentSegment &query,
     185  		      const TraitReference *trait_reference);
     186  
     187    void process_trait_impl_items_for_candidates ();
     188  
     189    const TraitReference *trait_reference;
     190  };
     191  
     192  } // namespace Resolver
     193  } // namespace Rust
     194  
     195  #endif // RUST_HIR_PATH_PROBE_H