mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-31 12:04:43 +00:00 
			
		
		
		
	
							parent
							
								
									0c1b4838ce
								
							
						
					
					
						commit
						acc4c3339d
					
				
					 9 changed files with 147 additions and 82 deletions
				
			
		|  | @ -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() { | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  | @ -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>) { | 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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,7 +46,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, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -867,10 +867,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) | ||||||
|             } |             } | ||||||
|  | @ -1884,16 +1884,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)?, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -50,6 +50,8 @@ use crate::{ | ||||||
|     utils::ClosureSubst, |     utils::ClosureSubst, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | use super::OperandKind; | ||||||
|  | 
 | ||||||
| mod as_place; | mod as_place; | ||||||
| mod pattern_matching; | 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 { |         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( | ||||||
|  | @ -352,7 +354,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)) => { | ||||||
|  | @ -376,7 +383,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(), | ||||||
|  | @ -482,7 +489,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)) | ||||||
|  | @ -523,7 +530,8 @@ impl<'ctx> MirLowerCtx<'ctx> { | ||||||
|                         self.push_assignment( |                         self.push_assignment( | ||||||
|                             current, |                             current, | ||||||
|                             place, |                             place, | ||||||
|                             Operand::Constant( |                             Rvalue::from(Operand { | ||||||
|  |                                 kind: OperandKind::Constant( | ||||||
|                                     ConstData { |                                     ConstData { | ||||||
|                                         ty, |                                         ty, | ||||||
|                                         value: chalk_ir::ConstValue::BoundVar(BoundVar::new( |                                         value: chalk_ir::ConstValue::BoundVar(BoundVar::new( | ||||||
|  | @ -538,6 +546,8 @@ impl<'ctx> MirLowerCtx<'ctx> { | ||||||
|                                     .intern(Interner), |                                     .intern(Interner), | ||||||
|                                 ) |                                 ) | ||||||
|                                 .into(), |                                 .into(), | ||||||
|  |                                 span: None, | ||||||
|  |                             }), | ||||||
|                             expr_id.into(), |                             expr_id.into(), | ||||||
|                         ); |                         ); | ||||||
|                         Ok(Some(current)) |                         Ok(Some(current)) | ||||||
|  | @ -882,7 +892,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(), | ||||||
|  | @ -984,7 +994,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 { | ||||||
|  | @ -1061,8 +1076,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)); | ||||||
|                 } |                 } | ||||||
|  | @ -1237,9 +1255,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( | ||||||
|  | @ -1481,7 +1501,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( | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  | @ -156,7 +156,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(( | ||||||
|  | @ -306,7 +306,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, | ||||||
|  | @ -366,7 +366,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, | ||||||
|  |  | ||||||
|  | @ -5,10 +5,10 @@ use hir_def::{AssocItemId, hir::ExprId}; | ||||||
| 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, VariantData, VariantId, |             ValueNs, VariantData, 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 { | ||||||
|  | @ -412,8 +423,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, | ||||||
|                     ); |                     ); | ||||||
|  | @ -422,7 +433,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, | ||||||
|  | @ -491,7 +502,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) | ||||||
|  | @ -528,7 +539,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) | ||||||
|  | @ -552,10 +565,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 { | ||||||
|  | @ -588,7 +605,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, | ||||||
|  |  | ||||||
|  | @ -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(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -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 { | ||||||
|  | @ -383,14 +383,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), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 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] |     #[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); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ali Bektas
						Ali Bektas