LCOV - code coverage report
Current view: top level - gcc/rust/hir - rust-ast-lower-expr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 721 664
Test Date: 2026-10-17 16:30:31 Functions: 92.1 % 63 58
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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              : #include "rust-ast-lower-expr.h"
      20              : #include "optional.h"
      21              : #include "rust-ast-lower-base.h"
      22              : #include "rust-ast-lower-block.h"
      23              : #include "rust-ast-lower-struct-field-expr.h"
      24              : #include "rust-ast-lower-pattern.h"
      25              : #include "rust-ast-lower-type.h"
      26              : #include "rust-ast.h"
      27              : #include "rust-builtin-ast-nodes.h"
      28              : #include "rust-diagnostics.h"
      29              : #include "rust-hir-map.h"
      30              : #include "rust-system.h"
      31              : #include "tree/rust-hir-expr.h"
      32              : 
      33              : namespace Rust {
      34              : namespace HIR {
      35              : 
      36       679404 : ASTLoweringExpr::ASTLoweringExpr ()
      37       679404 :   : ASTLoweringBase (), translated (nullptr), translated_array_elems (nullptr),
      38       679404 :     terminated (false)
      39       679404 : {}
      40              : 
      41              : HIR::Expr *
      42       679404 : ASTLoweringExpr::translate (AST::Expr &expr, bool *terminated)
      43              : {
      44       679404 :   ASTLoweringExpr resolver;
      45       679404 :   expr.accept_vis (resolver);
      46       679404 :   if (resolver.translated == nullptr)
      47              :     {
      48            0 :       rust_fatal_error (expr.get_locus (), "Failed to lower expr: [%s]",
      49            0 :                         expr.as_string ().c_str ());
      50              :       return nullptr;
      51              :     }
      52              : 
      53       679404 :   resolver.mappings.hir.exprs.insert (resolver.translated);
      54       679404 :   resolver.mappings.insert_location (
      55       679404 :     resolver.translated->get_mappings ().get_hirid (), expr.get_locus ());
      56              : 
      57       679404 :   if (terminated != nullptr)
      58        55046 :     *terminated = resolver.terminated;
      59              : 
      60       679404 :   return resolver.translated;
      61       679404 : }
      62              : 
      63              : void
      64         4608 : ASTLoweringExpr::visit (AST::TupleIndexExpr &expr)
      65              : {
      66         4608 :   HIR::Expr *tuple_expr
      67         4608 :     = ASTLoweringExpr::translate (expr.get_tuple_expr (), &terminated);
      68              : 
      69         4608 :   auto crate_num = mappings.crate.get_current_crate ();
      70         9216 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
      71         4608 :                                  mappings.get_next_hir_id (crate_num),
      72         4608 :                                  UNKNOWN_LOCAL_DEFID);
      73              : 
      74         4608 :   translated
      75         4608 :     = new HIR::TupleIndexExpr (mapping, std::unique_ptr<HIR::Expr> (tuple_expr),
      76         4608 :                                expr.get_tuple_index (), expr.get_outer_attrs (),
      77         9216 :                                expr.get_locus ());
      78         4608 : }
      79              : 
      80              : void
      81         4583 : ASTLoweringExpr::visit (AST::TupleExpr &expr)
      82              : {
      83         4583 :   std::vector<std::unique_ptr<HIR::Expr>> tuple_elements;
      84         4583 :   tuple_elements.reserve (expr.get_tuple_elems ().size ());
      85              : 
      86        13043 :   for (auto &e : expr.get_tuple_elems ())
      87         8460 :     tuple_elements.emplace_back (ASTLoweringExpr::translate (*e));
      88              : 
      89         4583 :   auto crate_num = mappings.crate.get_current_crate ();
      90         9166 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
      91         4583 :                                  mappings.get_next_hir_id (crate_num),
      92         4583 :                                  UNKNOWN_LOCAL_DEFID);
      93              : 
      94         4583 :   translated
      95         4583 :     = new HIR::TupleExpr (std::move (mapping), std::move (tuple_elements),
      96         9166 :                           expr.get_inner_attrs (), expr.get_outer_attrs (),
      97         4583 :                           expr.get_locus ());
      98         4583 : }
      99              : 
     100              : void
     101         1901 : ASTLoweringExpr::visit (AST::IfExpr &expr)
     102              : {
     103         1901 :   translated = ASTLoweringIfBlock::translate (expr, &terminated);
     104         1901 : }
     105              : 
     106              : void
     107         2023 : ASTLoweringExpr::visit (AST::IfExprConseqElse &expr)
     108              : {
     109         2023 :   translated = ASTLoweringIfBlock::translate (expr, &terminated);
     110         2023 : }
     111              : 
     112              : void
     113           78 : ASTLoweringExpr::visit (AST::IfLetExpr &expr)
     114              : {
     115           78 :   translated = ASTLoweringIfLetBlock::translate (expr);
     116           78 : }
     117              : 
     118              : void
     119           41 : ASTLoweringExpr::visit (AST::IfLetExprConseqElse &expr)
     120              : {
     121           41 :   translated = ASTLoweringIfLetBlock::translate (expr);
     122           41 : }
     123              : 
     124              : void
     125         3161 : ASTLoweringExpr::visit (AST::BlockExpr &expr)
     126              : {
     127         3161 :   translated = ASTLoweringBlock::translate (expr, &terminated);
     128         3161 : }
     129              : 
     130              : void
     131         1132 : ASTLoweringExpr::visit (AST::AnonConst &expr)
     132              : {
     133         1132 :   auto &mappings = Analysis::Mappings::get ();
     134         1132 :   auto crate_num = mappings.crate.get_current_crate ();
     135         2264 :   auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
     136              :                                         mappings.get_next_hir_id (crate_num),
     137         1132 :                                         UNKNOWN_LOCAL_DEFID);
     138              : 
     139         1132 :   if (expr.is_deferred ())
     140              :     {
     141           13 :       translated = new HIR::AnonConst (std::move (mapping), expr.get_locus ());
     142              :     }
     143              :   else
     144              :     {
     145         1119 :       auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
     146              : 
     147         2238 :       translated = new HIR::AnonConst (std::move (mapping),
     148         1119 :                                        std::unique_ptr<Expr> (inner_expr),
     149         1119 :                                        expr.get_locus ());
     150              :     }
     151         1132 : }
     152              : 
     153              : void
     154           15 : ASTLoweringExpr::visit (AST::ConstBlock &expr)
     155              : {
     156           15 :   auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ());
     157              : 
     158              :   // we know this will always be an `AnonConst`, or we have an issue. Let's
     159              :   // assert just to be sure.
     160           15 :   rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
     161           15 :   auto anon_const = static_cast<AnonConst *> (inner_expr);
     162              : 
     163           15 :   auto &mappings = Analysis::Mappings::get ();
     164           15 :   auto crate_num = mappings.crate.get_current_crate ();
     165           30 :   auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
     166              :                                         mappings.get_next_hir_id (crate_num),
     167           15 :                                         UNKNOWN_LOCAL_DEFID);
     168              : 
     169           15 :   translated
     170           15 :     = new HIR::ConstBlock (std::move (mapping), std::move (*anon_const),
     171           15 :                            expr.get_locus (), expr.get_outer_attrs ());
     172           15 : }
     173              : 
     174              : void
     175         5029 : ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr)
     176              : {
     177         5029 :   translated = ASTLoweringBlock::translate (expr, &terminated);
     178         5029 : }
     179              : 
     180              : void
     181        97288 : ASTLoweringExpr::visit (AST::PathInExpression &expr)
     182              : {
     183        97288 :   translated = ASTLowerPathInExpression::translate (expr);
     184        97288 : }
     185              : 
     186              : void
     187          224 : ASTLoweringExpr::visit (AST::QualifiedPathInExpression &expr)
     188              : {
     189          224 :   translated = ASTLowerQualPathInExpression::translate (expr);
     190          224 : }
     191              : 
     192              : void
     193            6 : ASTLoweringExpr::visit (AST::BoxExpr &expr)
     194              : {
     195            6 :   HIR::Expr *box_expr = ASTLoweringExpr::translate (expr.get_boxed_expr ());
     196              : 
     197            6 :   auto crate_num = mappings.crate.get_current_crate ();
     198           12 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     199            6 :                                  mappings.get_next_hir_id (crate_num),
     200            6 :                                  UNKNOWN_LOCAL_DEFID);
     201              : 
     202           12 :   translated = new HIR::BoxExpr (mapping, expr.get_locus (),
     203            6 :                                  std::unique_ptr<HIR::Expr> (box_expr));
     204            6 : }
     205              : 
     206              : void
     207         1128 : ASTLoweringExpr::visit (AST::ReturnExpr &expr)
     208              : {
     209         1128 :   terminated = true;
     210         1128 :   HIR::Expr *return_expr
     211         1128 :     = expr.has_returned_expr ()
     212         1128 :         ? ASTLoweringExpr::translate (expr.get_returned_expr ())
     213              :         : nullptr;
     214              : 
     215         1128 :   auto crate_num = mappings.crate.get_current_crate ();
     216         2256 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     217         1128 :                                  mappings.get_next_hir_id (crate_num),
     218         1128 :                                  UNKNOWN_LOCAL_DEFID);
     219              : 
     220         2256 :   translated = new HIR::ReturnExpr (mapping, expr.get_locus (),
     221         1128 :                                     std::unique_ptr<HIR::Expr> (return_expr));
     222         1128 : }
     223              : 
     224              : void
     225        75346 : ASTLoweringExpr::visit (AST::CallExpr &expr)
     226              : {
     227        75346 :   HIR::Expr *func = ASTLoweringExpr::translate (expr.get_function_expr ());
     228              : 
     229        75346 :   auto const &in_params = expr.get_params ();
     230              : 
     231        75346 :   std::vector<std::unique_ptr<HIR::Expr>> params;
     232        75346 :   params.reserve (in_params.size ());
     233              : 
     234       252836 :   for (auto &param : in_params)
     235       177490 :     params.emplace_back (ASTLoweringExpr::translate (*param));
     236              : 
     237        75346 :   auto crate_num = mappings.crate.get_current_crate ();
     238        75346 :   Analysis::NodeMapping mapping (
     239              :     crate_num, UNKNOWN_NODEID /* this can map back to the AST*/,
     240        75346 :     mappings.get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
     241              : 
     242        75346 :   translated = new HIR::CallExpr (mapping, std::unique_ptr<HIR::Expr> (func),
     243        75346 :                                   std::move (params), expr.get_outer_attrs (),
     244       150692 :                                   expr.get_locus ());
     245        75346 : }
     246              : 
     247              : void
     248        29483 : ASTLoweringExpr::visit (AST::MethodCallExpr &expr)
     249              : {
     250        29483 :   HIR::PathExprSegment method_path
     251        29483 :     = lower_path_expr_seg (expr.get_method_name ());
     252              : 
     253        29483 :   HIR::Expr *receiver = ASTLoweringExpr::translate (expr.get_receiver_expr ());
     254              : 
     255        29483 :   auto const &in_params = expr.get_params ();
     256        29483 :   std::vector<std::unique_ptr<HIR::Expr>> params;
     257        29483 :   params.reserve (in_params.size ());
     258              : 
     259        35637 :   for (auto &param : in_params)
     260         6154 :     params.emplace_back (ASTLoweringExpr::translate (*param));
     261              : 
     262        29483 :   auto crate_num = mappings.crate.get_current_crate ();
     263        58966 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     264        29483 :                                  mappings.get_next_hir_id (crate_num),
     265        29483 :                                  UNKNOWN_LOCAL_DEFID);
     266              : 
     267        29483 :   translated
     268        29483 :     = new HIR::MethodCallExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
     269              :                                method_path, std::move (params),
     270        58966 :                                expr.get_outer_attrs (), expr.get_locus ());
     271        29483 : }
     272              : 
     273              : void
     274         3670 : ASTLoweringExpr::visit (AST::AssignmentExpr &expr)
     275              : {
     276         3670 :   HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
     277         3670 :   HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
     278              : 
     279         3670 :   auto crate_num = mappings.crate.get_current_crate ();
     280         7340 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     281         3670 :                                  mappings.get_next_hir_id (crate_num),
     282         3670 :                                  UNKNOWN_LOCAL_DEFID);
     283              : 
     284         3670 :   translated
     285         3670 :     = new HIR::AssignmentExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
     286         7340 :                                std::unique_ptr<HIR::Expr> (rhs),
     287         3670 :                                expr.get_locus ());
     288         3670 : }
     289              : 
     290              : void
     291       148422 : ASTLoweringExpr::visit (AST::IdentifierExpr &expr)
     292              : {
     293       148422 :   auto crate_num = mappings.crate.get_current_crate ();
     294       296844 :   Analysis::NodeMapping mapping1 (crate_num, expr.get_node_id (),
     295       148422 :                                   mappings.get_next_hir_id (crate_num),
     296       148422 :                                   UNKNOWN_LOCAL_DEFID);
     297       148422 :   Analysis::NodeMapping mapping2 (mapping1);
     298              : 
     299       296844 :   HIR::PathIdentSegment ident_seg (expr.get_ident ().as_string ());
     300       148422 :   HIR::PathExprSegment seg (mapping1, ident_seg, expr.get_locus (),
     301       296844 :                             HIR::GenericArgs::create_empty ());
     302       296844 :   translated = new HIR::PathInExpression (mapping2, {seg}, expr.get_locus (),
     303       296844 :                                           false, expr.get_outer_attrs ());
     304       148422 : }
     305              : 
     306              : void
     307        13225 : ASTLoweringExpr::visit (AST::ArrayExpr &expr)
     308              : {
     309        13225 :   expr.get_array_elems ()->accept_vis (*this);
     310        13225 :   rust_assert (translated_array_elems != nullptr);
     311        13225 :   HIR::ArrayElems *elems = translated_array_elems;
     312              : 
     313        13225 :   auto crate_num = mappings.crate.get_current_crate ();
     314        26450 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     315        13225 :                                  mappings.get_next_hir_id (crate_num),
     316        13225 :                                  UNKNOWN_LOCAL_DEFID);
     317              : 
     318        13225 :   translated
     319        13225 :     = new HIR::ArrayExpr (mapping, std::unique_ptr<HIR::ArrayElems> (elems),
     320        26450 :                           expr.get_inner_attrs (), expr.get_outer_attrs (),
     321        26450 :                           expr.get_locus ());
     322        13225 : }
     323              : 
     324              : void
     325          739 : ASTLoweringExpr::visit (AST::ArrayIndexExpr &expr)
     326              : {
     327          739 :   HIR::Expr *array_expr = ASTLoweringExpr::translate (expr.get_array_expr ());
     328          739 :   HIR::Expr *array_index_expr
     329          739 :     = ASTLoweringExpr::translate (expr.get_index_expr ());
     330              : 
     331          739 :   auto crate_num = mappings.crate.get_current_crate ();
     332         1478 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     333          739 :                                  mappings.get_next_hir_id (crate_num),
     334          739 :                                  UNKNOWN_LOCAL_DEFID);
     335              : 
     336          739 :   translated
     337          739 :     = new HIR::ArrayIndexExpr (mapping, std::unique_ptr<HIR::Expr> (array_expr),
     338         1478 :                                std::unique_ptr<HIR::Expr> (array_index_expr),
     339         1478 :                                expr.get_outer_attrs (), expr.get_locus ());
     340          739 : }
     341              : 
     342              : void
     343        13053 : ASTLoweringExpr::visit (AST::ArrayElemsValues &elems)
     344              : {
     345        13053 :   std::vector<std::unique_ptr<HIR::Expr>> elements;
     346        13053 :   elements.reserve (elems.get_values ().size ());
     347              : 
     348       136849 :   for (auto &elem : elems.get_values ())
     349       123796 :     elements.emplace_back (ASTLoweringExpr::translate (*elem));
     350              : 
     351        13053 :   auto crate_num = mappings.crate.get_current_crate ();
     352        13053 :   Analysis::NodeMapping mapping (crate_num, elems.get_node_id (),
     353        13053 :                                  mappings.get_next_hir_id (crate_num),
     354        13053 :                                  UNKNOWN_LOCAL_DEFID);
     355              : 
     356        13053 :   translated_array_elems
     357        13053 :     = new HIR::ArrayElemsValues (mapping, std::move (elements));
     358        13053 : }
     359              : 
     360              : void
     361          172 : ASTLoweringExpr::visit (AST::ArrayElemsCopied &elems)
     362              : {
     363          172 :   HIR::Expr *element = ASTLoweringExpr::translate (elems.get_elem_to_copy ());
     364          172 :   HIR::Expr *num_copies = ASTLoweringExpr::translate (elems.get_num_copies ());
     365              : 
     366          172 :   auto crate_num = mappings.crate.get_current_crate ();
     367          172 :   Analysis::NodeMapping mapping (crate_num, elems.get_node_id (),
     368          172 :                                  mappings.get_next_hir_id (crate_num),
     369          172 :                                  UNKNOWN_LOCAL_DEFID);
     370              : 
     371          172 :   translated_array_elems
     372          172 :     = new HIR::ArrayElemsCopied (mapping, std::unique_ptr<HIR::Expr> (element),
     373          344 :                                  std::unique_ptr<HIR::Expr> (num_copies));
     374          172 : }
     375              : 
     376              : void
     377       202226 : ASTLoweringExpr::visit (AST::LiteralExpr &expr)
     378              : {
     379       202226 :   auto crate_num = mappings.crate.get_current_crate ();
     380       404452 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     381       202226 :                                  mappings.get_next_hir_id (crate_num),
     382       202226 :                                  UNKNOWN_LOCAL_DEFID);
     383              : 
     384       202226 :   HIR::Literal l = lower_literal (expr.get_literal ());
     385       202226 :   translated = new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
     386       404452 :                                      expr.get_outer_attrs ());
     387       202226 : }
     388              : 
     389              : void
     390        25039 : ASTLoweringExpr::visit (AST::ArithmeticOrLogicalExpr &expr)
     391              : {
     392        25039 :   HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
     393        25039 :   rust_assert (lhs != nullptr);
     394        25039 :   HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
     395        25039 :   rust_assert (rhs != nullptr);
     396              : 
     397        25039 :   auto crate_num = mappings.crate.get_current_crate ();
     398        50078 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     399        25039 :                                  mappings.get_next_hir_id (crate_num),
     400        25039 :                                  UNKNOWN_LOCAL_DEFID);
     401              : 
     402        50078 :   translated = new HIR::ArithmeticOrLogicalExpr (
     403        25039 :     mapping, std::unique_ptr<HIR::Expr> (lhs), std::unique_ptr<HIR::Expr> (rhs),
     404        25039 :     expr.get_expr_type (), expr.get_locus ());
     405        25039 : }
     406              : 
     407              : void
     408         6267 : ASTLoweringExpr::visit (AST::ComparisonExpr &expr)
     409              : {
     410         6267 :   HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
     411         6267 :   rust_assert (lhs != nullptr);
     412         6267 :   HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
     413         6267 :   rust_assert (rhs != nullptr);
     414              : 
     415         6267 :   auto crate_num = mappings.crate.get_current_crate ();
     416        12534 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     417         6267 :                                  mappings.get_next_hir_id (crate_num),
     418         6267 :                                  UNKNOWN_LOCAL_DEFID);
     419              : 
     420         6267 :   translated
     421         6267 :     = new HIR::ComparisonExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
     422        12534 :                                std::unique_ptr<HIR::Expr> (rhs),
     423         6267 :                                expr.get_expr_type (), expr.get_locus ());
     424         6267 : }
     425              : 
     426              : void
     427         1142 : ASTLoweringExpr::visit (AST::LazyBooleanExpr &expr)
     428              : {
     429         1142 :   HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ());
     430         1142 :   rust_assert (lhs != nullptr);
     431         1142 :   HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ());
     432         1142 :   rust_assert (rhs != nullptr);
     433              : 
     434         1142 :   auto crate_num = mappings.crate.get_current_crate ();
     435         2284 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     436         1142 :                                  mappings.get_next_hir_id (crate_num),
     437         1142 :                                  UNKNOWN_LOCAL_DEFID);
     438              : 
     439         1142 :   translated
     440         1142 :     = new HIR::LazyBooleanExpr (mapping, std::unique_ptr<HIR::Expr> (lhs),
     441         2284 :                                 std::unique_ptr<HIR::Expr> (rhs),
     442         1142 :                                 expr.get_expr_type (), expr.get_locus ());
     443         1142 : }
     444              : 
     445              : void
     446         1556 : ASTLoweringExpr::visit (AST::NegationExpr &expr)
     447              : {
     448         1556 :   HIR::Expr *negated_value
     449         1556 :     = ASTLoweringExpr::translate (expr.get_negated_expr ());
     450              : 
     451         1556 :   auto crate_num = mappings.crate.get_current_crate ();
     452         3112 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     453         1556 :                                  mappings.get_next_hir_id (crate_num),
     454         1556 :                                  UNKNOWN_LOCAL_DEFID);
     455         1556 :   translated
     456         1556 :     = new HIR::NegationExpr (mapping,
     457         1556 :                              std::unique_ptr<HIR::Expr> (negated_value),
     458         1556 :                              expr.get_expr_type (), expr.get_outer_attrs (),
     459         3112 :                              expr.get_locus ());
     460         1556 : }
     461              : 
     462              : void
     463         9147 : ASTLoweringExpr::visit (AST::TypeCastExpr &expr)
     464              : {
     465         9147 :   HIR::Expr *expr_to_cast_to
     466         9147 :     = ASTLoweringExpr::translate (expr.get_casted_expr ());
     467         9147 :   HIR::Type *type_to_cast_to
     468         9147 :     = lower_type_no_bounds (expr.get_type_to_cast_to ());
     469              : 
     470         9147 :   auto crate_num = mappings.crate.get_current_crate ();
     471        18294 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     472         9147 :                                  mappings.get_next_hir_id (crate_num),
     473         9147 :                                  UNKNOWN_LOCAL_DEFID);
     474              : 
     475         9147 :   translated
     476         9147 :     = new HIR::TypeCastExpr (mapping,
     477         9147 :                              std::unique_ptr<HIR::Expr> (expr_to_cast_to),
     478        18294 :                              std::unique_ptr<HIR::Type> (type_to_cast_to),
     479         9147 :                              expr.get_locus ());
     480         9147 : }
     481              : 
     482              : void
     483         1527 : ASTLoweringExpr::visit (AST::CompoundAssignmentExpr &expr)
     484              : {
     485         1527 :   ArithmeticOrLogicalOperator op;
     486         1527 :   switch (expr.get_expr_type ())
     487              :     {
     488              :     case CompoundAssignmentOperator::ADD:
     489              :       op = ArithmeticOrLogicalOperator::ADD;
     490              :       break;
     491              :     case CompoundAssignmentOperator::SUBTRACT:
     492              :       op = ArithmeticOrLogicalOperator::SUBTRACT;
     493              :       break;
     494              :     case CompoundAssignmentOperator::MULTIPLY:
     495              :       op = ArithmeticOrLogicalOperator::MULTIPLY;
     496              :       break;
     497              :     case CompoundAssignmentOperator::DIVIDE:
     498              :       op = ArithmeticOrLogicalOperator::DIVIDE;
     499              :       break;
     500              :     case CompoundAssignmentOperator::MODULUS:
     501              :       op = ArithmeticOrLogicalOperator::MODULUS;
     502              :       break;
     503              :     case CompoundAssignmentOperator::BITWISE_AND:
     504              :       op = ArithmeticOrLogicalOperator::BITWISE_AND;
     505              :       break;
     506              :     case CompoundAssignmentOperator::BITWISE_OR:
     507              :       op = ArithmeticOrLogicalOperator::BITWISE_OR;
     508              :       break;
     509              :     case CompoundAssignmentOperator::BITWISE_XOR:
     510              :       op = ArithmeticOrLogicalOperator::BITWISE_XOR;
     511              :       break;
     512              :     case CompoundAssignmentOperator::LEFT_SHIFT:
     513              :       op = ArithmeticOrLogicalOperator::LEFT_SHIFT;
     514              :       break;
     515              :     case CompoundAssignmentOperator::RIGHT_SHIFT:
     516              :       op = ArithmeticOrLogicalOperator::RIGHT_SHIFT;
     517              :       break;
     518            0 :     default:
     519            0 :       rust_unreachable ();
     520              :     }
     521              : 
     522         1527 :   HIR::Expr *asignee_expr = ASTLoweringExpr::translate (expr.get_left_expr ());
     523         1527 :   HIR::Expr *value = ASTLoweringExpr::translate (expr.get_right_expr ());
     524              : 
     525         1527 :   auto crate_num = mappings.crate.get_current_crate ();
     526         3054 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     527         1527 :                                  mappings.get_next_hir_id (crate_num),
     528         1527 :                                  UNKNOWN_LOCAL_DEFID);
     529              : 
     530         3054 :   translated = new HIR::CompoundAssignmentExpr (
     531         1527 :     mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
     532         3054 :     std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
     533         1527 : }
     534              : 
     535              : void
     536          105 : ASTLoweringExpr::visit (AST::StructExprStruct &struct_expr)
     537              : {
     538          105 :   HIR::PathInExpression *path
     539          105 :     = ASTLowerPathInExpression::translate (struct_expr.get_struct_name ());
     540          105 :   HIR::PathInExpression copied_path (*path);
     541          105 :   delete path;
     542              : 
     543          105 :   auto crate_num = mappings.crate.get_current_crate ();
     544          210 :   Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
     545          105 :                                  mappings.get_next_hir_id (crate_num),
     546          105 :                                  UNKNOWN_LOCAL_DEFID);
     547              : 
     548          210 :   translated = new HIR::StructExprStruct (mapping, copied_path,
     549          105 :                                           struct_expr.get_inner_attrs (),
     550          105 :                                           struct_expr.get_outer_attrs (),
     551          105 :                                           struct_expr.get_locus ());
     552          105 : }
     553              : 
     554              : void
     555         1840 : ASTLoweringExpr::visit (AST::StructExprStructFields &struct_expr)
     556              : {
     557              :   // bit of a hack for now
     558         1840 :   HIR::PathInExpression *path
     559         1840 :     = ASTLowerPathInExpression::translate (struct_expr.get_struct_name ());
     560         1840 :   HIR::PathInExpression copied_path (*path);
     561         1840 :   delete path;
     562              : 
     563         1840 :   tl::optional<std::unique_ptr<HIR::StructBase>> base = tl::nullopt;
     564         1840 :   if (struct_expr.has_struct_base ())
     565              :     {
     566           66 :       HIR::Expr *translated_base = ASTLoweringExpr::translate (
     567           66 :         struct_expr.get_struct_base ().get_base_struct ());
     568           66 :       base = tl::optional<std::unique_ptr<HIR::StructBase>> (
     569          132 :         std::make_unique<StructBase> (
     570          132 :           std::unique_ptr<HIR::Expr> (translated_base)));
     571              :     }
     572              : 
     573         1840 :   auto const &in_fields = struct_expr.get_fields ();
     574              : 
     575         1840 :   std::vector<std::unique_ptr<HIR::StructExprField>> fields;
     576         1840 :   fields.reserve (in_fields.size ());
     577              : 
     578         5058 :   for (auto &field : in_fields)
     579         3218 :     fields.emplace_back (ASTLowerStructExprField::translate (*field));
     580              : 
     581         1840 :   auto crate_num = mappings.crate.get_current_crate ();
     582         3680 :   Analysis::NodeMapping mapping (crate_num, struct_expr.get_node_id (),
     583         1840 :                                  mappings.get_next_hir_id (crate_num),
     584         1840 :                                  UNKNOWN_LOCAL_DEFID);
     585              : 
     586         1840 :   translated
     587         1840 :     = new HIR::StructExprStructFields (mapping, copied_path, std::move (fields),
     588              :                                        struct_expr.get_locus (),
     589              :                                        std::move (base),
     590         1840 :                                        struct_expr.get_inner_attrs (),
     591         3746 :                                        struct_expr.get_outer_attrs ());
     592         1906 : }
     593              : 
     594              : void
     595         7573 : ASTLoweringExpr::visit (AST::GroupedExpr &expr)
     596              : {
     597         7573 :   HIR::Expr *paren_expr
     598         7573 :     = ASTLoweringExpr::translate (expr.get_expr_in_parens ());
     599              : 
     600         7573 :   auto crate_num = mappings.crate.get_current_crate ();
     601        15146 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     602         7573 :                                  mappings.get_next_hir_id (crate_num),
     603         7573 :                                  UNKNOWN_LOCAL_DEFID);
     604              : 
     605         7573 :   translated
     606         7573 :     = new HIR::GroupedExpr (mapping, std::unique_ptr<HIR::Expr> (paren_expr),
     607        15146 :                             expr.get_inner_attrs (), expr.get_outer_attrs (),
     608        15146 :                             expr.get_locus ());
     609         7573 : }
     610              : 
     611              : void
     612         8187 : ASTLoweringExpr::visit (AST::FieldAccessExpr &expr)
     613              : {
     614         8187 :   HIR::Expr *receiver = ASTLoweringExpr::translate (expr.get_receiver_expr ());
     615              : 
     616         8187 :   auto crate_num = mappings.crate.get_current_crate ();
     617        16374 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     618         8187 :                                  mappings.get_next_hir_id (crate_num),
     619         8187 :                                  UNKNOWN_LOCAL_DEFID);
     620         8187 :   translated
     621         8187 :     = new HIR::FieldAccessExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
     622        16374 :                                 expr.get_field_name (), expr.get_outer_attrs (),
     623        16374 :                                 expr.get_locus ());
     624         8187 : }
     625              : 
     626              : void
     627          314 : ASTLoweringExpr::visit (AST::LoopExpr &expr)
     628              : {
     629          314 :   translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
     630          314 : }
     631              : 
     632              : void
     633          196 : ASTLoweringExpr::visit (AST::WhileLoopExpr &expr)
     634              : {
     635          196 :   translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
     636          196 : }
     637              : 
     638              : void
     639          273 : ASTLoweringExpr::visit (AST::BreakExpr &expr)
     640              : {
     641          273 :   tl::optional<HIR::Lifetime> break_label = tl::nullopt;
     642          273 :   if (expr.has_label ())
     643           33 :     break_label = lower_lifetime (expr.get_label_unchecked ().get_lifetime ());
     644              : 
     645          273 :   HIR::Expr *break_expr
     646          273 :     = expr.has_break_expr ()
     647          273 :         ? ASTLoweringExpr::translate (expr.get_break_expr_unchecked ())
     648              :         : nullptr;
     649              : 
     650          273 :   auto crate_num = mappings.crate.get_current_crate ();
     651          546 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     652          273 :                                  mappings.get_next_hir_id (crate_num),
     653          273 :                                  UNKNOWN_LOCAL_DEFID);
     654              : 
     655          273 :   translated
     656          273 :     = new HIR::BreakExpr (mapping, expr.get_locus (), std ::move (break_label),
     657          273 :                           std::unique_ptr<HIR::Expr> (break_expr),
     658          546 :                           expr.get_outer_attrs ());
     659          273 : }
     660              : 
     661              : void
     662           42 : ASTLoweringExpr::visit (AST::ContinueExpr &expr)
     663              : {
     664           42 :   tl::optional<HIR::Lifetime> break_label;
     665           42 :   if (expr.has_label ())
     666           12 :     break_label = lower_lifetime (expr.get_label_unchecked ());
     667              : 
     668           42 :   auto crate_num = mappings.crate.get_current_crate ();
     669           84 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     670           42 :                                  mappings.get_next_hir_id (crate_num),
     671           42 :                                  UNKNOWN_LOCAL_DEFID);
     672              : 
     673           42 :   translated
     674           42 :     = new HIR::ContinueExpr (mapping, expr.get_locus (),
     675           84 :                              std ::move (break_label), expr.get_outer_attrs ());
     676           42 : }
     677              : 
     678              : void
     679         5190 : ASTLoweringExpr::visit (AST::BorrowExpr &expr)
     680              : {
     681         5190 :   HIR::Expr *borrow_lvalue
     682         5190 :     = ASTLoweringExpr::translate (expr.get_borrowed_expr ());
     683              : 
     684         5190 :   auto crate_num = mappings.crate.get_current_crate ();
     685        10380 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     686         5190 :                                  mappings.get_next_hir_id (crate_num),
     687         5190 :                                  UNKNOWN_LOCAL_DEFID);
     688              : 
     689         5190 :   auto *borrow_expr
     690         5190 :     = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
     691              :                            expr.get_mutability (), expr.is_raw_borrow (),
     692         5190 :                            expr.get_outer_attrs (), expr.get_locus ());
     693              : 
     694         5190 :   if (expr.get_is_double_borrow ())
     695              :     {
     696           38 :       NodeId artificial_double_borrow_id = mappings.get_next_node_id ();
     697           38 :       Analysis::NodeMapping mapping (crate_num, artificial_double_borrow_id,
     698           38 :                                      mappings.get_next_hir_id (crate_num),
     699           38 :                                      UNKNOWN_LOCAL_DEFID);
     700              : 
     701           38 :       borrow_expr
     702           38 :         = new HIR::BorrowExpr (mapping,
     703           38 :                                std::unique_ptr<HIR::Expr> (borrow_expr),
     704              :                                expr.get_mutability (), expr.is_raw_borrow (),
     705           76 :                                expr.get_outer_attrs (), expr.get_locus ());
     706              :     }
     707              : 
     708         5190 :   translated = borrow_expr;
     709         5190 : }
     710              : 
     711              : void
     712         9587 : ASTLoweringExpr::visit (AST::DereferenceExpr &expr)
     713              : {
     714         9587 :   HIR::Expr *dref_lvalue
     715         9587 :     = ASTLoweringExpr::translate (expr.get_dereferenced_expr ());
     716              : 
     717         9587 :   auto crate_num = mappings.crate.get_current_crate ();
     718        19174 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     719         9587 :                                  mappings.get_next_hir_id (crate_num),
     720         9587 :                                  UNKNOWN_LOCAL_DEFID);
     721              : 
     722         9587 :   translated
     723         9587 :     = new HIR::DereferenceExpr (mapping,
     724         9587 :                                 std::unique_ptr<HIR::Expr> (dref_lvalue),
     725        19174 :                                 expr.get_outer_attrs (), expr.get_locus ());
     726         9587 : }
     727              : 
     728              : void
     729         6225 : ASTLoweringExpr::visit (AST::MatchExpr &expr)
     730              : {
     731         6225 :   translated = ASTLoweringExprWithBlock::translate (expr, &terminated);
     732         6225 : }
     733              : 
     734              : void
     735          195 : ASTLoweringExpr::visit (AST::RangeFromToExpr &expr)
     736              : {
     737          195 :   auto crate_num = mappings.crate.get_current_crate ();
     738          390 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     739          195 :                                  mappings.get_next_hir_id (crate_num),
     740          195 :                                  UNKNOWN_LOCAL_DEFID);
     741              : 
     742          195 :   HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
     743          195 :   HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
     744              : 
     745          195 :   translated
     746          195 :     = new HIR::RangeFromToExpr (mapping,
     747          195 :                                 std::unique_ptr<HIR::Expr> (range_from),
     748          390 :                                 std::unique_ptr<HIR::Expr> (range_to),
     749          195 :                                 expr.get_locus ());
     750          195 : }
     751              : 
     752              : void
     753           63 : ASTLoweringExpr::visit (AST::RangeFromExpr &expr)
     754              : {
     755           63 :   auto crate_num = mappings.crate.get_current_crate ();
     756          126 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     757           63 :                                  mappings.get_next_hir_id (crate_num),
     758           63 :                                  UNKNOWN_LOCAL_DEFID);
     759              : 
     760           63 :   HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
     761              : 
     762           63 :   translated
     763           63 :     = new HIR::RangeFromExpr (mapping, std::unique_ptr<HIR::Expr> (range_from),
     764           63 :                               expr.get_locus ());
     765           63 : }
     766              : 
     767              : void
     768          118 : ASTLoweringExpr::visit (AST::RangeToExpr &expr)
     769              : {
     770          118 :   auto crate_num = mappings.crate.get_current_crate ();
     771          236 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     772          118 :                                  mappings.get_next_hir_id (crate_num),
     773          118 :                                  UNKNOWN_LOCAL_DEFID);
     774              : 
     775          118 :   HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
     776              : 
     777          118 :   translated
     778          118 :     = new HIR::RangeToExpr (mapping, std::unique_ptr<HIR::Expr> (range_to),
     779          118 :                             expr.get_locus ());
     780          118 : }
     781              : 
     782              : void
     783           53 : ASTLoweringExpr::visit (AST::RangeFullExpr &expr)
     784              : {
     785           53 :   auto crate_num = mappings.crate.get_current_crate ();
     786          106 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     787           53 :                                  mappings.get_next_hir_id (crate_num),
     788           53 :                                  UNKNOWN_LOCAL_DEFID);
     789              : 
     790           53 :   translated = new HIR::RangeFullExpr (mapping, expr.get_locus ());
     791           53 : }
     792              : 
     793              : void
     794           13 : ASTLoweringExpr::visit (AST::RangeFromToInclExpr &expr)
     795              : {
     796           13 :   auto crate_num = mappings.crate.get_current_crate ();
     797           26 :   Analysis::NodeMapping path_mapping (crate_num, mappings.get_next_node_id (),
     798           13 :                                       mappings.get_next_hir_id (crate_num),
     799           13 :                                       UNKNOWN_LOCAL_DEFID);
     800           26 :   Analysis::NodeMapping call_mapping (crate_num, expr.get_node_id (),
     801           13 :                                       mappings.get_next_hir_id (crate_num),
     802           13 :                                       UNKNOWN_LOCAL_DEFID);
     803              : 
     804           13 :   HIR::Expr *func
     805              :     = new HIR::PathInExpression (path_mapping,
     806              :                                  LangItem::Kind::RANGE_INCLUSIVE_NEW,
     807           13 :                                  expr.get_locus (), false);
     808              : 
     809           13 :   HIR::Expr *range_from = ASTLoweringExpr::translate (expr.get_from_expr ());
     810           13 :   HIR::Expr *range_to = ASTLoweringExpr::translate (expr.get_to_expr ());
     811              : 
     812           13 :   std::vector<std::unique_ptr<HIR::Expr>> params;
     813           13 :   params.reserve (2);
     814           13 :   params.emplace_back (std::unique_ptr<HIR::Expr> (range_from));
     815           13 :   params.emplace_back (std::unique_ptr<HIR::Expr> (range_to));
     816              : 
     817           13 :   translated
     818           13 :     = new HIR::CallExpr (call_mapping, std::unique_ptr<HIR::Expr> (func),
     819           13 :                          std::move (params), expr.get_outer_attrs (),
     820           26 :                          expr.get_locus ());
     821           13 : }
     822              : 
     823              : void
     824          337 : ASTLoweringExpr::visit (AST::ClosureExprInner &expr)
     825              : {
     826          337 :   HIR::Expr *closure_expr
     827          337 :     = ASTLoweringExpr::translate (expr.get_definition_expr ());
     828              : 
     829          337 :   std::vector<HIR::ClosureParam> closure_params;
     830          337 :   closure_params.reserve (expr.get_params ().size ());
     831              : 
     832          720 :   for (auto &param : expr.get_params ())
     833          383 :     closure_params.emplace_back (lower_closure_param (param));
     834              : 
     835          337 :   auto crate_num = mappings.crate.get_current_crate ();
     836          674 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     837          337 :                                  mappings.get_next_hir_id (crate_num),
     838          337 :                                  mappings.get_next_localdef_id (crate_num));
     839              : 
     840          337 :   translated
     841          337 :     = new HIR::ClosureExpr (mapping, std::move (closure_params),
     842              :                             nullptr /* closure_return_type */,
     843          337 :                             std::unique_ptr<HIR::Expr> (closure_expr),
     844          337 :                             expr.get_has_move (), expr.get_outer_attrs (),
     845          337 :                             expr.get_locus ());
     846          337 : }
     847              : 
     848              : void
     849           31 : ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
     850              : {
     851           31 :   HIR::Type *closure_return_type = nullptr;
     852           31 :   HIR::Expr *closure_expr
     853           31 :     = ASTLoweringExpr::translate (expr.get_definition_expr ());
     854              : 
     855           31 :   std::vector<HIR::ClosureParam> closure_params;
     856           31 :   closure_params.reserve (expr.get_params ().size ());
     857              : 
     858           69 :   for (auto &param : expr.get_params ())
     859           38 :     closure_params.emplace_back (lower_closure_param (param));
     860              : 
     861           31 :   auto crate_num = mappings.crate.get_current_crate ();
     862           62 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     863           31 :                                  mappings.get_next_hir_id (crate_num),
     864           31 :                                  mappings.get_next_localdef_id (crate_num));
     865              : 
     866           31 :   translated
     867           31 :     = new HIR::ClosureExpr (mapping, std::move (closure_params),
     868           93 :                             std::unique_ptr<HIR::Type> (closure_return_type),
     869           62 :                             std::unique_ptr<HIR::Expr> (closure_expr),
     870           31 :                             expr.get_has_move (), expr.get_outer_attrs (),
     871           62 :                             expr.get_locus ());
     872           31 : }
     873              : 
     874              : HIR::InlineAsmOperand
     875           10 : translate_operand_in (const AST::InlineAsmOperand &operand)
     876              : {
     877           10 :   auto in_value = operand.get_in ();
     878              : 
     879           10 :   struct HIR::InlineAsmOperand::In in (
     880              :     in_value.reg,
     881           10 :     std::unique_ptr<Expr> (ASTLoweringExpr::translate (*in_value.expr.get ())));
     882           10 :   return in;
     883           10 : }
     884              : 
     885              : HIR::InlineAsmOperand
     886           17 : translate_operand_out (const AST::InlineAsmOperand &operand)
     887              : {
     888           17 :   auto out_value = operand.get_out ();
     889           17 :   struct HIR::InlineAsmOperand::Out out (out_value.reg, out_value.late,
     890           17 :                                          std::unique_ptr<Expr> (
     891              :                                            ASTLoweringExpr::translate (
     892           17 :                                              *out_value.expr.get ())));
     893           17 :   return out;
     894           17 : }
     895              : 
     896              : HIR::InlineAsmOperand
     897            0 : translate_operand_inout (const AST::InlineAsmOperand &operand)
     898              : {
     899            0 :   auto inout_value = operand.get_in_out ();
     900            0 :   struct HIR::InlineAsmOperand::InOut inout (inout_value.reg, inout_value.late,
     901            0 :                                              std::unique_ptr<Expr> (
     902              :                                                ASTLoweringExpr::translate (
     903            0 :                                                  *inout_value.expr.get ())));
     904            0 :   return inout;
     905            0 : }
     906              : 
     907              : HIR::InlineAsmOperand
     908            2 : translate_operand_split_in_out (const AST::InlineAsmOperand &operand)
     909              : {
     910            2 :   auto split_in_out_value = operand.get_split_in_out ();
     911            2 :   struct HIR::InlineAsmOperand::SplitInOut split_in_out (
     912              :     split_in_out_value.reg, split_in_out_value.late,
     913            2 :     std::unique_ptr<Expr> (
     914            2 :       ASTLoweringExpr::translate (*split_in_out_value.in_expr.get ())),
     915            2 :     std::unique_ptr<Expr> (
     916            2 :       ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ())));
     917            2 :   return split_in_out;
     918            2 : }
     919              : 
     920              : HIR::InlineAsmOperand
     921            0 : translate_operand_const (const AST::InlineAsmOperand &operand)
     922              : {
     923            0 :   auto const_value = operand.get_const ();
     924              : 
     925            0 :   auto inner_expr = ASTLoweringExpr::translate (const_value.anon_const);
     926              : 
     927              :   // Like `ConstBlock`, we know this should only be an `AnonConst` - let's
     928              :   // assert to make sure and static cast
     929            0 :   rust_assert (inner_expr->get_expression_type () == Expr::ExprType::AnonConst);
     930              : 
     931            0 :   auto anon_const = static_cast<AnonConst *> (inner_expr);
     932              : 
     933            0 :   return HIR::InlineAsmOperand::Const{*anon_const};
     934            0 : }
     935              : 
     936              : HIR::InlineAsmOperand
     937            0 : translate_operand_sym (const AST::InlineAsmOperand &operand)
     938              : {
     939            0 :   auto sym_value = operand.get_sym ();
     940            0 :   struct HIR::InlineAsmOperand::Sym sym (std::unique_ptr<Expr> (
     941            0 :     ASTLoweringExpr::translate (*sym_value.expr.get ())));
     942            0 :   return sym;
     943            0 : }
     944              : HIR::InlineAsmOperand
     945            0 : translate_operand_label (const AST::InlineAsmOperand &operand)
     946              : {
     947            0 :   auto label_value = operand.get_label ();
     948            0 :   struct HIR::InlineAsmOperand::Label label (label_value.label_name,
     949            0 :                                              std::unique_ptr<Expr> (
     950              :                                                ASTLoweringExpr::translate (
     951            0 :                                                  *label_value.expr.get ())));
     952            0 :   return label;
     953            0 : }
     954              : HIR::InlineAsmOperand
     955           29 : from_operand (const AST::InlineAsmOperand &operand)
     956              : {
     957           29 :   using RegisterType = AST::InlineAsmOperand::RegisterType;
     958           29 :   auto type = operand.get_register_type ();
     959              : 
     960              :   /*In,*/
     961              :   /*Out,*/
     962              :   /*InOut,*/
     963              :   /*SplitInOut,*/
     964              :   /*Const,*/
     965              :   /*Sym,*/
     966              :   /*Label,*/
     967           29 :   switch (type)
     968              :     {
     969           10 :     case RegisterType::In:
     970           10 :       return translate_operand_in (operand);
     971           17 :     case RegisterType::Out:
     972           17 :       return translate_operand_out (operand);
     973            0 :     case RegisterType::InOut:
     974            0 :       return translate_operand_inout (operand);
     975            2 :     case RegisterType::SplitInOut:
     976            2 :       return translate_operand_split_in_out (operand);
     977            0 :     case RegisterType::Const:
     978            0 :       return translate_operand_const (operand);
     979            0 :     case RegisterType::Sym:
     980            0 :       return translate_operand_sym (operand);
     981            0 :     case RegisterType::Label:
     982            0 :       return translate_operand_label (operand);
     983            0 :     default:
     984            0 :       rust_unreachable ();
     985              :     }
     986              : }
     987              : void
     988           27 : ASTLoweringExpr::visit (AST::InlineAsm &expr)
     989              : {
     990           27 :   auto crate_num = mappings.crate.get_current_crate ();
     991           54 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
     992           27 :                                  mappings.get_next_hir_id (crate_num),
     993           27 :                                  mappings.get_next_localdef_id (crate_num));
     994              : 
     995           27 :   std::vector<HIR::InlineAsmOperand> hir_operands;
     996           27 :   const std::vector<AST::InlineAsmOperand> &ast_operands = expr.get_operands ();
     997              :   /*int ast_operands_size = ast_operands.size ();*/
     998           56 :   for (auto &operand : ast_operands)
     999              :     {
    1000           29 :       hir_operands.push_back (from_operand (operand));
    1001              :     }
    1002              :   /*int hir_operands_size = hir_operands.size ();*/
    1003              : 
    1004              :   /*rust_debug ("{bdbt} : There are %d ast operands prelowering and %d hir "*/
    1005              :   /*     "operands after lowering\n",*/
    1006              :   /*     ast_operands_size, hir_operands_size);*/
    1007           27 :   translated
    1008           54 :     = new HIR::InlineAsm (expr.get_locus (), expr.is_global_asm,
    1009           54 :                           expr.get_template_ (), expr.get_template_strs (),
    1010           27 :                           hir_operands, expr.get_clobber_abi (),
    1011          108 :                           expr.get_options (), mapping);
    1012           27 : }
    1013              : 
    1014              : namespace {
    1015              : 
    1016              : tl::optional<std::string>
    1017           28 : convert_template_str (const std::string &in_template)
    1018              : {
    1019           28 :   std::string out_template;
    1020           28 :   auto it = in_template.cbegin ();
    1021              : 
    1022          396 :   while (it != in_template.cend ())
    1023              :     {
    1024          368 :       if (*it == '$')
    1025              :         {
    1026           52 :           it++;
    1027           52 :           if (it == in_template.cend ())
    1028              :             {
    1029            0 :               return tl::nullopt;
    1030              :             }
    1031           52 :           else if (*it >= '0' && *it <= '9')
    1032              :             {
    1033           36 :               out_template.push_back ('%');
    1034           36 :               out_template.push_back (*it);
    1035           36 :               it++;
    1036              :             }
    1037           16 :           else if (*it == '$')
    1038              :             {
    1039            0 :               out_template.push_back ('$');
    1040            0 :               it++;
    1041              :             }
    1042           16 :           else if (*it == '{')
    1043              :             {
    1044           16 :               it++;
    1045              :               // converting
    1046              :               //     v
    1047              :               //   ${123:abc}
    1048              :               // to
    1049              :               //   %abc123
    1050           16 :               auto num_it = it;
    1051           16 :               while (true)
    1052              :                 {
    1053           32 :                   if (it == in_template.cend ())
    1054            0 :                     return tl::nullopt;
    1055           32 :                   if (*it == ':')
    1056              :                     break;
    1057           16 :                   it++;
    1058              :                 }
    1059              :               auto colon_it = it;
    1060           32 :               while (true)
    1061              :                 {
    1062           48 :                   if (it == in_template.cend ())
    1063            0 :                     return tl::nullopt;
    1064           48 :                   if (*it == '}')
    1065              :                     break;
    1066           32 :                   it++;
    1067              :                 }
    1068              :               // output
    1069           16 :               out_template.push_back ('%');
    1070           16 :               out_template.append (colon_it + 1, it);
    1071           16 :               out_template.append (num_it, colon_it);
    1072              :               // increment past '}'
    1073           16 :               it++;
    1074              :             }
    1075              :           else
    1076              :             {
    1077            0 :               return tl::nullopt;
    1078              :             }
    1079              :         }
    1080          316 :       else if (*it == '%' || *it == '{' || *it == '|' || *it == '}')
    1081              :         {
    1082            0 :           out_template.push_back ('%');
    1083            0 :           out_template.push_back (*it);
    1084            0 :           it++;
    1085              :         }
    1086              :       else
    1087              :         {
    1088          316 :           out_template.push_back (*it);
    1089          316 :           it++;
    1090              :         }
    1091              :     }
    1092              : 
    1093           28 :   return out_template;
    1094           28 : }
    1095              : 
    1096              : // We're not really supporting llvm_asm, only the bare minimum for libcore
    1097              : // ex: llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
    1098              : bool
    1099           14 : check_llvm_asm_support (const AST::LlvmInlineAsm &expr)
    1100              : {
    1101              :   // TODO: more checks/constraint rewriting?
    1102              : 
    1103           28 :   if (!convert_template_str (expr.get_template ().symbol).has_value ())
    1104              :     return false;
    1105              : 
    1106              :   // TODO: check output constraints?
    1107              : 
    1108              :   // prohibit commas
    1109              :   // GCC uses them to list multiple options for constraints (?)
    1110              :   // while LLVM uses them for inout args (?)
    1111           29 :   for (auto &input : expr.get_inputs ())
    1112           15 :     if (input.constraint.find (',') != std::string::npos)
    1113           14 :       return false;
    1114              : 
    1115              :   // TODO: check clobbers?
    1116              : 
    1117              :   // no alignstack or intel support
    1118           14 :   if (expr.is_stack_aligned ())
    1119              :     return false;
    1120           14 :   if (expr.get_dialect () == AST::LlvmInlineAsm::Dialect::Intel)
    1121            0 :     return false;
    1122              : 
    1123              :   return true;
    1124              : }
    1125              : 
    1126              : } // namespace
    1127              : 
    1128              : void
    1129           14 : ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
    1130              : {
    1131           14 :   if (!check_llvm_asm_support (expr))
    1132              :     {
    1133            0 :       rust_error_at (expr.get_locus (), "unsupported %qs construct",
    1134              :                      "llvm_asm");
    1135            0 :       rust_inform (
    1136            0 :         expr.get_locus (),
    1137              :         "%<llvm_asm%> has been replaced with %<asm%>, gccrs only supports a "
    1138              :         "subset of %<llvm_asm%> to compile libcore");
    1139              :     }
    1140              : 
    1141           14 :   auto crate_num = mappings.crate.get_current_crate ();
    1142           28 :   Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
    1143           14 :                                  mappings.get_next_hir_id (crate_num),
    1144           14 :                                  mappings.get_next_localdef_id (crate_num));
    1145              : 
    1146           14 :   std::vector<LlvmOperand> inputs;
    1147           14 :   inputs.reserve (expr.get_inputs ().size ());
    1148              : 
    1149           14 :   std::vector<LlvmOperand> outputs;
    1150           14 :   outputs.reserve (expr.get_outputs ().size ());
    1151              : 
    1152           29 :   for (auto i : expr.get_inputs ())
    1153              :     {
    1154           15 :       std::unique_ptr<Expr> inner_expr
    1155           15 :         = std::unique_ptr<Expr> (translate (*i.expr.get ()));
    1156           15 :       inputs.emplace_back (i.constraint, std::move (inner_expr));
    1157           30 :     }
    1158              : 
    1159           31 :   for (auto o : expr.get_outputs ())
    1160              :     {
    1161           17 :       std::unique_ptr<Expr> inner_expr
    1162           17 :         = std::unique_ptr<Expr> (translate (*o.expr.get ()));
    1163           17 :       outputs.emplace_back (o.constraint, std::move (inner_expr));
    1164           34 :     }
    1165              : 
    1166           14 :   HIR::LlvmInlineAsm::Options options{expr.is_volatile (),
    1167           14 :                                       expr.is_stack_aligned (),
    1168           14 :                                       expr.get_dialect ()};
    1169              : 
    1170           14 :   auto new_template = expr.get_template ();
    1171           14 :   new_template.symbol
    1172           14 :     = convert_template_str (new_template.symbol).value_or (std::string ());
    1173              : 
    1174           14 :   rust_debug_fmt_at (expr.get_locus (),
    1175              :                      "converting %<llvm_asm%> template %qs to %qs",
    1176           14 :                      expr.get_template ().symbol.c_str (),
    1177              :                      new_template.symbol.c_str ());
    1178              : 
    1179           14 :   translated
    1180           28 :     = new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
    1181           14 :                               std::move (new_template), expr.get_clobbers (),
    1182           14 :                               options, expr.get_outer_attrs (), mapping);
    1183           14 : }
    1184              : 
    1185              : void
    1186            0 : ASTLoweringExpr::visit (AST::FormatArgs &fmt)
    1187              : {
    1188            0 :   rust_sorry_at (fmt.get_locus (),
    1189              :                  "FormatArgs lowering is not implemented yet");
    1190            0 : }
    1191              : 
    1192              : void
    1193           15 : ASTLoweringExpr::visit (AST::OffsetOf &offset_of)
    1194              : {
    1195           15 :   auto type = std::unique_ptr<Type> (
    1196           15 :     ASTLoweringType::translate (offset_of.get_type ()));
    1197              : 
    1198           15 :   auto crate_num = mappings.crate.get_current_crate ();
    1199           30 :   Analysis::NodeMapping mapping (crate_num, offset_of.get_node_id (),
    1200           15 :                                  mappings.get_next_hir_id (crate_num),
    1201           15 :                                  mappings.get_next_localdef_id (crate_num));
    1202              : 
    1203           15 :   translated = new HIR::OffsetOf (std::move (type), offset_of.get_field (),
    1204           15 :                                   mapping, offset_of.get_locus ());
    1205           15 : }
    1206              : 
    1207              : } // namespace HIR
    1208              : } // namespace Rust
        

Generated by: LCOV version 2.5.0-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.