From: Kushal Pal <kushalpal...@gmail.com>

This commit adds location_t to BIR::Statement where type is ASSIGNMENT
this information will be later used for reporting borrow-checking
errors.

gcc/rust/ChangeLog:

        * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
        (ExprStmtBuilder::visit): Added location parameter.
        * checks/errors/borrowck/rust-bir-builder-internal.h: Likewise.
        * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
        Likewise.
        * checks/errors/borrowck/rust-bir-builder-pattern.h: Likewise.
        * checks/errors/borrowck/rust-bir-builder.h: Likewise.
        * checks/errors/borrowck/rust-bir.h: Likewise.

Signed-off-by: Kushal Pal <kushalpal...@gmail.com>
---
 .../borrowck/rust-bir-builder-expr-stmt.cc    | 145 ++++++++++++------
 .../borrowck/rust-bir-builder-internal.h      |  67 ++++----
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |  74 ++++-----
 .../borrowck/rust-bir-builder-pattern.h       |   7 +-
 .../checks/errors/borrowck/rust-bir-builder.h |   3 +-
 gcc/rust/checks/errors/borrowck/rust-bir.h    |  19 ++-
 6 files changed, 194 insertions(+), 121 deletions(-)

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 acfcdd88425..49b830124d7 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
@@ -80,14 +80,21 @@ ExprStmtBuilder::visit (HIR::ClosureExpr &expr)
 {
   auto closure_ty = lookup_type (expr)->as<TyTy::ClosureType> ();
   std::vector<PlaceId> captures;
+  std::vector<location_t> capture_locations;
   for (auto &capture : closure_ty->get_captures ())
     {
       captures.push_back (ctx.place_db.lookup_variable (capture));
+      auto location = Analysis::Mappings::get ()
+                       .lookup_ast_item (capture)
+                       .value ()
+                       ->get_locus ();
+      capture_locations.push_back (location);
     }
-  move_all (captures);
+  move_all (captures, capture_locations);
 
   // Note: Not a coercion site for captures.
-  return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr));
+  return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
@@ -96,23 +103,31 @@ ExprStmtBuilder::visit (HIR::StructExprStructFields 
&fields)
   auto *p_adt_type = lookup_type (fields)->as<TyTy::ADTType> ();
   auto struct_ty = p_adt_type->get_variants ().at (0);
   auto init_values = StructBuilder (ctx, struct_ty).build (fields);
-  move_all (init_values);
+  // collect fields locations
+  std::vector<location_t> field_locations;
+  for (auto &field : fields.get_fields ())
+    {
+      field_locations.push_back (field->get_locus ());
+    }
+  move_all (init_values, field_locations);
   return_expr (new InitializerExpr (std::move (init_values)),
-              lookup_type (fields));
+              lookup_type (fields), fields.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::StructExprStruct &expr)
 {
   // There is no way to modify empty struct, which makes them constant.
-  return_place (ctx.place_db.get_constant (lookup_type (expr)));
+  return_place (ctx.place_db.get_constant (lookup_type (expr)),
+               expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::LiteralExpr &expr)
 {
   // Different literal values of the same type are not distinguished in BIR.
-  return_place (ctx.place_db.get_constant (lookup_type (expr)));
+  return_place (ctx.place_db.get_constant (lookup_type (expr)),
+               expr.get_locus ());
 }
 
 void
@@ -122,12 +137,12 @@ ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
   if (ctx.place_db[operand].is_constant ())
     {
       // Cannot borrow a constant, must create a temporary copy.
-      push_tmp_assignment (operand);
+      push_tmp_assignment (operand, expr.get_locus ());
       operand = translated;
     }
 
   // BorrowExpr cannot be annotated with lifetime.
-  return_borrowed (operand, lookup_type (expr));
+  return_borrowed (operand, lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -135,7 +150,8 @@ ExprStmtBuilder::visit (HIR::DereferenceExpr &expr)
 {
   auto operand = visit_expr (*expr.get_expr ());
   return_place (ctx.place_db.lookup_or_add_path (Place::DEREF,
-                                                lookup_type (expr), operand));
+                                                lookup_type (expr), operand),
+               expr.get_locus ());
 }
 
 void
@@ -149,7 +165,8 @@ void
 ExprStmtBuilder::visit (HIR::NegationExpr &expr)
 {
   PlaceId operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({move_place (operand)}), lookup_type (expr));
+  return_expr (new Operator<1> ({move_place (operand, expr.get_locus ())}),
+              lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -157,8 +174,10 @@ ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
-              lookup_type (expr));
+  return_expr (new Operator<2> (
+                {move_place (lhs, expr.get_lhs ()->get_locus ()),
+                 move_place (rhs, expr.get_rhs ()->get_locus ())}),
+              lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -166,8 +185,10 @@ ExprStmtBuilder::visit (HIR::ComparisonExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
-              lookup_type (expr));
+  return_expr (new Operator<2> (
+                {move_place (lhs, expr.get_lhs ()->get_locus ()),
+                 move_place (rhs, expr.get_rhs ()->get_locus ())}),
+              lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -175,14 +196,16 @@ ExprStmtBuilder::visit (HIR::LazyBooleanExpr &expr)
 {
   return_place (LazyBooleanExprBuilder (ctx, take_or_create_return_place (
                                               lookup_type (expr)))
-                 .build (expr));
+                 .build (expr),
+               expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::TypeCastExpr &expr)
 {
   auto operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({operand}), lookup_type (expr));
+  return_expr (new Operator<1> ({operand}), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
@@ -190,7 +213,7 @@ ExprStmtBuilder::visit (HIR::AssignmentExpr &expr)
 {
   auto lhs = visit_expr (*expr.get_lhs ());
   auto rhs = visit_expr (*expr.get_rhs ());
-  push_assignment (lhs, rhs);
+  push_assignment (lhs, rhs, expr.get_locus ());
   translated = INVALID_PLACE;
 }
 
@@ -199,13 +222,13 @@ ExprStmtBuilder::visit (HIR::CompoundAssignmentExpr &expr)
 {
   auto lhs = visit_expr (*expr.get_lhs ());
   auto rhs = visit_expr (*expr.get_rhs ());
-  push_assignment (lhs, new Operator<2> ({lhs, rhs}));
+  push_assignment (lhs, new Operator<2> ({lhs, rhs}), expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::GroupedExpr &expr)
 {
-  return_place (visit_expr (*expr.get_expr_in_parens ()));
+  return_place (visit_expr (*expr.get_expr_in_parens ()), expr.get_locus ());
 }
 
 void
@@ -217,15 +240,22 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
       case HIR::ArrayElems::VALUES: {
        auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (*elems));
        auto init_values = visit_list (elem_vals.get_values ());
-       move_all (init_values);
+       // collect locations
+       std::vector<location_t> value_locations;
+       for (auto &value : elem_vals.get_values ())
+         {
+           value_locations.push_back (value->get_locus ());
+         }
+       move_all (init_values, value_locations);
        return_expr (new InitializerExpr (std::move (init_values)),
-                    lookup_type (expr));
+                    lookup_type (expr), expr.get_locus ());
        break;
       }
       case HIR::ArrayElems::COPIED: {
        auto &elem_copied = (static_cast<HIR::ArrayElemsCopied &> (*elems));
        auto init = visit_expr (*elem_copied.get_elem_to_copy ());
-       return_expr (new InitializerExpr ({init}), lookup_type (expr));
+       return_expr (new InitializerExpr ({init}), lookup_type (expr),
+                    expr.get_locus ());
        break;
       }
     }
@@ -238,8 +268,9 @@ ExprStmtBuilder::visit (HIR::ArrayIndexExpr &expr)
   auto rhs = visit_expr (*expr.get_index_expr ());
   // The index is not tracked in BIR.
   std::ignore = rhs;
-  return_place (
-    ctx.place_db.lookup_or_add_path (Place::INDEX, lookup_type (expr), lhs));
+  return_place (ctx.place_db.lookup_or_add_path (Place::INDEX,
+                                                lookup_type (expr), lhs),
+               expr.get_locus ());
 }
 
 void
@@ -247,7 +278,7 @@ ExprStmtBuilder::visit (HIR::TupleExpr &expr)
 {
   std::vector<PlaceId> init_values = visit_list (expr.get_tuple_elems ());
   return_expr (new InitializerExpr (std::move (init_values)),
-              lookup_type (expr));
+              lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -256,7 +287,8 @@ ExprStmtBuilder::visit (HIR::TupleIndexExpr &expr)
   auto tuple = visit_expr (*expr.get_tuple_expr ());
   return_place (ctx.place_db.lookup_or_add_path (Place::FIELD,
                                                 lookup_type (expr), tuple,
-                                                expr.get_tuple_index ()));
+                                                expr.get_tuple_index ()),
+               expr.get_locus ());
 }
 
 void
@@ -273,10 +305,16 @@ ExprStmtBuilder::visit (HIR::CallExpr &expr)
       coercion_site (arguments[i], fn_type->get_param_type_at (i));
     }
 
-  move_all (arguments);
+  // collect parameter locations
+  std::vector<location_t> parameter_locations;
+  for (auto &parameter : expr.get_arguments ())
+    {
+      parameter_locations.push_back (parameter->get_locus ());
+    }
+  move_all (arguments, parameter_locations);
 
   return_expr (new CallExpr (fn, std::move (arguments)), lookup_type (expr),
-              true);
+              expr.get_locus (), true);
 }
 
 void
@@ -302,7 +340,8 @@ ExprStmtBuilder::visit (HIR::FieldAccessExpr &expr)
 
   return_place (ctx.place_db.lookup_or_add_path (Place::FIELD,
                                                 field_ty->get_field_type (),
-                                                receiver, field_index));
+                                                receiver, field_index),
+               expr.get_locus ());
 }
 
 void
@@ -338,7 +377,8 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
       if (block.has_expr () && !unreachable)
        {
          push_assignment (block_ctx.label_var,
-                          visit_expr (*block.get_final_expr ()));
+                          visit_expr (*block.get_final_expr ()),
+                          block.get_start_locus ());
        }
       if (!ctx.get_current_bb ().is_terminated ())
        {
@@ -347,13 +387,14 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
       ctx.current_bb = block_ctx.break_bb;
       ctx.loop_and_label_stack.pop_back ();
 
-      return_place (block_ctx.label_var);
+      return_place (block_ctx.label_var, block.get_start_locus ());
     }
   else if (block.has_expr () && !unreachable)
     {
       return_place (visit_expr (*block.get_final_expr (),
                                take_or_create_return_place (
-                                 lookup_type (*block.get_final_expr ()))));
+                                 lookup_type (*block.get_final_expr ()))),
+                   block.get_start_locus ());
     }
 
   if (!unreachable)
@@ -379,7 +420,8 @@ ExprStmtBuilder::visit (HIR::BreakExpr &brk)
   LoopAndLabelCtx info = brk.has_label () ? get_label_ctx (brk.get_label ())
                                          : get_unnamed_loop_ctx ();
   if (brk.has_break_expr ())
-    push_assignment (info.label_var, visit_expr (*brk.get_expr ()));
+    push_assignment (info.label_var, visit_expr (*brk.get_expr ()),
+                    brk.get_locus ());
 
   start_new_consecutive_bb ();
   unwind_until (ctx.place_db.get_scope (info.continue_scope).parent);
@@ -392,27 +434,30 @@ ExprStmtBuilder::visit (HIR::RangeFromToExpr &range)
 {
   auto from = visit_expr (*range.get_from_expr ());
   auto to = visit_expr (*range.get_to_expr ());
-  return_expr (new InitializerExpr ({from, to}), lookup_type (range));
+  return_expr (new InitializerExpr ({from, to}), lookup_type (range),
+              range.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::RangeFromExpr &expr)
 {
   auto from = visit_expr (*expr.get_from_expr ());
-  return_expr (new InitializerExpr ({from}), lookup_type (expr));
+  return_expr (new InitializerExpr ({from}), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::RangeToExpr &expr)
 {
   auto to = visit_expr (*expr.get_to_expr ());
-  return_expr (new InitializerExpr ({to}), lookup_type (expr));
+  return_expr (new InitializerExpr ({to}), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::RangeFullExpr &expr)
 {
-  return_expr (new InitializerExpr ({}), lookup_type (expr));
+  return_expr (new InitializerExpr ({}), lookup_type (expr), expr.get_locus 
());
 }
 
 void
@@ -420,14 +465,16 @@ ExprStmtBuilder::visit (HIR::RangeFromToInclExpr &expr)
 {
   auto from = visit_expr (*expr.get_from_expr ());
   auto to = visit_expr (*expr.get_to_expr ());
-  return_expr (new InitializerExpr ({from, to}), lookup_type (expr));
+  return_expr (new InitializerExpr ({from, to}), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::RangeToInclExpr &expr)
 {
   auto to = visit_expr (*expr.get_to_expr ());
-  return_expr (new InitializerExpr ({to}), lookup_type (expr));
+  return_expr (new InitializerExpr ({to}), lookup_type (expr),
+              expr.get_locus ());
 }
 
 void
@@ -436,7 +483,9 @@ ExprStmtBuilder::visit (HIR::ReturnExpr &ret)
   if (ret.has_return_expr ())
     {
       push_assignment (RETURN_VALUE_PLACE,
-                      move_place (visit_expr (*ret.get_expr ())));
+                      move_place (visit_expr (*ret.get_expr ()),
+                                  ret.get_expr ()->get_locus ()),
+                      ret.get_locus ());
     }
   unwind_until (ROOT_SCOPE);
   ctx.get_current_bb ().statements.emplace_back (Statement::Kind::RETURN);
@@ -468,7 +517,7 @@ ExprStmtBuilder::visit (HIR::WhileLoopExpr &expr)
 
   auto cond_val = visit_expr (*expr.get_predicate_expr ());
   auto body_bb = new_bb ();
-  push_switch (cond_val, {body_bb, loop.break_bb});
+  push_switch (cond_val, expr.get_locus (), {body_bb, loop.break_bb});
 
   ctx.current_bb = body_bb;
   std::ignore = visit_expr (*expr.get_loop_block ());
@@ -492,7 +541,7 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
   if (expr.get_if_block ()->statements.empty ())
     return;
 
-  push_switch (visit_expr (*expr.get_if_condition ()));
+  push_switch (visit_expr (*expr.get_if_condition ()), expr.get_locus ());
   BasicBlockId if_block = ctx.current_bb;
 
   ctx.current_bb = new_bb ();
@@ -518,7 +567,9 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 {
-  push_switch (move_place (visit_expr (*expr.get_if_condition ())));
+  push_switch (move_place (visit_expr (*expr.get_if_condition ()),
+                          expr.get_if_condition ()->get_locus ()),
+              expr.get_locus ());
   BasicBlockId if_end_bb = ctx.current_bb;
 
   PlaceId result = take_or_create_return_place (lookup_type (expr));
@@ -539,7 +590,7 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 
   ctx.current_bb = new_bb ();
   BasicBlockId final_start_bb = ctx.current_bb;
-  return_place (result);
+  return_place (result, expr.get_locus ());
 
   // Jumps are added at the end to match rustc MIR order for easier comparison.
   add_jump (if_end_bb, then_start_bb);
@@ -627,7 +678,7 @@ ExprStmtBuilder::visit (HIR::QualifiedPathInExpression 
&expr)
 {
   // Note: Type is only stored for the expr, not the segment.
   PlaceId result = resolve_variable_or_fn (expr, lookup_type (expr));
-  return_place (result);
+  return_place (result, expr.get_locus ());
 }
 
 void
@@ -635,7 +686,7 @@ ExprStmtBuilder::visit (HIR::PathInExpression &expr)
 {
   // Note: Type is only stored for the expr, not the segment.
   PlaceId result = resolve_variable_or_fn (expr, lookup_type (expr));
-  return_place (result);
+  return_place (result, expr.get_locus ());
 }
 
 void
@@ -677,7 +728,7 @@ ExprStmtBuilder::visit (HIR::ExprStmt &stmt)
   // We must read the value for current liveness and we must not store it into
   // the same place.
   if (result != INVALID_PLACE)
-    push_tmp_assignment (result);
+    push_tmp_assignment (result, stmt.get_locus ());
 }
 } // namespace BIR
 } // namespace Rust
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 f47c41f5473..46f811ea25a 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -237,33 +237,35 @@ protected:
   }
 
 protected: // Helpers to add BIR statements
-  void push_assignment (PlaceId lhs, AbstractExpr *rhs)
+  void push_assignment (PlaceId lhs, AbstractExpr *rhs, location_t location)
   {
-    ctx.get_current_bb ().statements.emplace_back (lhs, rhs);
+    ctx.get_current_bb ().statements.emplace_back (lhs, rhs, location);
     translated = lhs;
   }
 
-  void push_assignment (PlaceId lhs, PlaceId rhs)
+  void push_assignment (PlaceId lhs, PlaceId rhs, location_t location)
   {
-    push_assignment (lhs, new Assignment (rhs));
+    push_assignment (lhs, new Assignment (rhs), location);
   }
 
-  void push_tmp_assignment (AbstractExpr *rhs, TyTy::BaseType *tyty)
+  void push_tmp_assignment (AbstractExpr *rhs, TyTy::BaseType *tyty,
+                           location_t location)
   {
     PlaceId tmp = ctx.place_db.add_temporary (tyty);
     push_storage_live (tmp);
-    push_assignment (tmp, rhs);
+    push_assignment (tmp, rhs, location);
   }
 
-  void push_tmp_assignment (PlaceId rhs)
+  void push_tmp_assignment (PlaceId rhs, location_t location)
   {
-    push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty);
+    push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty,
+                        location);
   }
 
-  void push_switch (PlaceId switch_val,
+  void push_switch (PlaceId switch_val, location_t location,
                    std::initializer_list<BasicBlockId> destinations = {})
   {
-    auto copy = move_place (switch_val);
+    auto copy = move_place (switch_val, location);
     ctx.get_current_bb ().statements.emplace_back (Statement::Kind::SWITCH,
                                                   copy);
     ctx.get_current_bb ().successors.insert (
@@ -301,17 +303,18 @@ protected: // Helpers to add BIR statements
                                                   place);
   }
 
-  PlaceId borrow_place (PlaceId place_id, TyTy::BaseType *ty)
+  PlaceId borrow_place (PlaceId place_id, TyTy::BaseType *ty,
+                       location_t location)
   {
     auto mutability = ty->as<const TyTy::ReferenceType> ()->mutability ();
     auto loan = ctx.place_db.add_loan ({mutability, place_id});
     push_tmp_assignment (new BorrowExpr (place_id, loan,
                                         ctx.place_db.get_next_free_region ()),
-                        ty);
+                        ty, location);
     return translated;
   }
 
-  PlaceId move_place (PlaceId arg)
+  PlaceId move_place (PlaceId arg, location_t location)
   {
     auto &place = ctx.place_db[arg];
 
@@ -319,27 +322,31 @@ protected: // Helpers to add BIR statements
       return arg;
 
     if (place.tyty->is<TyTy::ReferenceType> ())
-      return reborrow_place (arg);
+      return reborrow_place (arg, location);
 
     if (place.is_rvalue ())
       return arg;
 
-    push_tmp_assignment (arg);
+    push_tmp_assignment (arg, location);
     return translated;
   }
 
-  PlaceId reborrow_place (PlaceId arg)
+  PlaceId reborrow_place (PlaceId arg, location_t location)
   {
     auto ty = ctx.place_db[arg].tyty->as<TyTy::ReferenceType> ();
     return borrow_place (ctx.place_db.lookup_or_add_path (Place::DEREF,
                                                          ty->get_base (), arg),
-                        ty);
+                        ty, location);
   }
 
-  template <typename T> void move_all (T &args)
+  template <typename T>
+  void move_all (T &args, std::vector<location_t> locations)
   {
-    std::transform (args.begin (), args.end (), args.begin (),
-                   [this] (PlaceId arg) { return move_place (arg); });
+    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);
+                   });
   }
 
 protected: // CFG helpers
@@ -477,12 +484,15 @@ protected: // Implicit conversions.
   {
     if (ctx.place_db[translated].tyty->get_kind () != TyTy::REF)
       {
+       // FIXME: not sure how to fetch correct location for this
+       // this function is unused yet, so can ignore for now
        auto ty = ctx.place_db[translated].tyty;
        translated
          = borrow_place (translated,
                          new TyTy::ReferenceType (ty->get_ref (),
                                                   TyTy::TyVar (ty->get_ref ()),
-                                                  Mutability::Imm));
+                                                  Mutability::Imm),
+                         UNKNOWN_LOCATION);
       }
   }
 };
@@ -531,16 +541,16 @@ protected:
    * @param can_panic mark that expression can panic to insert jump to
    * cleanup.
    */
-  void return_expr (AbstractExpr *expr, TyTy::BaseType *ty,
+  void return_expr (AbstractExpr *expr, TyTy::BaseType *ty, location_t 
location,
                    bool can_panic = false)
   {
     if (expr_return_place != INVALID_PLACE)
       {
-       push_assignment (expr_return_place, expr);
+       push_assignment (expr_return_place, expr, location);
       }
     else
       {
-       push_tmp_assignment (expr, ty);
+       push_tmp_assignment (expr, ty, location);
       }
 
     if (can_panic)
@@ -556,12 +566,12 @@ protected:
   }
 
   /** Mark place to be a result of processed subexpression. */
-  void return_place (PlaceId place, bool can_panic = false)
+  void return_place (PlaceId place, location_t location, bool can_panic = 
false)
   {
     if (expr_return_place != INVALID_PLACE)
       {
        // Return place is already allocated, no need to defer assignment.
-       push_assignment (expr_return_place, place);
+       push_assignment (expr_return_place, place, location);
       }
     else
       {
@@ -585,14 +595,15 @@ protected:
     translated = ctx.place_db.get_constant (lookup_type (expr));
   }
 
-  PlaceId return_borrowed (PlaceId place_id, TyTy::BaseType *ty)
+  PlaceId return_borrowed (PlaceId place_id, TyTy::BaseType *ty,
+                          location_t location)
   {
     // TODO: deduplicate with borrow_place
     auto loan = ctx.place_db.add_loan (
       {ty->as<const TyTy::ReferenceType> ()->mutability (), place_id});
     return_expr (new BorrowExpr (place_id, loan,
                                 ctx.place_db.get_next_free_region ()),
-                ty);
+                ty, location);
     return translated;
   }
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index 11134c21ea6..3f46d57ea51 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -45,13 +45,14 @@ public:
     PlaceId return_place = take_or_create_return_place (lookup_type (expr));
 
     short_circuit_bb = new_bb ();
-    push_assignment (return_place, visit_expr (expr));
+    push_assignment (return_place, visit_expr (expr), expr.get_locus ());
     auto final_bb = new_bb ();
     push_goto (final_bb);
 
     ctx.current_bb = short_circuit_bb;
     push_assignment (return_place,
-                    ctx.place_db.get_constant (lookup_type (expr)));
+                    ctx.place_db.get_constant (lookup_type (expr)),
+                    expr.get_locus ());
     push_goto (final_bb);
 
     ctx.current_bb = final_bb;
@@ -62,10 +63,11 @@ protected:
   void visit (HIR::LazyBooleanExpr &expr) override
   {
     auto lhs = visit_expr (*expr.get_lhs ());
-    push_switch (move_place (lhs), {short_circuit_bb});
+    push_switch (move_place (lhs, expr.get_lhs ()->get_locus ()),
+                expr.get_locus (), {short_circuit_bb});
 
     start_new_consecutive_bb ();
-    return_place (visit_expr (*expr.get_rhs ()));
+    return_place (visit_expr (*expr.get_rhs ()), expr.get_locus ());
   }
   void visit (HIR::GroupedExpr &expr) override
   {
@@ -76,15 +78,15 @@ protected:
 public:
   void visit (HIR::QualifiedPathInExpression &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::PathInExpression &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ClosureExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::StructExprStructFields &fields) override
   {
@@ -96,119 +98,119 @@ public:
   }
   void visit (HIR::LiteralExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::BorrowExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::DereferenceExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ErrorPropagationExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::NegationExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ArithmeticOrLogicalExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ComparisonExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::TypeCastExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::AssignmentExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::CompoundAssignmentExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ArrayExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::ArrayIndexExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::TupleExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::TupleIndexExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::CallExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::MethodCallExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::FieldAccessExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::BlockExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::UnsafeBlockExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::LoopExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::WhileLoopExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::WhileLetLoopExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::IfExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::IfExprConseqElse &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::IfLetExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::IfLetExprConseqElse &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::MatchExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::AwaitExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
   void visit (HIR::AsyncBlockExpr &expr) override
   {
-    return_place (ExprStmtBuilder (ctx).build (expr));
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
 
 protected: // Illegal at this position.
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
index f704f77d1ae..32095eb186b 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.h
@@ -65,7 +65,7 @@ public:
   void go (HIR::Pattern &pattern) { pattern.accept_vis (*this); }
 
   void visit_identifier (const Analysis::NodeMapping &node, bool is_ref,
-                        bool is_mut = false)
+                        location_t location, bool is_mut = false)
   {
     if (is_ref)
       {
@@ -82,7 +82,7 @@ public:
 
     if (init.has_value ())
       {
-       push_assignment (translated, init.value ());
+       push_assignment (translated, init.value (), location);
       }
   }
 
@@ -91,7 +91,7 @@ public:
     // Top-level identifiers are resolved directly to avoid useless temporary
     // (for cleaner BIR).
     visit_identifier (pattern.get_mappings (), pattern.get_is_ref (),
-                     pattern.is_mut ());
+                     pattern.get_locus (), pattern.is_mut ());
   }
 
   void visit (HIR::ReferencePattern &pattern) override
@@ -210,6 +210,7 @@ public:
                                                   field_index);
              visit_identifier (ident_field->get_mappings (),
                                ident_field->get_has_ref (),
+                               ident_field->get_locus (),
                                ident_field->is_mut ());
              break;
            }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
index bafa22b4f45..4f7d2b07475 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
@@ -152,7 +152,8 @@ private:
          {
            push_assignment (RETURN_VALUE_PLACE,
                             ctx.place_db.get_constant (
-                              ctx.place_db[RETURN_VALUE_PLACE].tyty));
+                              ctx.place_db[RETURN_VALUE_PLACE].tyty),
+                            body.get_end_locus ());
          }
        ctx.get_current_bb ().statements.emplace_back (Statement::Kind::RETURN);
       }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h 
b/gcc/rust/checks/errors/borrowck/rust-bir.h
index ed190a0973f..0e0ef6643f5 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -77,19 +77,25 @@ private:
   // otherwise: <unused>
   std::unique_ptr<AbstractExpr> expr;
   TyTy::BaseType *type;
+  // stores location of the actual expression from source code
+  // currently only available when kind == Kind::ASSIGNMENT
+  // FIXME: Add location for Statements other than ASSIGNMENT
+  location_t location;
 
 public:
-  Statement (PlaceId lhs, AbstractExpr *rhs)
-    : kind (Kind::ASSIGNMENT), place (lhs), expr (rhs)
+  Statement (PlaceId lhs, AbstractExpr *rhs, location_t location)
+    : kind (Kind::ASSIGNMENT), place (lhs), expr (rhs), location (location)
   {}
 
   explicit Statement (Kind kind, PlaceId place = INVALID_PLACE,
-                     AbstractExpr *expr = nullptr)
-    : kind (kind), place (place), expr (expr)
+                     AbstractExpr *expr = nullptr,
+                     location_t location = UNKNOWN_LOCATION)
+    : kind (kind), place (place), expr (expr), location (location)
   {}
 
-  explicit Statement (Kind kind, PlaceId place, TyTy::BaseType *type)
-    : kind (kind), place (place), type (type)
+  explicit Statement (Kind kind, PlaceId place, TyTy::BaseType *type,
+                     location_t location = UNKNOWN_LOCATION)
+    : kind (kind), place (place), type (type), location (location)
   {}
 
 public:
@@ -97,6 +103,7 @@ public:
   WARN_UNUSED_RESULT PlaceId get_place () const { return place; }
   WARN_UNUSED_RESULT AbstractExpr &get_expr () const { return *expr; }
   WARN_UNUSED_RESULT TyTy::BaseType *get_type () const { return type; }
+  WARN_UNUSED_RESULT location_t get_location () const { return location; }
 };
 
 /** Unique identifier for a basic block in the BIR. */
-- 
2.45.2

Reply via email to