(root)/
gcc-13.2.0/
gcc/
rust/
resolve/
rust-ast-resolve-type.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_AST_RESOLVE_TYPE_H
      20  #define RUST_AST_RESOLVE_TYPE_H
      21  
      22  #include "rust-ast-resolve-base.h"
      23  #include "rust-ast-resolve-expr.h"
      24  #include "rust-ast-full.h"
      25  
      26  namespace Rust {
      27  namespace Resolver {
      28  
      29  class ResolveRelativeTypePath
      30  {
      31  public:
      32    static bool go (AST::TypePath &path, NodeId &resolved_node_id);
      33  };
      34  
      35  class ResolveRelativeQualTypePath : public ResolverBase
      36  {
      37    using ResolverBase::visit;
      38  
      39  public:
      40    static bool go (AST::QualifiedPathInType &path);
      41  
      42    void visit (AST::TypePathSegmentGeneric &seg) override;
      43  
      44    void visit (AST::TypePathSegment &seg) override;
      45  
      46  protected:
      47    bool resolve_qual_seg (AST::QualifiedPathType &seg);
      48  
      49  private:
      50    ResolveRelativeQualTypePath ();
      51  
      52    bool failure_flag;
      53  };
      54  
      55  class ResolveType : public ResolverBase
      56  {
      57    using Rust::Resolver::ResolverBase::visit;
      58  
      59  public:
      60    static NodeId go (AST::Type *type)
      61    {
      62      ResolveType resolver;
      63      type->accept_vis (resolver);
      64      return resolver.resolved_node;
      65    }
      66  
      67    void visit (AST::BareFunctionType &fntype) override
      68    {
      69      for (auto &param : fntype.get_function_params ())
      70        ResolveType::go (param.get_type ().get ());
      71  
      72      if (fntype.has_return_type ())
      73        ResolveType::go (fntype.get_return_type ().get ());
      74    }
      75  
      76    void visit (AST::TupleType &tuple) override
      77    {
      78      if (tuple.is_unit_type ())
      79        {
      80  	resolved_node = resolver->get_unit_type_node_id ();
      81  	return;
      82        }
      83  
      84      for (auto &elem : tuple.get_elems ())
      85        ResolveType::go (elem.get ());
      86    }
      87  
      88    void visit (AST::TypePath &path) override
      89    {
      90      ResolveRelativeTypePath::go (path, resolved_node);
      91    }
      92  
      93    void visit (AST::QualifiedPathInType &path) override
      94    {
      95      ResolveRelativeQualTypePath::go (path);
      96    }
      97  
      98    void visit (AST::ArrayType &type) override;
      99  
     100    void visit (AST::ReferenceType &type) override;
     101  
     102    void visit (AST::InferredType &type) override;
     103  
     104    void visit (AST::NeverType &type) override;
     105  
     106    void visit (AST::RawPointerType &type) override;
     107  
     108    void visit (AST::TraitObjectTypeOneBound &type) override;
     109  
     110    void visit (AST::TraitObjectType &type) override;
     111  
     112    void visit (AST::SliceType &type) override;
     113  
     114  private:
     115    ResolveType () : ResolverBase () {}
     116  };
     117  
     118  class ResolveTypeBound : public ResolverBase
     119  {
     120    using Rust::Resolver::ResolverBase::visit;
     121  
     122  public:
     123    static NodeId go (AST::TypeParamBound *type)
     124    {
     125      ResolveTypeBound resolver;
     126      type->accept_vis (resolver);
     127      return resolver.resolved_node;
     128    };
     129  
     130    void visit (AST::TraitBound &bound) override
     131    {
     132      resolved_node = ResolveType::go (&bound.get_type_path ());
     133    }
     134  
     135  private:
     136    ResolveTypeBound () : ResolverBase () {}
     137  };
     138  
     139  class ResolveGenericParam : public ResolverBase
     140  {
     141    using Rust::Resolver::ResolverBase::visit;
     142  
     143  public:
     144    static NodeId go (AST::GenericParam *param, const CanonicalPath &prefix,
     145  		    const CanonicalPath &canonical_prefix)
     146    {
     147      ResolveGenericParam resolver (prefix, canonical_prefix);
     148      param->accept_vis (resolver);
     149      return resolver.resolved_node;
     150    }
     151  
     152    void visit (AST::ConstGenericParam &param) override
     153    {
     154      ResolveType::go (param.get_type ().get ());
     155  
     156      if (param.has_default_value ())
     157        ResolveExpr::go (param.get_default_value ().get_expression ().get (),
     158  		       prefix, canonical_prefix);
     159  
     160      ok = true;
     161    }
     162  
     163    void visit (AST::TypeParam &param) override
     164    {
     165      // if it has a type lets resolve it
     166      if (param.has_type ())
     167        ResolveType::go (param.get_type ().get ());
     168  
     169      if (param.has_type_param_bounds ())
     170        {
     171  	for (auto &bound : param.get_type_param_bounds ())
     172  	  {
     173  	    ResolveTypeBound::go (bound.get ());
     174  	  }
     175        }
     176  
     177      auto seg = CanonicalPath::new_seg (param.get_node_id (),
     178  				       param.get_type_representation ());
     179      resolver->get_type_scope ().insert (
     180        seg, param.get_node_id (), param.get_locus (), false, Rib::ItemType::Type,
     181        [&] (const CanonicalPath &, NodeId, Location locus) -> void {
     182  	rust_error_at (param.get_locus (),
     183  		       "generic param redefined multiple times");
     184  	rust_error_at (locus, "was defined here");
     185        });
     186  
     187      mappings->insert_canonical_path (param.get_node_id (), seg);
     188    }
     189  
     190  private:
     191    ResolveGenericParam (const CanonicalPath &prefix,
     192  		       const CanonicalPath &canonical_prefix)
     193      : ResolverBase (), ok (false), prefix (prefix),
     194        canonical_prefix (canonical_prefix)
     195    {}
     196  
     197    bool ok;
     198    const CanonicalPath &prefix;
     199    const CanonicalPath &canonical_prefix;
     200  };
     201  
     202  class ResolveWhereClause : public ResolverBase
     203  {
     204    using Rust::Resolver::ResolverBase::visit;
     205  
     206  public:
     207    static void Resolve (AST::WhereClause &where_clause)
     208    {
     209      ResolveWhereClause r;
     210      for (auto &clause : where_clause.get_items ())
     211        clause->accept_vis (r);
     212    }
     213  
     214    void visit (AST::TypeBoundWhereClauseItem &item) override
     215    {
     216      ResolveType::go (item.get_type ().get ());
     217      if (item.has_type_param_bounds ())
     218        {
     219  	for (auto &bound : item.get_type_param_bounds ())
     220  	  {
     221  	    ResolveTypeBound::go (bound.get ());
     222  	  }
     223        }
     224    }
     225  
     226  private:
     227    ResolveWhereClause () : ResolverBase () {}
     228  };
     229  
     230  class ResolveTypeToCanonicalPath : public ResolverBase
     231  {
     232    using Rust::Resolver::ResolverBase::visit;
     233  
     234  public:
     235    static bool go (AST::Type *type, CanonicalPath &result);
     236  
     237    void visit (AST::TypePath &path) override;
     238  
     239    void visit (AST::ReferenceType &type) override;
     240  
     241    void visit (AST::RawPointerType &type) override;
     242  
     243    void visit (AST::SliceType &type) override;
     244  
     245    void visit (AST::TraitObjectTypeOneBound &type) override;
     246  
     247    void visit (AST::TraitObjectType &type) override;
     248  
     249  private:
     250    ResolveTypeToCanonicalPath ();
     251  
     252    CanonicalPath result;
     253  };
     254  
     255  class ResolveGenericArgs : public ResolverBase
     256  {
     257    using Rust::Resolver::ResolverBase::visit;
     258  
     259  public:
     260    static void go (AST::GenericArgs &generic_args);
     261    static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix,
     262  		  const CanonicalPath &canonical_prefix);
     263  
     264  private:
     265    ResolveGenericArgs (const CanonicalPath &prefix,
     266  		      const CanonicalPath &canonical_prefix)
     267      : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
     268    {}
     269  
     270    bool is_type_name (const CanonicalPath &path);
     271    bool is_const_value_name (const CanonicalPath &path);
     272  
     273    /**
     274     * Resolve a disambiguated generic arg
     275     */
     276    void disambiguate (AST::GenericArg &arg);
     277  
     278    /**
     279     * Resolve a disambiguated generic arg
     280     */
     281    void resolve_disambiguated_generic (AST::GenericArg &arg);
     282  
     283    const CanonicalPath &prefix;
     284    const CanonicalPath &canonical_prefix;
     285  };
     286  
     287  } // namespace Resolver
     288  } // namespace Rust
     289  
     290  #endif // RUST_AST_RESOLVE_TYPE_H