about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAli Bektas <bektasali@protonmail.com>2025-02-28 00:28:41 +0100
committerAli Bektas <bektasali@protonmail.com>2025-03-19 01:45:51 +0100
commita3c5b6a2dcd7ad57dda3d483aa29f71208f56dd6 (patch)
tree1d3861c95084d2324cbf919bd39d4c700997ac0f
parent835117c64ee38c1c3545ffe5584c8ab0867bacd6 (diff)
downloadrust-a3c5b6a2dcd7ad57dda3d483aa29f71208f56dd6.tar.gz
rust-a3c5b6a2dcd7ad57dda3d483aa29f71208f56dd6.zip
Fix span info for mir::Operand
Fixes #19172
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir.rs23
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs22
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs47
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs19
9 files changed, 147 insertions, 82 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
index 247f0ec429f..43408eb75e2 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -77,7 +77,14 @@ pub struct Local {
 /// currently implements it, but it seems like this may be something to check against in the
 /// validator.
 #[derive(Debug, PartialEq, Eq, Clone)]
-pub enum Operand {
+pub struct Operand {
+    kind: OperandKind,
+    // FIXME : This should actually just be of type `MirSpan`.
+    span: Option<MirSpan>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum OperandKind {
     /// Creates a value by loading the given place.
     ///
     /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
@@ -101,7 +108,13 @@ pub enum Operand {
 
 impl Operand {
     fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap, ty: Ty) -> Self {
-        Operand::Constant(intern_const_scalar(ConstScalar::Bytes(data, memory_map), ty))
+        Operand {
+            kind: OperandKind::Constant(intern_const_scalar(
+                ConstScalar::Bytes(data, memory_map),
+                ty,
+            )),
+            span: None,
+        }
     }
 
     fn from_bytes(data: Box<[u8]>, ty: Ty) -> Self {
@@ -1076,11 +1089,11 @@ impl MirBody {
             f: &mut impl FnMut(&mut Place, &mut ProjectionStore),
             store: &mut ProjectionStore,
         ) {
-            match op {
-                Operand::Copy(p) | Operand::Move(p) => {
+            match &mut op.kind {
+                OperandKind::Copy(p) | OperandKind::Move(p) => {
                     f(p, store);
                 }
-                Operand::Constant(_) | Operand::Static(_) => (),
+                OperandKind::Constant(_) | OperandKind::Static(_) => (),
             }
         }
         for (_, block) in self.basic_blocks.iter_mut() {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
index d9938fc60cd..769510c4253 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
@@ -15,13 +15,13 @@ use crate::{
     ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
     db::{HirDatabase, InternedClosure},
     display::DisplayTarget,
-    mir::Operand,
+    mir::OperandKind,
     utils::ClosureSubst,
 };
 
 use super::{
-    BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Place,
-    ProjectionElem, Rvalue, StatementKind, TerminatorKind,
+    BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Operand,
+    Place, ProjectionElem, Rvalue, StatementKind, TerminatorKind,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -120,8 +120,8 @@ fn make_fetch_closure_field(
 
 fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
     let mut result = vec![];
-    let mut for_operand = |op: &Operand, span: MirSpan| match op {
-        Operand::Copy(p) | Operand::Move(p) => {
+    let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
+        OperandKind::Copy(p) | OperandKind::Move(p) => {
             let mut ty: Ty = body.locals[p.local].ty.clone();
             let mut is_dereference_of_ref = false;
             for proj in p.projection.lookup(&body.projection_store) {
@@ -139,10 +139,10 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
                 && !ty.clone().is_copy(db, body.owner)
                 && !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR)
             {
-                result.push(MovedOutOfRef { span, ty });
+                result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty });
             }
         }
-        Operand::Constant(_) | Operand::Static(_) => (),
+        OperandKind::Constant(_) | OperandKind::Static(_) => (),
     };
     for (_, block) in body.basic_blocks.iter() {
         db.unwind_if_revision_cancelled();
@@ -215,8 +215,8 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
 
 fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved> {
     let mut result = vec![];
-    let mut for_operand = |op: &Operand, span: MirSpan| match op {
-        Operand::Copy(p) | Operand::Move(p) => {
+    let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
+        OperandKind::Copy(p) | OperandKind::Move(p) => {
             let mut ty: Ty = body.locals[p.local].ty.clone();
             for proj in p.projection.lookup(&body.projection_store) {
                 ty = proj.projected_ty(
@@ -232,7 +232,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved>
                 result.push(PartiallyMoved { span, ty, local: p.local });
             }
         }
-        Operand::Constant(_) | Operand::Static(_) => (),
+        OperandKind::Constant(_) | OperandKind::Static(_) => (),
     };
     for (_, block) in body.basic_blocks.iter() {
         db.unwind_if_revision_cancelled();
@@ -500,7 +500,7 @@ fn record_usage(local: LocalId, result: &mut ArenaMap<LocalId, MutabilityReason>
 }
 
 fn record_usage_for_operand(arg: &Operand, result: &mut ArenaMap<LocalId, MutabilityReason>) {
-    if let Operand::Copy(p) | Operand::Move(p) = arg {
+    if let OperandKind::Copy(p) | OperandKind::Move(p) = arg.kind {
         record_usage(p.local, result);
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index ee412dd00b3..00e51ae2057 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -46,7 +46,7 @@ use crate::{
 
 use super::{
     AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan,
-    Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
+    Operand, OperandKind, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
     TerminatorKind, UnOp, return_slot,
 };
 
@@ -867,10 +867,10 @@ impl Evaluator<'_> {
     }
 
     fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> {
-        Ok(match o {
-            Operand::Copy(p) | Operand::Move(p) => self.place_ty(p, locals)?,
-            Operand::Constant(c) => c.data(Interner).ty.clone(),
-            &Operand::Static(s) => {
+        Ok(match &o.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
+            OperandKind::Constant(c) => c.data(Interner).ty.clone(),
+            &OperandKind::Static(s) => {
                 let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone();
                 TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner)
             }
@@ -1884,16 +1884,16 @@ impl Evaluator<'_> {
     }
 
     fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
-        Ok(match it {
-            Operand::Copy(p) | Operand::Move(p) => {
+        Ok(match &it.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => {
                 locals.drop_flags.remove_place(p, &locals.body.projection_store);
                 self.eval_place(p, locals)?
             }
-            Operand::Static(st) => {
+            OperandKind::Static(st) => {
                 let addr = self.eval_static(*st, locals)?;
                 Interval::new(addr, self.ptr_size())
             }
-            Operand::Constant(konst) => self.allocate_const_in_heap(locals, konst)?,
+            OperandKind::Constant(konst) => self.allocate_const_in_heap(locals, konst)?,
         })
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 95c93b5f3ed..9816902fc07 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -50,6 +50,8 @@ use crate::{
     utils::ClosureSubst,
 };
 
+use super::OperandKind;
+
 mod as_place;
 mod pattern_matching;
 
@@ -329,7 +331,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
         let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else {
             return Ok(None);
         };
-        Ok(Some((Operand::Copy(p), current)))
+        Ok(Some((Operand { kind: OperandKind::Copy(p), span: Some(expr_id.into()) }, current)))
     }
 
     fn lower_expr_to_place_with_adjust(
@@ -352,7 +354,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     else {
                         return Ok(None);
                     };
-                    self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
+                    self.push_assignment(
+                        current,
+                        place,
+                        Operand { kind: OperandKind::Copy(p), span: None }.into(),
+                        expr_id.into(),
+                    );
                     Ok(Some(current))
                 }
                 Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => {
@@ -376,7 +383,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         place,
                         Rvalue::Cast(
                             CastKind::PointerCoercion(*cast),
-                            Operand::Copy(p),
+                            Operand { kind: OperandKind::Copy(p), span: None },
                             last.target.clone(),
                         ),
                         expr_id.into(),
@@ -482,7 +489,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         self.push_assignment(
                             current,
                             place,
-                            Operand::Copy(temp).into(),
+                            Operand { kind: OperandKind::Copy(temp), span: None }.into(),
                             expr_id.into(),
                         );
                         Ok(Some(current))
@@ -523,21 +530,24 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         self.push_assignment(
                             current,
                             place,
-                            Operand::Constant(
-                                ConstData {
-                                    ty,
-                                    value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
-                                        DebruijnIndex::INNERMOST,
-                                        generics.type_or_const_param_idx(p.into()).ok_or(
-                                            MirLowerError::TypeError(
-                                                "fail to lower const generic param",
-                                            ),
-                                        )?,
-                                    )),
-                                }
-                                .intern(Interner),
-                            )
-                            .into(),
+                            Rvalue::from(Operand {
+                                kind: OperandKind::Constant(
+                                    ConstData {
+                                        ty,
+                                        value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
+                                            DebruijnIndex::INNERMOST,
+                                            generics.type_or_const_param_idx(p.into()).ok_or(
+                                                MirLowerError::TypeError(
+                                                    "fail to lower const generic param",
+                                                ),
+                                            )?,
+                                        )),
+                                    }
+                                    .intern(Interner),
+                                )
+                                .into(),
+                                span: None,
+                            }),
                             expr_id.into(),
                         );
                         Ok(Some(current))
@@ -882,7 +892,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                                                 })),
                                                 &mut self.result.projection_store,
                                             );
-                                            Operand::Copy(p)
+                                            Operand { kind: OperandKind::Copy(p), span: None }
                                         }
                                     })
                                     .collect(),
@@ -984,7 +994,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
                 else {
                     return Ok(None);
                 };
-                self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());
+                self.push_assignment(
+                    current,
+                    place,
+                    Operand { kind: OperandKind::Copy(p), span: None }.into(),
+                    expr_id.into(),
+                );
                 Ok(Some(current))
             }
             Expr::UnaryOp {
@@ -1061,8 +1076,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     else {
                         return Ok(None);
                     };
-                    let r_value =
-                        Rvalue::CheckedBinaryOp(op.into(), Operand::Copy(lhs_place), rhs_op);
+                    let r_value = Rvalue::CheckedBinaryOp(
+                        op.into(),
+                        Operand { kind: OperandKind::Copy(lhs_place), span: None },
+                        rhs_op,
+                    );
                     self.push_assignment(current, lhs_place, r_value, expr_id.into());
                     return Ok(Some(current));
                 }
@@ -1237,9 +1255,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
                                 Rvalue::Ref(*bk, p),
                                 capture_spans[0],
                             );
-                            operands.push(Operand::Move(tmp));
+                            operands.push(Operand { kind: OperandKind::Move(tmp), span: None });
+                        }
+                        CaptureKind::ByValue => {
+                            operands.push(Operand { kind: OperandKind::Move(p), span: None })
                         }
-                        CaptureKind::ByValue => operands.push(Operand::Move(p)),
                     }
                 }
                 self.push_assignment(
@@ -1481,7 +1501,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                 .const_eval(const_id, subst, None)
                 .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))?
         };
-        Ok(Operand::Constant(c))
+        Ok(Operand { kind: OperandKind::Constant(c), span: None })
     }
 
     fn write_bytes_to_place(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
index 7b0ee22d51f..c2077d669fb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
@@ -1,6 +1,6 @@
 //! MIR lowering for places
 
-use crate::mir::MutBorrowKind;
+use crate::mir::{MutBorrowKind, Operand, OperandKind};
 
 use super::*;
 use hir_def::FunctionId;
@@ -156,7 +156,7 @@ impl MirLowerCtx<'_> {
                         self.push_assignment(
                             current,
                             temp,
-                            Operand::Static(s).into(),
+                            Operand { kind: OperandKind::Static(s), span: None }.into(),
                             expr_id.into(),
                         );
                         Ok(Some((
@@ -306,7 +306,7 @@ impl MirLowerCtx<'_> {
         );
         let Some(current) = self.lower_call(
             index_fn_op,
-            Box::new([Operand::Copy(place), index_operand]),
+            Box::new([Operand { kind: OperandKind::Copy(place), span: None }, index_operand]),
             result,
             current,
             false,
@@ -366,7 +366,7 @@ impl MirLowerCtx<'_> {
         let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
         let Some(current) = self.lower_call(
             deref_fn_op,
-            Box::new([Operand::Copy(ref_place)]),
+            Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]),
             result,
             current,
             false,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index d6b2100253f..7607560bdd1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -5,10 +5,10 @@ use hir_def::{AssocItemId, hir::ExprId};
 use crate::{
     BindingMode,
     mir::{
-        LocalId, MutBorrowKind,
+        LocalId, MutBorrowKind, Operand, OperandKind,
         lower::{
             BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner,
-            MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place,
+            MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Pat, PatId, Place,
             PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
             Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
             ValueNs, VariantData, VariantId,
@@ -217,10 +217,14 @@ impl MirLowerCtx<'_> {
                     self.push_assignment(
                         current,
                         discr,
-                        Rvalue::CheckedBinaryOp(binop, lv, Operand::Copy(cond_place)),
+                        Rvalue::CheckedBinaryOp(
+                            binop,
+                            lv,
+                            Operand { kind: OperandKind::Copy(cond_place), span: None },
+                        ),
                         pattern.into(),
                     );
-                    let discr = Operand::Copy(discr);
+                    let discr = Operand { kind: OperandKind::Copy(discr), span: None };
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
@@ -262,7 +266,10 @@ impl MirLowerCtx<'_> {
                             self.set_terminator(
                                 current,
                                 TerminatorKind::SwitchInt {
-                                    discr: Operand::Copy(place_len),
+                                    discr: Operand {
+                                        kind: OperandKind::Copy(place_len),
+                                        span: None,
+                                    },
                                     targets: SwitchTargets::static_if(
                                         pattern_len as u128,
                                         next,
@@ -282,10 +289,14 @@ impl MirLowerCtx<'_> {
                             self.push_assignment(
                                 current,
                                 discr,
-                                Rvalue::CheckedBinaryOp(BinOp::Le, c, Operand::Copy(place_len)),
+                                Rvalue::CheckedBinaryOp(
+                                    BinOp::Le,
+                                    c,
+                                    Operand { kind: OperandKind::Copy(place_len), span: None },
+                                ),
                                 pattern.into(),
                             );
-                            let discr = Operand::Copy(discr);
+                            let discr = Operand { kind: OperandKind::Copy(discr), span: None };
                             self.set_terminator(
                                 current,
                                 TerminatorKind::SwitchInt {
@@ -412,8 +423,8 @@ impl MirLowerCtx<'_> {
                         tmp2,
                         Rvalue::CheckedBinaryOp(
                             BinOp::Eq,
-                            Operand::Copy(tmp),
-                            Operand::Copy(cond_place),
+                            Operand { kind: OperandKind::Copy(tmp), span: None },
+                            Operand { kind: OperandKind::Copy(cond_place), span: None },
                         ),
                         span,
                     );
@@ -422,7 +433,7 @@ impl MirLowerCtx<'_> {
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
-                            discr: Operand::Copy(tmp2),
+                            discr: Operand { kind: OperandKind::Copy(tmp2), span: None },
                             targets: SwitchTargets::static_if(1, next, else_target),
                         },
                         span,
@@ -491,7 +502,7 @@ impl MirLowerCtx<'_> {
                 self.push_assignment(
                     current,
                     lhs_place,
-                    Operand::Copy(cond_place).into(),
+                    Operand { kind: OperandKind::Copy(cond_place), span: None }.into(),
                     expr.into(),
                 );
                 (current, current_else)
@@ -528,7 +539,9 @@ impl MirLowerCtx<'_> {
             current,
             target_place.into(),
             match mode {
-                BindingMode::Move => Operand::Copy(cond_place).into(),
+                BindingMode::Move => {
+                    Operand { kind: OperandKind::Copy(cond_place), span: None }.into()
+                }
                 BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place),
                 BindingMode::Ref(Mutability::Mut) => {
                     Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place)
@@ -552,10 +565,14 @@ impl MirLowerCtx<'_> {
         self.push_assignment(
             current,
             discr,
-            Rvalue::CheckedBinaryOp(BinOp::Eq, c, Operand::Copy(cond_place)),
+            Rvalue::CheckedBinaryOp(
+                BinOp::Eq,
+                c,
+                Operand { kind: OperandKind::Copy(cond_place), span: None },
+            ),
             pattern.into(),
         );
-        let discr = Operand::Copy(discr);
+        let discr = Operand { kind: OperandKind::Copy(discr), span: None };
         self.set_terminator(
             current,
             TerminatorKind::SwitchInt {
@@ -588,7 +605,7 @@ impl MirLowerCtx<'_> {
                     self.set_terminator(
                         current,
                         TerminatorKind::SwitchInt {
-                            discr: Operand::Copy(tmp),
+                            discr: Operand { kind: OperandKind::Copy(tmp), span: None },
                             targets: SwitchTargets::static_if(e, next, *else_target),
                         },
                         span,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
index c733c7ed845..99be0d57c9a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
@@ -25,7 +25,7 @@ use crate::{
     infer::normalize,
 };
 
-use super::{MirBody, MirLowerError, Operand, Rvalue, StatementKind, TerminatorKind};
+use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, TerminatorKind};
 
 macro_rules! not_supported {
     ($it: expr) => {
@@ -170,8 +170,8 @@ impl Filler<'_> {
     }
 
     fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> {
-        match op {
-            Operand::Constant(c) => {
+        match &mut op.kind {
+            OperandKind::Constant(c) => {
                 match &c.data(Interner).value {
                     chalk_ir::ConstValue::BoundVar(b) => {
                         let resolved = self
@@ -215,7 +215,7 @@ impl Filler<'_> {
                 }
                 self.fill_const(c)?;
             }
-            Operand::Copy(_) | Operand::Move(_) | Operand::Static(_) => (),
+            OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (),
         }
         Ok(())
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index d9c0000fffd..b65cf9dab50 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -18,8 +18,8 @@ use crate::{
 };
 
 use super::{
-    AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, Place,
-    Rvalue, UnOp,
+    AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, OperandKind,
+    Place, Rvalue, UnOp,
 };
 
 macro_rules! w {
@@ -383,14 +383,14 @@ impl<'a> MirPrettyCtx<'a> {
     }
 
     fn operand(&mut self, r: &Operand) {
-        match r {
-            Operand::Copy(p) | Operand::Move(p) => {
+        match &r.kind {
+            OperandKind::Copy(p) | OperandKind::Move(p) => {
                 // MIR at the time of writing doesn't have difference between move and copy, so we show them
                 // equally. Feel free to change it.
                 self.place(p);
             }
-            Operand::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
-            Operand::Static(s) => w!(self, "Static({:?})", s),
+            OperandKind::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
+            OperandKind::Static(s) => w!(self, "Static({:?})", s),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
index 7d0f10983d7..da8eed29b03 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
@@ -18,7 +18,22 @@ pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOf
 mod tests {
     use crate::tests::check_diagnostics;
 
-    // FIXME: spans are broken
+    #[test]
+    fn abc() {
+        check_diagnostics(
+            r#"
+struct NotCopy;
+struct S {
+    field: NotCopy,
+}
+
+fn f(s: &S) -> S {
+    S { field: s.field }
+             //^^^^^^^ error: cannot move `NotCopy` out of reference
+}
+            "#,
+        );
+    }
 
     #[test]
     fn move_by_explicit_deref() {
@@ -85,7 +100,7 @@ fn consume<T>(_: X<T>) {
 fn main() {
     let a = &X(Y);
     consume(*a);
-  //^^^^^^^^^^^ error: cannot move `X<Y>` out of reference
+          //^^ error: cannot move `X<Y>` out of reference
     let a = &X(5);
     consume(*a);
 }