From: Lishin <[email protected]>

Pass the struct expression HIR ID through BIR so moves from the same
expression can be identified. For now, report the case as unsupported
when an expression moves more than one value.

gcc/rust/ChangeLog:

        * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
        (ExprStmtBuilder::visit): Pass the struct expression HIR ID.
        * checks/errors/borrowck/rust-bir-builder-internal.h
        (AbstractBuilder::push_tmp_assignment): Propagate move sites.
        (AbstractBuilder::move_place): Likewise.
        (AbstractBuilder::move_all): Likewise.
        * checks/errors/borrowck/rust-bir-drop-analysis.cc
        (annotate_drop_statements): Reject multiple move sources.

gcc/testsuite/ChangeLog:

        * rust/compile/drop-conditional-product-move.rs: New test.

Signed-off-by: Lishin <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/c007e328479c591983717ff57322cf62a4b9b540

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4798

 .../borrowck/rust-bir-builder-expr-stmt.cc    |  2 +-
 .../borrowck/rust-bir-builder-internal.h      | 25 ++++++----
 .../errors/borrowck/rust-bir-drop-analysis.cc | 16 +++++-
 .../compile/drop-conditional-product-move.rs  | 49 +++++++++++++++++++
 4 files changed, 79 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/drop-conditional-product-move.rs

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 889e4611e..6586e9521 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -111,7 +111,7 @@ ExprStmtBuilder::visit (HIR::StructExprStructFields &fields)
     {
       field_locations.push_back (field->get_locus ());
     }
-  move_all (init_values, field_locations);
+  move_all (init_values, field_locations, fields.get_mappings ().get_hirid ());
   return_expr (new InitializerExpr (std::move (init_values)),
               lookup_type (fields), fields.get_locus ());
 }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index b5644741d..b1ced93eb 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -280,17 +280,19 @@ protected: // Helpers to add BIR statements
   }
 
   void push_tmp_assignment (AbstractExpr *rhs, TyTy::BaseType *tyty,
-                           location_t location)
+                           location_t location,
+                           tl::optional<HirId> move_site = tl::nullopt)
   {
     PlaceId tmp = ctx.place_db.add_temporary (tyty);
     push_storage_live (tmp);
-    push_assignment (tmp, rhs, location);
+    push_assignment (tmp, rhs, location, move_site);
   }
 
-  void push_tmp_assignment (PlaceId rhs, location_t location)
+  void push_tmp_assignment (PlaceId rhs, location_t location,
+                           tl::optional<HirId> move_site = tl::nullopt)
   {
-    push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty,
-                        location);
+    push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty, 
location,
+                        move_site);
   }
 
   void push_switch (PlaceId switch_val, location_t location,
@@ -353,7 +355,8 @@ protected: // Helpers to add BIR statements
     return translated;
   }
 
-  PlaceId move_place (PlaceId arg, location_t location)
+  PlaceId move_place (PlaceId arg, location_t location,
+                     tl::optional<HirId> move_site = tl::nullopt)
   {
     auto &place = ctx.place_db[arg];
 
@@ -366,7 +369,7 @@ protected: // Helpers to add BIR statements
     if (place.is_rvalue ())
       return arg;
 
-    push_tmp_assignment (arg, location);
+    push_tmp_assignment (arg, location, move_site);
     return translated;
   }
 
@@ -379,12 +382,14 @@ protected: // Helpers to add BIR statements
   }
 
   template <typename T>
-  void move_all (T &args, std::vector<location_t> locations)
+  void move_all (T &args, std::vector<location_t> locations,
+                tl::optional<HirId> move_site = tl::nullopt)
   {
     rust_assert (args.size () == locations.size ());
     std::transform (args.begin (), args.end (), locations.begin (),
-                   args.begin (), [this] (PlaceId arg, location_t location) {
-                     return move_place (arg, location);
+                   args.begin (),
+                   [this, move_site] (PlaceId arg, location_t location) {
+                     return move_place (arg, location, move_site);
                    });
   }
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
index 22be1553e..8a52d78f1 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
@@ -18,6 +18,7 @@
 
 #include "rust-bir-drop-analysis.h"
 #include "rust-bir.h"
+#include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 
 namespace Rust {
@@ -301,8 +302,19 @@ annotate_drop_statements (
                          static_cast<NodeId> (
                            rhs_place.variable_or_field_index));
                      if (hirid.has_value ())
-                       results.move_sources[move_site.value ()]
-                         = hirid.value ();
+                       {
+                         auto move_source
+                           = results.move_sources.find (move_site.value ());
+                         if (move_source != results.move_sources.end ()
+                             && move_source->second != hirid.value ())
+                           rust_sorry_at (statement.get_location (),
+                                          "moving multiple IDs within the "
+                                          "same location is not "
+                                          "yet supported");
+                         else
+                           results.move_sources.emplace (move_site.value (),
+                                                         hirid.value ());
+                       }
                    }
                }
            }
diff --git a/gcc/testsuite/rust/compile/drop-conditional-product-move.rs 
b/gcc/testsuite/rust/compile/drop-conditional-product-move.rs
new file mode 100644
index 000000000..a221a0308
--- /dev/null
+++ b/gcc/testsuite/rust/compile/drop-conditional-product-move.rs
@@ -0,0 +1,49 @@
+// { dg-additional-options "-frust-borrowcheck -w" }
+
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "drop"]
+pub trait Drop {
+    fn drop(&mut self);
+}
+
+struct Droppable {
+    value: i32,
+}
+
+impl Drop for Droppable {
+    fn drop(&mut self) {}
+}
+
+struct Pair {
+    first: Droppable,
+    second: Droppable,
+}
+
+fn unconditional_product_move() {
+    let first = Droppable { value: 1 };
+    let second = Droppable { value: 2 };
+    let _pair = Pair { first, second }; // { dg-message "sorry, unimplemented: 
moving multiple IDs within the same location is not yet supported" }
+}
+
+fn conditional_product_move(condition: bool) {
+    let first = Droppable { value: 1 };
+    let second = Droppable { value: 2 };
+
+    if condition {
+        let _pair = Pair {
+            first,
+            second, // { dg-message "sorry, unimplemented: moving multiple IDs 
within the same location is not yet supported" }
+        };
+    }
+}
+
+fn main() {
+    unconditional_product_move();
+    conditional_product_move(true);
+}
-- 
2.55.0

Reply via email to