LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors/borrowck - rust-borrow-checker-diagnostics.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 60 60
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
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-borrow-checker-diagnostics.h"
      20              : #include "polonius/rust-polonius-ffi.h"
      21              : #include "rust-diagnostics.h"
      22              : 
      23              : namespace Rust {
      24              : namespace BIR {
      25              : 
      26              : void
      27           36 : BorrowCheckerDiagnostics::report_errors ()
      28              : {
      29           36 :   report_move_errors ();
      30           36 :   report_loan_errors ();
      31           36 :   report_subset_errors ();
      32           36 : }
      33              : 
      34              : void
      35           36 : BorrowCheckerDiagnostics::report_move_errors ()
      36              : {
      37           39 :   for (const auto &pair : move_errors)
      38              :     {
      39            3 :       auto error_location = get_statement (pair.first).get_location ();
      40              : 
      41              :       // in future, we can use the assigned at location to hint the
      42              :       // user to implement copy trait for the type
      43              :       /*
      44              :       for (auto it : facts.path_assigned_at_base)
      45              :         {
      46              :           if (pair.second[0] == it.first)
      47              :             {
      48              :               auto point_assigned_at = it.second;
      49              :               auto assigned_at_location
      50              :                 = get_statement (point_assigned_at).get_location ();
      51              :             }
      52              :         }
      53              :         */
      54              : 
      55            3 :       std::vector<LabelLocationPair> labels{
      56            3 :         {"moved value used here", error_location}};
      57              :       // add labels to all the moves for the given path
      58           50 :       for (auto it : facts.path_moved_at_base)
      59              :         {
      60           47 :           if (pair.second[0] == it.first)
      61              :             {
      62           14 :               auto point_moved_at = it.second;
      63              :               // don't label the move location where the error occured
      64           14 :               if (pair.first != point_moved_at)
      65              :                 {
      66           11 :                   auto move_at_location
      67           11 :                     = get_statement (point_moved_at).get_location ();
      68           11 :                   labels.push_back ({"value moved here", move_at_location});
      69              :                 }
      70              :             }
      71              :         }
      72            3 :       multi_label_error ("use of moved value", error_location, labels);
      73            3 :     }
      74           36 : }
      75              : 
      76              : void
      77           36 : BorrowCheckerDiagnostics::report_loan_errors ()
      78              : {
      79           52 :   for (const auto &pair : loan_errors)
      80              :     {
      81           16 :       auto error_location = get_statement (pair.first).get_location ();
      82           32 :       for (const auto &loan : pair.second)
      83              :         {
      84           16 :           auto loan_struct = get_loan (loan);
      85           16 :           multi_label_error ("use of borrowed value", error_location,
      86              :                              {{"borrow occurs here", loan_struct.location},
      87              :                               {"borrowed value used here", error_location}});
      88              :         }
      89              :     }
      90           36 : }
      91              : 
      92              : void
      93           36 : BorrowCheckerDiagnostics::report_subset_errors ()
      94              : {
      95              :   // remove duplicates in subset_errors
      96              :   //
      97              :   // Polonius may output subset errors for same 2 origins at multiple points
      98              :   // so to avoid duplicating the errors, we can remove the elements in subset
      99              :   // errors with same origin pair
     100           36 :   std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
     101           36 :     deduplicated_subset_errors;
     102              : 
     103           46 :   for (auto pair : subset_errors)
     104              :     {
     105           10 :       auto it = std::find_if (
     106              :         deduplicated_subset_errors.begin (), deduplicated_subset_errors.end (),
     107            8 :         [&pair] (std::pair<size_t, std::pair<size_t, size_t>> element) {
     108            8 :           return element.second == pair.second;
     109              :         });
     110           10 :       if (it == deduplicated_subset_errors.end ())
     111              :         {
     112            2 :           deduplicated_subset_errors.push_back (pair);
     113              :         }
     114              :     }
     115           38 :   for (const auto &error : deduplicated_subset_errors)
     116              :     {
     117            2 :       auto first_lifetime_location
     118            2 :         = get_lifetime_param (error.second.first)->get_locus ();
     119            2 :       auto second_lifetime_location
     120            2 :         = get_lifetime_param (error.second.second)->get_locus ();
     121            2 :       multi_label_error (
     122              :         "subset error, some lifetime constraints need to be added",
     123              :         bir_function.location,
     124              :         {{"lifetime defined here", first_lifetime_location},
     125              :          {"lifetime defined here", second_lifetime_location},
     126            2 :          {"subset error occurs in this function", bir_function.location}});
     127              :     }
     128           36 : }
     129              : 
     130              : const BIR::Statement &
     131           30 : BorrowCheckerDiagnostics::get_statement (Polonius::Point point)
     132              : {
     133           30 :   auto statement_index = Polonius::FullPoint::extract_stmt (point);
     134           30 :   auto bb_index = Polonius::FullPoint::extract_bb (point);
     135              :   // assert that the extracted indexes are valid
     136           30 :   rust_assert (bb_index < bir_function.basic_blocks.size ());
     137           30 :   rust_assert (statement_index
     138              :                < bir_function.basic_blocks[{bb_index}].statements.size ());
     139           30 :   return bir_function.basic_blocks[{bb_index}].statements[statement_index];
     140              : }
     141              : 
     142              : const BIR::Loan &
     143           16 : BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
     144              : {
     145           16 :   return bir_function.place_db.get_loans ()[{(uint32_t) loan}];
     146              : }
     147              : 
     148              : const HIR::LifetimeParam *
     149            4 : BorrowCheckerDiagnostics::get_lifetime_param (Polonius::Origin origin)
     150              : 
     151              : {
     152            4 :   return bir_function.region_hir_map.at (origin);
     153              : }
     154              : 
     155              : void
     156           21 : BorrowCheckerDiagnostics::multi_label_error (
     157              :   const char *error_message, location_t error_location,
     158              :   std::vector<LabelLocationPair> location_label_pairs)
     159              : {
     160           21 :   rich_location r{line_table, error_location};
     161           73 :   for (auto &label_location : location_label_pairs)
     162              :     {
     163           52 :       r.add_range (label_location.location, SHOW_RANGE_WITHOUT_CARET,
     164              :                    &label_location.label);
     165              :     }
     166           21 :   rust_error_at (r, "%s", error_message);
     167           21 : }
     168              : 
     169              : } // namespace BIR
     170              : } // 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.