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_LOWER_IMPLITEM_H
      20  #define RUST_AST_LOWER_IMPLITEM_H
      21  
      22  #include "rust-diagnostics.h"
      23  #include "rust-ast-lower-type.h"
      24  #include "rust-ast-lower-stmt.h"
      25  #include "rust-ast-lower-expr.h"
      26  #include "rust-ast-lower-pattern.h"
      27  #include "rust-ast-lower-block.h"
      28  
      29  namespace Rust {
      30  namespace HIR {
      31  
      32  class ASTLowerImplItem : public ASTLoweringBase
      33  {
      34    using Rust::HIR::ASTLoweringBase::visit;
      35  
      36  public:
      37    static HIR::ImplItem *translate (AST::InherentImplItem *item,
      38  				   HirId parent_impl_id)
      39    {
      40      ASTLowerImplItem resolver;
      41      item->accept_vis (resolver);
      42  
      43      if (resolver.translated != nullptr)
      44        {
      45  	rust_assert (resolver.item_cast != nullptr);
      46  
      47  	auto id = resolver.translated->get_impl_mappings ().get_hirid ();
      48  	auto defid = resolver.translated->get_impl_mappings ().get_defid ();
      49  	auto locus = resolver.translated->get_locus ();
      50  
      51  	resolver.handle_outer_attributes (*resolver.item_cast);
      52  	resolver.mappings->insert_hir_implitem (parent_impl_id,
      53  						resolver.translated);
      54  	resolver.mappings->insert_location (id, locus);
      55  	resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
      56        }
      57  
      58      return resolver.translated;
      59    }
      60  
      61    static HIR::ImplItem *translate (AST::TraitImplItem *item,
      62  				   HirId parent_impl_id)
      63    {
      64      ASTLowerImplItem resolver;
      65      item->accept_vis (resolver);
      66  
      67      if (resolver.translated != nullptr)
      68        {
      69  	rust_assert (resolver.item_cast != nullptr);
      70  
      71  	auto id = resolver.translated->get_impl_mappings ().get_hirid ();
      72  	auto defid = resolver.translated->get_impl_mappings ().get_defid ();
      73  	auto locus = resolver.translated->get_locus ();
      74  
      75  	resolver.handle_outer_attributes (*resolver.item_cast);
      76  	resolver.mappings->insert_hir_implitem (parent_impl_id,
      77  						resolver.translated);
      78  	resolver.mappings->insert_location (id, locus);
      79  	resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
      80        }
      81  
      82      return resolver.translated;
      83    }
      84  
      85    void visit (AST::TypeAlias &alias) override
      86    {
      87      std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
      88      HIR::WhereClause where_clause (std::move (where_clause_items));
      89      HIR::Visibility vis = translate_visibility (alias.get_visibility ());
      90  
      91      std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
      92      if (alias.has_generics ())
      93        generic_params = lower_generic_params (alias.get_generic_params ());
      94  
      95      HIR::Type *existing_type
      96        = ASTLoweringType::translate (alias.get_type_aliased ().get ());
      97  
      98      auto crate_num = mappings->get_current_crate ();
      99      Analysis::NodeMapping mapping (crate_num, alias.get_node_id (),
     100  				   mappings->get_next_hir_id (crate_num),
     101  				   mappings->get_next_localdef_id (crate_num));
     102  
     103      auto type_alias = new HIR::TypeAlias (
     104        mapping, alias.get_new_type_name (), std::move (generic_params),
     105        std::move (where_clause), std::unique_ptr<HIR::Type> (existing_type),
     106        std::move (vis), alias.get_outer_attrs (), alias.get_locus ());
     107  
     108      translated = type_alias;
     109      item_cast = type_alias;
     110    }
     111  
     112    void visit (AST::ConstantItem &constant) override
     113    {
     114      HIR::Visibility vis = translate_visibility (constant.get_visibility ());
     115  
     116      HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
     117      HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
     118  
     119      auto crate_num = mappings->get_current_crate ();
     120      Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
     121  				   mappings->get_next_hir_id (crate_num),
     122  				   mappings->get_next_localdef_id (crate_num));
     123  
     124      auto translated_constant
     125        = new HIR::ConstantItem (mapping, constant.get_identifier (), vis,
     126  			       std::unique_ptr<HIR::Type> (type),
     127  			       std::unique_ptr<HIR::Expr> (expr),
     128  			       constant.get_outer_attrs (),
     129  			       constant.get_locus ());
     130      translated = translated_constant;
     131      item_cast = translated_constant;
     132    }
     133  
     134    void visit (AST::Function &function) override
     135    {
     136      // ignore for now and leave empty
     137      std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
     138      HIR::WhereClause where_clause (std::move (where_clause_items));
     139      HIR::FunctionQualifiers qualifiers
     140        = lower_qualifiers (function.get_qualifiers ());
     141      HIR::Visibility vis = translate_visibility (function.get_visibility ());
     142  
     143      // need
     144      std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
     145      if (function.has_generics ())
     146        {
     147  	generic_params = lower_generic_params (function.get_generic_params ());
     148        }
     149      Identifier function_name = function.get_function_name ();
     150      Location locus = function.get_locus ();
     151  
     152      std::unique_ptr<HIR::Type> return_type
     153        = function.has_return_type () ? std::unique_ptr<HIR::Type> (
     154  	  ASTLoweringType::translate (function.get_return_type ().get ()))
     155  				    : nullptr;
     156  
     157      std::vector<HIR::FunctionParam> function_params;
     158      for (auto ¶m : function.get_function_params ())
     159        {
     160  	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
     161  	  ASTLoweringPattern::translate (param.get_pattern ().get ()));
     162  	auto translated_type = std::unique_ptr<HIR::Type> (
     163  	  ASTLoweringType::translate (param.get_type ().get ()));
     164  
     165  	auto crate_num = mappings->get_current_crate ();
     166  	Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
     167  				       mappings->get_next_hir_id (crate_num),
     168  				       UNKNOWN_LOCAL_DEFID);
     169  
     170  	auto hir_param
     171  	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
     172  				std::move (translated_type),
     173  				param.get_locus ());
     174  	function_params.push_back (std::move (hir_param));
     175        }
     176  
     177      bool terminated = false;
     178      std::unique_ptr<HIR::BlockExpr> function_body
     179        = std::unique_ptr<HIR::BlockExpr> (
     180  	ASTLoweringBlock::translate (function.get_definition ().get (),
     181  				     &terminated));
     182  
     183      auto crate_num = mappings->get_current_crate ();
     184      Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
     185  				   mappings->get_next_hir_id (crate_num),
     186  				   mappings->get_next_localdef_id (crate_num));
     187  
     188      mappings->insert_location (function_body->get_mappings ().get_hirid (),
     189  			       function.get_locus ());
     190  
     191      auto fn
     192        = new HIR::Function (mapping, std::move (function_name),
     193  			   std::move (qualifiers), std::move (generic_params),
     194  			   std::move (function_params), std::move (return_type),
     195  			   std::move (where_clause), std::move (function_body),
     196  			   std::move (vis), function.get_outer_attrs (),
     197  			   HIR::SelfParam::error (), locus);
     198  
     199      // add the mappings for the function params at the end
     200      for (auto ¶m : fn->get_function_params ())
     201        {
     202  	mappings->insert_hir_param (¶m);
     203  	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
     204        }
     205  
     206      translated = fn;
     207      item_cast = fn;
     208    }
     209  
     210    void visit (AST::Method &method) override
     211    {
     212      // ignore for now and leave empty
     213      std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
     214      HIR::WhereClause where_clause (std::move (where_clause_items));
     215      HIR::FunctionQualifiers qualifiers
     216        = lower_qualifiers (method.get_qualifiers ());
     217      HIR::Visibility vis = translate_visibility (method.get_visibility ());
     218  
     219      // need
     220      std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
     221      if (method.has_generics ())
     222        {
     223  	generic_params = lower_generic_params (method.get_generic_params ());
     224        }
     225      Identifier method_name = method.get_method_name ();
     226      Location locus = method.get_locus ();
     227  
     228      HIR::SelfParam self_param = lower_self (method.get_self_param ());
     229  
     230      std::unique_ptr<HIR::Type> return_type
     231        = method.has_return_type () ? std::unique_ptr<HIR::Type> (
     232  	  ASTLoweringType::translate (method.get_return_type ().get ()))
     233  				  : nullptr;
     234  
     235      std::vector<HIR::FunctionParam> function_params;
     236      for (auto ¶m : method.get_function_params ())
     237        {
     238  	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
     239  	  ASTLoweringPattern::translate (param.get_pattern ().get ()));
     240  	auto translated_type = std::unique_ptr<HIR::Type> (
     241  	  ASTLoweringType::translate (param.get_type ().get ()));
     242  
     243  	auto crate_num = mappings->get_current_crate ();
     244  	Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
     245  				       mappings->get_next_hir_id (crate_num),
     246  				       UNKNOWN_LOCAL_DEFID);
     247  
     248  	auto hir_param
     249  	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
     250  				std::move (translated_type),
     251  				param.get_locus ());
     252  	function_params.push_back (std::move (hir_param));
     253        }
     254  
     255      bool terminated = false;
     256      std::unique_ptr<HIR::BlockExpr> method_body
     257        = std::unique_ptr<HIR::BlockExpr> (
     258  	ASTLoweringBlock::translate (method.get_definition ().get (),
     259  				     &terminated));
     260  
     261      auto crate_num = mappings->get_current_crate ();
     262      Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
     263  				   mappings->get_next_hir_id (crate_num),
     264  				   mappings->get_next_localdef_id (crate_num));
     265      auto mth
     266        = new HIR::Function (mapping, std::move (method_name),
     267  			   std::move (qualifiers), std::move (generic_params),
     268  			   std::move (function_params), std::move (return_type),
     269  			   std::move (where_clause), std::move (method_body),
     270  			   std::move (vis), method.get_outer_attrs (),
     271  			   std::move (self_param), locus);
     272  
     273      // insert mappings for self
     274      mappings->insert_hir_self_param (&self_param);
     275      mappings->insert_location (self_param.get_mappings ().get_hirid (),
     276  			       self_param.get_locus ());
     277  
     278      // add the mappings for the function params at the end
     279      for (auto ¶m : mth->get_function_params ())
     280        {
     281  	mappings->insert_hir_param (¶m);
     282  	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
     283        }
     284  
     285      translated = mth;
     286      item_cast = mth;
     287    }
     288  
     289  private:
     290    ASTLowerImplItem () : translated (nullptr), item_cast (nullptr) {}
     291  
     292    HIR::ImplItem *translated;
     293    HIR::Item *item_cast;
     294  };
     295  
     296  class ASTLowerTraitItem : public ASTLoweringBase
     297  {
     298    using Rust::HIR::ASTLoweringBase::visit;
     299  
     300  public:
     301    static HIR::TraitItem *translate (AST::TraitItem *item)
     302    {
     303      ASTLowerTraitItem resolver;
     304      item->accept_vis (resolver);
     305  
     306      if (resolver.translated != nullptr)
     307        {
     308  	auto id = resolver.translated->get_mappings ().get_hirid ();
     309  	auto defid = resolver.translated->get_mappings ().get_defid ();
     310  	auto locus = resolver.translated->get_trait_locus ();
     311  
     312  	resolver.handle_outer_attributes (*resolver.translated);
     313  	resolver.mappings->insert_hir_trait_item (resolver.translated);
     314  	resolver.mappings->insert_location (id, locus);
     315  	resolver.mappings->insert_defid_mapping (defid, resolver.translated);
     316        }
     317  
     318      return resolver.translated;
     319    }
     320  
     321    void visit (AST::TraitItemFunc &func) override
     322    {
     323      AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();
     324  
     325      std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
     326      HIR::WhereClause where_clause (std::move (where_clause_items));
     327      HIR::FunctionQualifiers qualifiers
     328        = lower_qualifiers (func.get_trait_function_decl ().get_qualifiers ());
     329  
     330      std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
     331      if (ref.has_generics ())
     332        {
     333  	generic_params = lower_generic_params (ref.get_generic_params ());
     334        }
     335  
     336      std::unique_ptr<HIR::Type> return_type
     337        = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
     338  	  ASTLoweringType::translate (ref.get_return_type ().get ()))
     339  			       : nullptr;
     340  
     341      std::vector<HIR::FunctionParam> function_params;
     342      for (auto ¶m : ref.get_function_params ())
     343        {
     344  	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
     345  	  ASTLoweringPattern::translate (param.get_pattern ().get ()));
     346  	auto translated_type = std::unique_ptr<HIR::Type> (
     347  	  ASTLoweringType::translate (param.get_type ().get ()));
     348  
     349  	auto crate_num = mappings->get_current_crate ();
     350  	Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
     351  				       mappings->get_next_hir_id (crate_num),
     352  				       UNKNOWN_LOCAL_DEFID);
     353  
     354  	auto hir_param
     355  	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
     356  				std::move (translated_type),
     357  				param.get_locus ());
     358  	function_params.push_back (std::move (hir_param));
     359        }
     360  
     361      HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
     362  				 std::move (generic_params),
     363  				 HIR::SelfParam::error (),
     364  				 std::move (function_params),
     365  				 std::move (return_type),
     366  				 std::move (where_clause));
     367      bool terminated = false;
     368      std::unique_ptr<HIR::BlockExpr> block_expr
     369        = func.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
     370  	  ASTLoweringBlock::translate (func.get_definition ().get (),
     371  				       &terminated))
     372  			       : nullptr;
     373  
     374      auto crate_num = mappings->get_current_crate ();
     375      Analysis::NodeMapping mapping (crate_num, func.get_node_id (),
     376  				   mappings->get_next_hir_id (crate_num),
     377  				   mappings->get_next_localdef_id (crate_num));
     378  
     379      HIR::TraitItemFunc *trait_item
     380        = new HIR::TraitItemFunc (mapping, std::move (decl),
     381  				std::move (block_expr), func.get_outer_attrs (),
     382  				func.get_locus ());
     383      translated = trait_item;
     384  
     385      // add the mappings for the function params at the end
     386      for (auto ¶m : trait_item->get_decl ().get_function_params ())
     387        {
     388  	mappings->insert_hir_param (¶m);
     389  	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
     390        }
     391    }
     392  
     393    void visit (AST::TraitItemMethod &method) override
     394    {
     395      AST::TraitMethodDecl &ref = method.get_trait_method_decl ();
     396  
     397      std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
     398      HIR::WhereClause where_clause (std::move (where_clause_items));
     399      HIR::FunctionQualifiers qualifiers
     400        = lower_qualifiers (method.get_trait_method_decl ().get_qualifiers ());
     401  
     402      std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
     403      if (ref.has_generics ())
     404        {
     405  	generic_params = lower_generic_params (ref.get_generic_params ());
     406        }
     407  
     408      std::unique_ptr<HIR::Type> return_type
     409        = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
     410  	  ASTLoweringType::translate (ref.get_return_type ().get ()))
     411  			       : nullptr;
     412  
     413      HIR::SelfParam self_param = lower_self (ref.get_self_param ());
     414  
     415      std::vector<HIR::FunctionParam> function_params;
     416      for (auto ¶m : ref.get_function_params ())
     417        {
     418  	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
     419  	  ASTLoweringPattern::translate (param.get_pattern ().get ()));
     420  	auto translated_type = std::unique_ptr<HIR::Type> (
     421  	  ASTLoweringType::translate (param.get_type ().get ()));
     422  
     423  	auto crate_num = mappings->get_current_crate ();
     424  	Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
     425  				       mappings->get_next_hir_id (crate_num),
     426  				       UNKNOWN_LOCAL_DEFID);
     427  
     428  	auto hir_param
     429  	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
     430  				std::move (translated_type),
     431  				param.get_locus ());
     432  	function_params.push_back (hir_param);
     433        }
     434  
     435      HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
     436  				 std::move (generic_params),
     437  				 std::move (self_param),
     438  				 std::move (function_params),
     439  				 std::move (return_type),
     440  				 std::move (where_clause));
     441      bool terminated = false;
     442      std::unique_ptr<HIR::BlockExpr> block_expr
     443        = method.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
     444  	  ASTLoweringBlock::translate (method.get_definition ().get (),
     445  				       &terminated))
     446  				 : nullptr;
     447  
     448      auto crate_num = mappings->get_current_crate ();
     449      Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
     450  				   mappings->get_next_hir_id (crate_num),
     451  				   mappings->get_next_localdef_id (crate_num));
     452  
     453      HIR::TraitItemFunc *trait_item
     454        = new HIR::TraitItemFunc (mapping, std::move (decl),
     455  				std::move (block_expr),
     456  				method.get_outer_attrs (), method.get_locus ());
     457      translated = trait_item;
     458  
     459      // insert mappings for self
     460      mappings->insert_hir_self_param (&self_param);
     461      mappings->insert_location (self_param.get_mappings ().get_hirid (),
     462  			       self_param.get_locus ());
     463  
     464      // add the mappings for the function params at the end
     465      for (auto ¶m : trait_item->get_decl ().get_function_params ())
     466        {
     467  	mappings->insert_hir_param (¶m);
     468  	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
     469        }
     470    }
     471  
     472    void visit (AST::TraitItemConst &constant) override
     473    {
     474      HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
     475      HIR::Expr *expr
     476        = constant.has_expression ()
     477  	  ? ASTLoweringExpr::translate (constant.get_expr ().get ())
     478  	  : nullptr;
     479  
     480      auto crate_num = mappings->get_current_crate ();
     481      Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
     482  				   mappings->get_next_hir_id (crate_num),
     483  				   mappings->get_next_localdef_id (crate_num));
     484  
     485      HIR::TraitItemConst *trait_item
     486        = new HIR::TraitItemConst (mapping, constant.get_identifier (),
     487  				 std::unique_ptr<HIR::Type> (type),
     488  				 std::unique_ptr<HIR::Expr> (expr),
     489  				 constant.get_outer_attrs (),
     490  				 constant.get_locus ());
     491      translated = trait_item;
     492    }
     493  
     494    void visit (AST::TraitItemType &type) override
     495    {
     496      std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
     497  
     498      auto crate_num = mappings->get_current_crate ();
     499      Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
     500  				   mappings->get_next_hir_id (crate_num),
     501  				   mappings->get_next_localdef_id (crate_num));
     502  
     503      HIR::TraitItemType *trait_item
     504        = new HIR::TraitItemType (mapping, type.get_identifier (),
     505  				std::move (type_param_bounds),
     506  				type.get_outer_attrs (), type.get_locus ());
     507      translated = trait_item;
     508    }
     509  
     510  private:
     511    ASTLowerTraitItem () : translated (nullptr) {}
     512  
     513    HIR::TraitItem *translated;
     514  };
     515  
     516  } // namespace HIR
     517  } // namespace Rust
     518  
     519  #endif // RUST_AST_LOWER_IMPLITEM_H