Merge pull request #19247 from alibektas/19172_very_new

fix: Correct span info for mir::Operand
This commit is contained in:
Lukas Wirth 2025-04-30 10:13:02 +00:00 committed by GitHub
commit 1ad31eff67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 146 additions and 82 deletions

View File

@ -77,7 +77,14 @@ pub struct Local {
/// currently implements it, but it seems like this may be something to check against in the /// currently implements it, but it seems like this may be something to check against in the
/// validator. /// validator.
#[derive(Debug, PartialEq, Eq, Clone)] #[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. /// Creates a value by loading the given place.
/// ///
/// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
@ -101,7 +108,13 @@ pub enum Operand {
impl Operand { impl Operand {
fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap, ty: Ty) -> Self { 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 { fn from_bytes(data: Box<[u8]>, ty: Ty) -> Self {
@ -1076,11 +1089,11 @@ impl MirBody {
f: &mut impl FnMut(&mut Place, &mut ProjectionStore), f: &mut impl FnMut(&mut Place, &mut ProjectionStore),
store: &mut ProjectionStore, store: &mut ProjectionStore,
) { ) {
match op { match &mut op.kind {
Operand::Copy(p) | Operand::Move(p) => { OperandKind::Copy(p) | OperandKind::Move(p) => {
f(p, store); f(p, store);
} }
Operand::Constant(_) | Operand::Static(_) => (), OperandKind::Constant(_) | OperandKind::Static(_) => (),
} }
} }
for (_, block) in self.basic_blocks.iter_mut() { for (_, block) in self.basic_blocks.iter_mut() {

View File

@ -15,13 +15,13 @@ use crate::{
ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags, ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
db::{HirDatabase, InternedClosure}, db::{HirDatabase, InternedClosure},
display::DisplayTarget, display::DisplayTarget,
mir::Operand, mir::OperandKind,
utils::ClosureSubst, utils::ClosureSubst,
}; };
use super::{ use super::{
BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Place, BasicBlockId, BorrowKind, LocalId, MirBody, MirLowerError, MirSpan, MutBorrowKind, Operand,
ProjectionElem, Rvalue, StatementKind, TerminatorKind, Place, ProjectionElem, Rvalue, StatementKind, TerminatorKind,
}; };
#[derive(Debug, Clone, PartialEq, Eq)] #[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> { fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
let mut result = vec![]; let mut result = vec![];
let mut for_operand = |op: &Operand, span: MirSpan| match op { let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
Operand::Copy(p) | Operand::Move(p) => { OperandKind::Copy(p) | OperandKind::Move(p) => {
let mut ty: Ty = body.locals[p.local].ty.clone(); let mut ty: Ty = body.locals[p.local].ty.clone();
let mut is_dereference_of_ref = false; let mut is_dereference_of_ref = false;
for proj in p.projection.lookup(&body.projection_store) { 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.clone().is_copy(db, body.owner)
&& !ty.data(Interner).flags.intersects(TypeFlags::HAS_ERROR) && !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() { for (_, block) in body.basic_blocks.iter() {
db.unwind_if_revision_cancelled(); 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> { fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved> {
let mut result = vec![]; let mut result = vec![];
let mut for_operand = |op: &Operand, span: MirSpan| match op { let mut for_operand = |op: &Operand, span: MirSpan| match op.kind {
Operand::Copy(p) | Operand::Move(p) => { OperandKind::Copy(p) | OperandKind::Move(p) => {
let mut ty: Ty = body.locals[p.local].ty.clone(); let mut ty: Ty = body.locals[p.local].ty.clone();
for proj in p.projection.lookup(&body.projection_store) { for proj in p.projection.lookup(&body.projection_store) {
ty = proj.projected_ty( 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 }); result.push(PartiallyMoved { span, ty, local: p.local });
} }
} }
Operand::Constant(_) | Operand::Static(_) => (), OperandKind::Constant(_) | OperandKind::Static(_) => (),
}; };
for (_, block) in body.basic_blocks.iter() { for (_, block) in body.basic_blocks.iter() {
db.unwind_if_revision_cancelled(); db.unwind_if_revision_cancelled();
@ -492,7 +492,7 @@ fn record_usage(local: LocalId, result: &mut ArenaMap<LocalId, MutabilityReason>
} }
fn record_usage_for_operand(arg: &Operand, 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); record_usage(p.local, result);
} }
} }

View File

@ -47,7 +47,7 @@ use crate::{
use super::{ use super::{
AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan, 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, TerminatorKind, UnOp, return_slot,
}; };
@ -856,10 +856,10 @@ impl Evaluator<'_> {
} }
fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> { fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> {
Ok(match o { Ok(match &o.kind {
Operand::Copy(p) | Operand::Move(p) => self.place_ty(p, locals)?, OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
Operand::Constant(c) => c.data(Interner).ty.clone(), OperandKind::Constant(c) => c.data(Interner).ty.clone(),
&Operand::Static(s) => { &OperandKind::Static(s) => {
let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone(); let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone();
TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner) TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner)
} }
@ -1873,16 +1873,16 @@ impl Evaluator<'_> {
} }
fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> { fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
Ok(match it { Ok(match &it.kind {
Operand::Copy(p) | Operand::Move(p) => { OperandKind::Copy(p) | OperandKind::Move(p) => {
locals.drop_flags.remove_place(p, &locals.body.projection_store); locals.drop_flags.remove_place(p, &locals.body.projection_store);
self.eval_place(p, locals)? self.eval_place(p, locals)?
} }
Operand::Static(st) => { OperandKind::Static(st) => {
let addr = self.eval_static(*st, locals)?; let addr = self.eval_static(*st, locals)?;
Interval::new(addr, self.ptr_size()) 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)?,
}) })
} }

View File

@ -48,6 +48,8 @@ use crate::{
utils::ClosureSubst, utils::ClosureSubst,
}; };
use super::OperandKind;
mod as_place; mod as_place;
mod pattern_matching; mod pattern_matching;
@ -324,7 +326,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else { let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else {
return Ok(None); 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( fn lower_expr_to_place_with_adjust(
@ -347,7 +349,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
else { else {
return Ok(None); 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)) Ok(Some(current))
} }
Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => { Adjust::Borrow(AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) => {
@ -371,7 +378,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
place, place,
Rvalue::Cast( Rvalue::Cast(
CastKind::PointerCoercion(*cast), CastKind::PointerCoercion(*cast),
Operand::Copy(p), Operand { kind: OperandKind::Copy(p), span: None },
last.target.clone(), last.target.clone(),
), ),
expr_id.into(), expr_id.into(),
@ -476,7 +483,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.push_assignment( self.push_assignment(
current, current,
place, place,
Operand::Copy(temp).into(), Operand { kind: OperandKind::Copy(temp), span: None }.into(),
expr_id.into(), expr_id.into(),
); );
Ok(Some(current)) Ok(Some(current))
@ -517,21 +524,23 @@ impl<'ctx> MirLowerCtx<'ctx> {
self.push_assignment( self.push_assignment(
current, current,
place, place,
Operand::Constant( Rvalue::from(Operand {
ConstData { kind: OperandKind::Constant(
ty, ConstData {
value: chalk_ir::ConstValue::BoundVar(BoundVar::new( ty,
DebruijnIndex::INNERMOST, value: chalk_ir::ConstValue::BoundVar(BoundVar::new(
generics.type_or_const_param_idx(p.into()).ok_or( DebruijnIndex::INNERMOST,
MirLowerError::TypeError( generics.type_or_const_param_idx(p.into()).ok_or(
"fail to lower const generic param", MirLowerError::TypeError(
), "fail to lower const generic param",
)?, ),
)), )?,
} )),
.intern(Interner), }
) .intern(Interner),
.into(), ),
span: None,
}),
expr_id.into(), expr_id.into(),
); );
Ok(Some(current)) Ok(Some(current))
@ -876,7 +885,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
})), })),
&mut self.result.projection_store, &mut self.result.projection_store,
); );
Operand::Copy(p) Operand { kind: OperandKind::Copy(p), span: None }
} }
}) })
.collect(), .collect(),
@ -979,7 +988,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
else { else {
return Ok(None); 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)) Ok(Some(current))
} }
Expr::UnaryOp { Expr::UnaryOp {
@ -1056,8 +1070,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
else { else {
return Ok(None); return Ok(None);
}; };
let r_value = let r_value = Rvalue::CheckedBinaryOp(
Rvalue::CheckedBinaryOp(op.into(), Operand::Copy(lhs_place), rhs_op); op.into(),
Operand { kind: OperandKind::Copy(lhs_place), span: None },
rhs_op,
);
self.push_assignment(current, lhs_place, r_value, expr_id.into()); self.push_assignment(current, lhs_place, r_value, expr_id.into());
return Ok(Some(current)); return Ok(Some(current));
} }
@ -1232,9 +1249,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
Rvalue::Ref(*bk, p), Rvalue::Ref(*bk, p),
capture_spans[0], 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( self.push_assignment(
@ -1476,7 +1495,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
.const_eval(const_id, subst, None) .const_eval(const_id, subst, None)
.map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))? .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( fn write_bytes_to_place(

View File

@ -1,6 +1,6 @@
//! MIR lowering for places //! MIR lowering for places
use crate::mir::MutBorrowKind; use crate::mir::{MutBorrowKind, Operand, OperandKind};
use super::*; use super::*;
use hir_def::FunctionId; use hir_def::FunctionId;
@ -155,7 +155,7 @@ impl MirLowerCtx<'_> {
self.push_assignment( self.push_assignment(
current, current,
temp, temp,
Operand::Static(s).into(), Operand { kind: OperandKind::Static(s), span: None }.into(),
expr_id.into(), expr_id.into(),
); );
Ok(Some(( Ok(Some((
@ -305,7 +305,7 @@ impl MirLowerCtx<'_> {
); );
let Some(current) = self.lower_call( let Some(current) = self.lower_call(
index_fn_op, index_fn_op,
Box::new([Operand::Copy(place), index_operand]), Box::new([Operand { kind: OperandKind::Copy(place), span: None }, index_operand]),
result, result,
current, current,
false, false,
@ -365,7 +365,7 @@ impl MirLowerCtx<'_> {
let mut result: Place = self.temp(target_ty_ref, current, span)?.into(); let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
let Some(current) = self.lower_call( let Some(current) = self.lower_call(
deref_fn_op, deref_fn_op,
Box::new([Operand::Copy(ref_place)]), Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]),
result, result,
current, current,
false, false,

View File

@ -5,10 +5,10 @@ use hir_def::{AssocItemId, hir::ExprId, signatures::VariantFields};
use crate::{ use crate::{
BindingMode, BindingMode,
mir::{ mir::{
LocalId, MutBorrowKind, LocalId, MutBorrowKind, Operand, OperandKind,
lower::{ lower::{
BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner, 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, PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind, Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
ValueNs, VariantId, ValueNs, VariantId,
@ -217,10 +217,14 @@ impl MirLowerCtx<'_> {
self.push_assignment( self.push_assignment(
current, current,
discr, discr,
Rvalue::CheckedBinaryOp(binop, lv, Operand::Copy(cond_place)), Rvalue::CheckedBinaryOp(
binop,
lv,
Operand { kind: OperandKind::Copy(cond_place), span: None },
),
pattern.into(), pattern.into(),
); );
let discr = Operand::Copy(discr); let discr = Operand { kind: OperandKind::Copy(discr), span: None };
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
@ -262,7 +266,10 @@ impl MirLowerCtx<'_> {
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
discr: Operand::Copy(place_len), discr: Operand {
kind: OperandKind::Copy(place_len),
span: None,
},
targets: SwitchTargets::static_if( targets: SwitchTargets::static_if(
pattern_len as u128, pattern_len as u128,
next, next,
@ -282,10 +289,14 @@ impl MirLowerCtx<'_> {
self.push_assignment( self.push_assignment(
current, current,
discr, 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(), pattern.into(),
); );
let discr = Operand::Copy(discr); let discr = Operand { kind: OperandKind::Copy(discr), span: None };
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
@ -407,8 +418,8 @@ impl MirLowerCtx<'_> {
tmp2, tmp2,
Rvalue::CheckedBinaryOp( Rvalue::CheckedBinaryOp(
BinOp::Eq, BinOp::Eq,
Operand::Copy(tmp), Operand { kind: OperandKind::Copy(tmp), span: None },
Operand::Copy(cond_place), Operand { kind: OperandKind::Copy(cond_place), span: None },
), ),
span, span,
); );
@ -417,7 +428,7 @@ impl MirLowerCtx<'_> {
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
discr: Operand::Copy(tmp2), discr: Operand { kind: OperandKind::Copy(tmp2), span: None },
targets: SwitchTargets::static_if(1, next, else_target), targets: SwitchTargets::static_if(1, next, else_target),
}, },
span, span,
@ -486,7 +497,7 @@ impl MirLowerCtx<'_> {
self.push_assignment( self.push_assignment(
current, current,
lhs_place, lhs_place,
Operand::Copy(cond_place).into(), Operand { kind: OperandKind::Copy(cond_place), span: None }.into(),
expr.into(), expr.into(),
); );
(current, current_else) (current, current_else)
@ -523,7 +534,9 @@ impl MirLowerCtx<'_> {
current, current,
target_place.into(), target_place.into(),
match mode { 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::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place),
BindingMode::Ref(Mutability::Mut) => { BindingMode::Ref(Mutability::Mut) => {
Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place) Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place)
@ -547,10 +560,14 @@ impl MirLowerCtx<'_> {
self.push_assignment( self.push_assignment(
current, current,
discr, 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(), pattern.into(),
); );
let discr = Operand::Copy(discr); let discr = Operand { kind: OperandKind::Copy(discr), span: None };
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
@ -583,7 +600,7 @@ impl MirLowerCtx<'_> {
self.set_terminator( self.set_terminator(
current, current,
TerminatorKind::SwitchInt { TerminatorKind::SwitchInt {
discr: Operand::Copy(tmp), discr: Operand { kind: OperandKind::Copy(tmp), span: None },
targets: SwitchTargets::static_if(e, next, *else_target), targets: SwitchTargets::static_if(e, next, *else_target),
}, },
span, span,

View File

@ -25,7 +25,7 @@ use crate::{
infer::normalize, infer::normalize,
}; };
use super::{MirBody, MirLowerError, Operand, Rvalue, StatementKind, TerminatorKind}; use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, TerminatorKind};
macro_rules! not_supported { macro_rules! not_supported {
($it: expr) => { ($it: expr) => {
@ -170,8 +170,8 @@ impl Filler<'_> {
} }
fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> { fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> {
match op { match &mut op.kind {
Operand::Constant(c) => { OperandKind::Constant(c) => {
match &c.data(Interner).value { match &c.data(Interner).value {
chalk_ir::ConstValue::BoundVar(b) => { chalk_ir::ConstValue::BoundVar(b) => {
let resolved = self let resolved = self
@ -215,7 +215,7 @@ impl Filler<'_> {
} }
self.fill_const(c)?; self.fill_const(c)?;
} }
Operand::Copy(_) | Operand::Move(_) | Operand::Static(_) => (), OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (),
} }
Ok(()) Ok(())
} }

View File

@ -18,8 +18,8 @@ use crate::{
}; };
use super::{ use super::{
AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, Place, AggregateKind, BasicBlockId, BorrowKind, LocalId, MirBody, MutBorrowKind, Operand, OperandKind,
Rvalue, UnOp, Place, Rvalue, UnOp,
}; };
macro_rules! w { macro_rules! w {
@ -374,14 +374,14 @@ impl<'a> MirPrettyCtx<'a> {
} }
fn operand(&mut self, r: &Operand) { fn operand(&mut self, r: &Operand) {
match r { match &r.kind {
Operand::Copy(p) | Operand::Move(p) => { OperandKind::Copy(p) | OperandKind::Move(p) => {
// MIR at the time of writing doesn't have difference between move and copy, so we show them // MIR at the time of writing doesn't have difference between move and copy, so we show them
// equally. Feel free to change it. // equally. Feel free to change it.
self.place(p); self.place(p);
} }
Operand::Constant(c) => w!(self, "Const({})", self.hir_display(c)), OperandKind::Constant(c) => w!(self, "Const({})", self.hir_display(c)),
Operand::Static(s) => w!(self, "Static({:?})", s), OperandKind::Static(s) => w!(self, "Static({:?})", s),
} }
} }

View File

@ -18,7 +18,22 @@ pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOf
mod tests { mod tests {
use crate::tests::check_diagnostics; use crate::tests::check_diagnostics;
// FIXME: spans are broken #[test]
fn operand_field_span_respected() {
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] #[test]
fn move_by_explicit_deref() { fn move_by_explicit_deref() {
@ -85,7 +100,7 @@ fn consume<T>(_: X<T>) {
fn main() { fn main() {
let a = &X(Y); let a = &X(Y);
consume(*a); consume(*a);
//^^^^^^^^^^^ error: cannot move `X<Y>` out of reference //^^ error: cannot move `X<Y>` out of reference
let a = &X(5); let a = &X(5);
consume(*a); consume(*a);
} }