LCOV - code coverage report
Current view: top level - gcc/rust/ast - rust-desugar-for-loops.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 72 72
Test Date: 2026-08-22 16:33:35 Functions: 100.0 % 5 5
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2025-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-desugar-for-loops.h"
      20              : #include "rust-ast.h"
      21              : #include "rust-hir-map.h"
      22              : #include "rust-path.h"
      23              : #include "rust-pattern.h"
      24              : #include "rust-stmt.h"
      25              : #include "rust-expr.h"
      26              : #include "rust-ast-builder.h"
      27              : 
      28              : namespace Rust {
      29              : namespace AST {
      30              : 
      31          119 : DesugarForLoops::DesugarForLoops () {}
      32              : 
      33              : MatchCase
      34          119 : DesugarForLoops::DesugarCtx::make_break_arm ()
      35              : {
      36          119 :   auto arm = builder.match_arm (std::unique_ptr<Pattern> (new PathInExpression (
      37          119 :     builder.path_in_expression (LangItem::Kind::OPTION_NONE))));
      38              : 
      39          119 :   auto break_expr
      40          119 :     = std::unique_ptr<Expr> (new BreakExpr (tl::nullopt, tl::nullopt, {}, loc));
      41              : 
      42          119 :   return MatchCase (std::move (arm), std::move (break_expr));
      43          119 : }
      44              : 
      45              : MatchCase
      46          119 : DesugarForLoops::DesugarCtx::make_continue_arm ()
      47              : {
      48          119 :   auto val = builder.identifier_pattern (DesugarCtx::continue_pattern_id);
      49              : 
      50          119 :   auto patterns = std::vector<std::unique_ptr<Pattern>> ();
      51          119 :   patterns.emplace_back (std::move (val));
      52              : 
      53          119 :   auto pattern_item = std::unique_ptr<TupleStructItems> (
      54          119 :     new TupleStructItemsNoRest (std::move (patterns)));
      55          119 :   auto pattern = std::unique_ptr<Pattern> (new TupleStructPattern (
      56          238 :     builder.path_in_expression (LangItem::Kind::OPTION_SOME),
      57          119 :     std::move (pattern_item)));
      58              : 
      59          119 :   auto val_arm = builder.match_arm (std::move (pattern));
      60              : 
      61          119 :   auto next = builder.identifier (DesugarCtx::next_value_id);
      62              : 
      63          119 :   auto assignment = std::unique_ptr<Expr> (
      64              :     new AssignmentExpr (std::move (next),
      65          238 :                         builder.identifier (DesugarCtx::continue_pattern_id),
      66          357 :                         {}, loc));
      67              : 
      68          119 :   return MatchCase (std::move (val_arm), std::move (assignment));
      69          119 : }
      70              : 
      71              : std::unique_ptr<Expr>
      72          119 : DesugarForLoops::desugar (ForLoopExpr &expr, Builder::Source node_source)
      73              : {
      74          119 :   auto ctx = DesugarCtx (expr.get_locus (), node_source);
      75              : 
      76          119 :   auto into_iter = std::make_unique<PathInExpression> (
      77          119 :     ctx.builder.path_in_expression (LangItem::Kind::INTOITER_INTOITER));
      78          119 :   auto next = std::make_unique<PathInExpression> (
      79          119 :     ctx.builder.path_in_expression (LangItem::Kind::ITERATOR_NEXT));
      80              : 
      81              :   // IntoIterator::into_iter(<head>)
      82          119 :   auto into_iter_call
      83          119 :     = ctx.builder.call (std::move (into_iter),
      84          357 :                         expr.get_iterator_expr ().clone_expr ());
      85              : 
      86              :   // Iterator::next(iter)
      87          119 :   auto next_call = ctx.builder.call (
      88          119 :     std::move (next),
      89          357 :     ctx.builder.ref (ctx.builder.identifier (DesugarCtx::iter_id), true));
      90              : 
      91              :   // None => break,
      92          119 :   auto break_arm = ctx.make_break_arm ();
      93              :   // Some(val) => __next = val; },
      94          119 :   auto continue_arm = ctx.make_continue_arm ();
      95              : 
      96              :   // match <next_call> {
      97              :   //     <continue_arm>
      98              :   //     <break_arm>
      99              :   // }
     100          119 :   auto match_next
     101          476 :     = ctx.builder.match (std::move (next_call),
     102          119 :                          {std::move (continue_arm), std::move (break_arm)});
     103              : 
     104              :   // let mut __next;
     105          119 :   auto let_next = ctx.builder.let (
     106          119 :     ctx.builder.identifier_pattern (DesugarCtx::next_value_id, true));
     107              :   // let <pattern> = __next;
     108          119 :   auto let_pat
     109          238 :     = ctx.builder.let (expr.get_pattern ().clone_pattern (), nullptr,
     110          357 :                        ctx.builder.identifier (DesugarCtx::next_value_id));
     111              : 
     112          119 :   auto loop_stmts = std::vector<std::unique_ptr<Stmt>> ();
     113          119 :   loop_stmts.emplace_back (std::move (let_next));
     114          119 :   loop_stmts.emplace_back (ctx.builder.statementify (std::move (match_next)));
     115          119 :   loop_stmts.emplace_back (std::move (let_pat));
     116          119 :   loop_stmts.emplace_back (
     117          238 :     ctx.builder.statementify (expr.get_loop_block ().clone_expr ()));
     118              : 
     119              :   // loop {
     120              :   //     <let_next>;
     121              :   //     <match_next>;
     122              :   //     <let_pat>;
     123              :   //
     124              :   //     <body>;
     125              :   // }
     126          119 :   auto loop = ctx.builder.loop (std::move (loop_stmts));
     127              : 
     128          119 :   auto mut_iter_pattern
     129          119 :     = ctx.builder.identifier_pattern (DesugarCtx::iter_id, true);
     130          119 :   auto match_iter
     131          357 :     = ctx.builder.match (std::move (into_iter_call),
     132              :                          {ctx.builder.match_case (std::move (mut_iter_pattern),
     133          119 :                                                   std::move (loop))});
     134              : 
     135          119 :   auto let_result
     136          238 :     = ctx.builder.let (ctx.builder.identifier_pattern (DesugarCtx::result_id),
     137          357 :                        nullptr, std::move (match_iter));
     138          119 :   auto result_return = ctx.builder.identifier (DesugarCtx::result_id);
     139              : 
     140          119 :   return ctx.builder.block (std::move (let_result), std::move (result_return));
     141          357 : }
     142              : 
     143              : void
     144          119 : DesugarForLoops::go (std::unique_ptr<Expr> &ptr, Builder::Source node_source)
     145              : {
     146          119 :   rust_assert (ptr->get_expr_kind () == Expr::Kind::Loop);
     147              : 
     148          119 :   auto &loop = static_cast<BaseLoopExpr &> (*ptr);
     149              : 
     150          119 :   rust_assert (loop.get_loop_kind () == BaseLoopExpr::Kind::For);
     151              : 
     152          119 :   auto &for_loop = static_cast<ForLoopExpr &> (loop);
     153          119 :   auto desugared = DesugarForLoops ().desugar (for_loop, node_source);
     154              : 
     155          119 :   ptr = std::move (desugared);
     156          119 : }
     157              : 
     158              : } // namespace AST
     159              : } // namespace Rust
        

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