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