mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Use Place directly, it's Copy even more use cases
This commit is contained in:
parent
25528c1e28
commit
890b39381f
@ -396,8 +396,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
);
|
||||
self.suggest_split_at_mut_if_applicable(
|
||||
&mut err,
|
||||
&place,
|
||||
&issued_borrow.borrowed_place,
|
||||
place,
|
||||
issued_borrow.borrowed_place,
|
||||
);
|
||||
err
|
||||
}
|
||||
@ -410,7 +410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
(BorrowKind::Mut { .. }, BorrowKind::Shallow)
|
||||
| (BorrowKind::Unique, BorrowKind::Shallow) => {
|
||||
if let Some(immutable_section_description) =
|
||||
self.classify_immutable_section(&issued_borrow.assigned_place)
|
||||
self.classify_immutable_section(issued_borrow.assigned_place)
|
||||
{
|
||||
let mut err = self.cannot_mutate_in_immutable_section(
|
||||
span,
|
||||
@ -546,8 +546,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
fn suggest_split_at_mut_if_applicable(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
place: &Place<'tcx>,
|
||||
borrowed_place: &Place<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
borrowed_place: Place<'tcx>,
|
||||
) {
|
||||
if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) =
|
||||
(&place.projection[..], &borrowed_place.projection[..])
|
||||
@ -1382,7 +1382,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
|
||||
let descr_place = self.describe_any_place(place.as_ref());
|
||||
if loan.kind == BorrowKind::Shallow {
|
||||
if let Some(section) = self.classify_immutable_section(&loan.assigned_place) {
|
||||
if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
|
||||
let mut err = self.cannot_mutate_in_immutable_section(
|
||||
span,
|
||||
loan_span,
|
||||
@ -1534,17 +1534,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Describe the reason for the fake borrow that was assigned to `place`.
|
||||
fn classify_immutable_section(&self, place: &Place<'tcx>) -> Option<&'static str> {
|
||||
fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str> {
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
struct FakeReadCauseFinder<'a, 'tcx> {
|
||||
place: &'a Place<'tcx>,
|
||||
struct FakeReadCauseFinder<'tcx> {
|
||||
place: Place<'tcx>,
|
||||
cause: Option<FakeReadCause>,
|
||||
}
|
||||
impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> {
|
||||
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
|
||||
match statement {
|
||||
Statement { kind: StatementKind::FakeRead(cause, box ref place), .. }
|
||||
if *place == *self.place =>
|
||||
Statement { kind: StatementKind::FakeRead(cause, box place), .. }
|
||||
if *place == self.place =>
|
||||
{
|
||||
self.cause = Some(*cause);
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
// whether or not the right-hand side is a place expression
|
||||
if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
VarBindingForm {
|
||||
opt_match_place: Some((ref opt_match_place, match_span)),
|
||||
opt_match_place: Some((opt_match_place, match_span)),
|
||||
binding_mode: _,
|
||||
opt_ty_info: _,
|
||||
pat_span: _,
|
||||
@ -117,7 +117,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
grouped_errors,
|
||||
kind,
|
||||
original_path,
|
||||
move_from,
|
||||
*move_from,
|
||||
local,
|
||||
opt_match_place,
|
||||
match_span,
|
||||
@ -143,16 +143,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
|
||||
kind: IllegalMoveOriginKind<'tcx>,
|
||||
original_path: Place<'tcx>,
|
||||
move_from: &Place<'tcx>,
|
||||
move_from: Place<'tcx>,
|
||||
bind_to: Local,
|
||||
match_place: &Option<Place<'tcx>>,
|
||||
match_place: Option<Place<'tcx>>,
|
||||
match_span: Span,
|
||||
statement_span: Span,
|
||||
) {
|
||||
debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span);
|
||||
|
||||
let from_simple_let = match_place.is_none();
|
||||
let match_place = match_place.as_ref().unwrap_or(move_from);
|
||||
let match_place = match_place.unwrap_or(move_from);
|
||||
|
||||
match self.move_data.rev_lookup.find(match_place.as_ref()) {
|
||||
// Error with the match place
|
||||
@ -178,7 +178,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
};
|
||||
grouped_errors.push(GroupedMoveError::MovesFromPlace {
|
||||
span,
|
||||
move_from: *match_place,
|
||||
move_from,
|
||||
original_path,
|
||||
kind,
|
||||
binds_to,
|
||||
@ -223,14 +223,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let (span, use_spans, original_path, kind): (
|
||||
Span,
|
||||
Option<UseSpans>,
|
||||
&Place<'tcx>,
|
||||
Place<'tcx>,
|
||||
&IllegalMoveOriginKind<'_>,
|
||||
) = match error {
|
||||
GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. }
|
||||
| GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
|
||||
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
|
||||
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
|
||||
(span, None, original_path, kind)
|
||||
}
|
||||
GroupedMoveError::OtherIllegalMove { use_spans, ref original_path, ref kind } => {
|
||||
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
|
||||
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
|
||||
}
|
||||
};
|
||||
@ -247,7 +247,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
IllegalMoveOriginKind::BorrowedContent { target_place } => self
|
||||
.report_cannot_move_from_borrowed_content(
|
||||
original_path,
|
||||
target_place,
|
||||
*target_place,
|
||||
span,
|
||||
use_spans,
|
||||
),
|
||||
@ -268,7 +268,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
fn report_cannot_move_from_static(
|
||||
&mut self,
|
||||
place: &Place<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
let description = if place.projection.len() == 1 {
|
||||
@ -288,8 +288,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
fn report_cannot_move_from_borrowed_content(
|
||||
&mut self,
|
||||
move_place: &Place<'tcx>,
|
||||
deref_target_place: &Place<'tcx>,
|
||||
move_place: Place<'tcx>,
|
||||
deref_target_place: Place<'tcx>,
|
||||
span: Span,
|
||||
use_spans: Option<UseSpans>,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
|
@ -160,13 +160,13 @@ where
|
||||
|
||||
match rvalue {
|
||||
mir::Rvalue::AddressOf(mt, borrowed_place) => {
|
||||
if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, borrowed_place) {
|
||||
if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) {
|
||||
self.trans.gen(borrowed_place.local);
|
||||
}
|
||||
}
|
||||
|
||||
mir::Rvalue::Ref(_, kind, borrowed_place) => {
|
||||
if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, borrowed_place) {
|
||||
if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) {
|
||||
self.trans.gen(borrowed_place.local);
|
||||
}
|
||||
}
|
||||
@ -230,7 +230,7 @@ impl MutBorrow<'mir, 'tcx> {
|
||||
/// below. See [rust-lang/unsafe-code-guidelines#134].
|
||||
///
|
||||
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
|
||||
fn shared_borrow_allows_mutation(&self, place: &Place<'tcx>) -> bool {
|
||||
fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
|
||||
!place.ty(self.body, self.tcx).ty.is_freeze(self.tcx, self.param_env, DUMMY_SP)
|
||||
}
|
||||
}
|
||||
@ -238,17 +238,17 @@ impl MutBorrow<'mir, 'tcx> {
|
||||
pub trait BorrowAnalysisKind<'tcx> {
|
||||
const ANALYSIS_NAME: &'static str;
|
||||
|
||||
fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool;
|
||||
fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool;
|
||||
fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool;
|
||||
fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool;
|
||||
}
|
||||
|
||||
impl BorrowAnalysisKind<'tcx> for AnyBorrow {
|
||||
const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals";
|
||||
|
||||
fn in_ref(&self, _: mir::BorrowKind, _: &Place<'_>) -> bool {
|
||||
fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool {
|
||||
true
|
||||
}
|
||||
fn in_address_of(&self, _: Mutability, _: &Place<'_>) -> bool {
|
||||
fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -256,7 +256,7 @@ impl BorrowAnalysisKind<'tcx> for AnyBorrow {
|
||||
impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
|
||||
const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals";
|
||||
|
||||
fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool {
|
||||
fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool {
|
||||
match kind {
|
||||
mir::BorrowKind::Mut { .. } => true,
|
||||
mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => {
|
||||
@ -265,7 +265,7 @@ impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool {
|
||||
fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool {
|
||||
match mt {
|
||||
Mutability::Mut => true,
|
||||
Mutability::Not => self.shared_borrow_allows_mutation(place),
|
||||
|
@ -94,7 +94,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
/// problematic for borrowck.
|
||||
///
|
||||
/// Maybe we should have separate "borrowck" and "moveck" modes.
|
||||
fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
|
||||
fn move_path_for(&mut self, place: Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
|
||||
debug!("lookup({:?})", place);
|
||||
let mut base = self.builder.data.rev_lookup.locals[place.local];
|
||||
|
||||
@ -195,7 +195,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn create_move_path(&mut self, place: &Place<'tcx>) {
|
||||
fn create_move_path(&mut self, place: Place<'tcx>) {
|
||||
// This is an non-moving access (such as an overwrite or
|
||||
// drop), so this not being a valid move path is OK.
|
||||
let _ = self.move_path_for(place);
|
||||
@ -279,22 +279,22 @@ struct Gatherer<'b, 'a, 'tcx> {
|
||||
|
||||
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(box (ref place, ref rval)) => {
|
||||
self.create_move_path(place);
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place, rval)) => {
|
||||
self.create_move_path(*place);
|
||||
if let RvalueInitializationState::Shallow = rval.initialization_state() {
|
||||
// Box starts out uninitialized - need to create a separate
|
||||
// move-path for the interior so it will be separate from
|
||||
// the exterior.
|
||||
self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone()));
|
||||
self.create_move_path(self.builder.tcx.mk_place_deref(place.clone()));
|
||||
self.gather_init(place.as_ref(), InitKind::Shallow);
|
||||
} else {
|
||||
self.gather_init(place.as_ref(), InitKind::Deep);
|
||||
}
|
||||
self.gather_rvalue(rval);
|
||||
}
|
||||
StatementKind::FakeRead(_, ref place) => {
|
||||
self.create_move_path(place);
|
||||
StatementKind::FakeRead(_, place) => {
|
||||
self.create_move_path(**place);
|
||||
}
|
||||
StatementKind::LlvmInlineAsm(ref asm) => {
|
||||
for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
|
||||
@ -308,7 +308,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
}
|
||||
StatementKind::StorageLive(_) => {}
|
||||
StatementKind::StorageDead(local) => {
|
||||
self.gather_move(&Place::from(local));
|
||||
self.gather_move(Place::from(*local));
|
||||
}
|
||||
StatementKind::SetDiscriminant { .. } => {
|
||||
span_bug!(
|
||||
@ -369,7 +369,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
| TerminatorKind::Unreachable => {}
|
||||
|
||||
TerminatorKind::Return => {
|
||||
self.gather_move(&Place::return_place());
|
||||
self.gather_move(Place::return_place());
|
||||
}
|
||||
|
||||
TerminatorKind::Assert { ref cond, .. } => {
|
||||
@ -380,16 +380,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
self.gather_operand(discr);
|
||||
}
|
||||
|
||||
TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => {
|
||||
TerminatorKind::Yield { ref value, resume_arg: place, .. } => {
|
||||
self.gather_operand(value);
|
||||
self.create_move_path(place);
|
||||
self.gather_init(place.as_ref(), InitKind::Deep);
|
||||
}
|
||||
|
||||
TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
|
||||
TerminatorKind::Drop { location, target: _, unwind: _ } => {
|
||||
self.gather_move(location);
|
||||
}
|
||||
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
|
||||
TerminatorKind::DropAndReplace { location, ref value, .. } => {
|
||||
self.create_move_path(location);
|
||||
self.gather_operand(value);
|
||||
self.gather_init(location.as_ref(), InitKind::Deep);
|
||||
@ -405,7 +405,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
for arg in args {
|
||||
self.gather_operand(arg);
|
||||
}
|
||||
if let Some((ref destination, _bb)) = *destination {
|
||||
if let Some((destination, _bb)) = *destination {
|
||||
self.create_move_path(destination);
|
||||
self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
|
||||
}
|
||||
@ -416,14 +416,14 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
fn gather_operand(&mut self, operand: &Operand<'tcx>) {
|
||||
match *operand {
|
||||
Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
|
||||
Operand::Move(ref place) => {
|
||||
Operand::Move(place) => {
|
||||
// a move
|
||||
self.gather_move(place);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_move(&mut self, place: &Place<'tcx>) {
|
||||
fn gather_move(&mut self, place: Place<'tcx>) {
|
||||
debug!("gather_move({:?}, {:?})", self.loc, place);
|
||||
|
||||
if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] =
|
||||
@ -434,7 +434,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
// are disjoint, which is expected by drop elaboration.
|
||||
let base_place =
|
||||
Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) };
|
||||
let base_path = match self.move_path_for(&base_place) {
|
||||
let base_path = match self.move_path_for(base_place) {
|
||||
Ok(path) => path,
|
||||
Err(MoveError::UnionMove { path }) => {
|
||||
self.record_move(place, path);
|
||||
@ -467,13 +467,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
match self.move_path_for(place) {
|
||||
Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path),
|
||||
Err(error @ MoveError::IllegalMove { .. }) => {
|
||||
self.builder.errors.push((*place, error));
|
||||
self.builder.errors.push((place, error));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn record_move(&mut self, place: &Place<'tcx>, path: MovePathIndex) {
|
||||
fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
|
||||
let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc });
|
||||
debug!(
|
||||
"gather_move({:?}, {:?}): adding move {:?} of {:?}",
|
||||
|
@ -464,7 +464,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// avoid allocations.
|
||||
pub fn eval_place_to_op(
|
||||
&self,
|
||||
place: &mir::Place<'tcx>,
|
||||
place: mir::Place<'tcx>,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||
let base_op = match place.local {
|
||||
@ -498,7 +498,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
use rustc_middle::mir::Operand::*;
|
||||
let op = match *mir_op {
|
||||
// FIXME: do some more logic on `move` to invalidate the old location
|
||||
Copy(ref place) | Move(ref place) => self.eval_place_to_op(place, layout)?,
|
||||
Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?,
|
||||
|
||||
Constant(ref constant) => {
|
||||
let val =
|
||||
|
@ -635,7 +635,7 @@ where
|
||||
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
|
||||
pub fn eval_place(
|
||||
&mut self,
|
||||
place: &mir::Place<'tcx>,
|
||||
place: mir::Place<'tcx>,
|
||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||
let mut place_ty = match place.local {
|
||||
mir::RETURN_PLACE => {
|
||||
|
@ -87,23 +87,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.tcx.span = stmt.source_info.span;
|
||||
self.memory.tcx.span = stmt.source_info.span;
|
||||
|
||||
match stmt.kind {
|
||||
Assign(box (ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?,
|
||||
match &stmt.kind {
|
||||
Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
|
||||
|
||||
SetDiscriminant { ref place, variant_index } => {
|
||||
let dest = self.eval_place(place)?;
|
||||
self.write_discriminant_index(variant_index, dest)?;
|
||||
SetDiscriminant { place, variant_index } => {
|
||||
let dest = self.eval_place(**place)?;
|
||||
self.write_discriminant_index(*variant_index, dest)?;
|
||||
}
|
||||
|
||||
// Mark locals as alive
|
||||
StorageLive(local) => {
|
||||
let old_val = self.storage_live(local)?;
|
||||
let old_val = self.storage_live(*local)?;
|
||||
self.deallocate_local(old_val)?;
|
||||
}
|
||||
|
||||
// Mark locals as dead
|
||||
StorageDead(local) => {
|
||||
let old_val = self.storage_dead(local);
|
||||
let old_val = self.storage_dead(*local);
|
||||
self.deallocate_local(old_val)?;
|
||||
}
|
||||
|
||||
@ -112,9 +112,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
FakeRead(..) => {}
|
||||
|
||||
// Stacked Borrows.
|
||||
Retag(kind, ref place) => {
|
||||
let dest = self.eval_place(place)?;
|
||||
M::retag(self, kind, dest)?;
|
||||
Retag(kind, place) => {
|
||||
let dest = self.eval_place(**place)?;
|
||||
M::retag(self, *kind, dest)?;
|
||||
}
|
||||
|
||||
// Statements we do not track.
|
||||
@ -138,7 +138,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
pub fn eval_rvalue_into_place(
|
||||
&mut self,
|
||||
rvalue: &mir::Rvalue<'tcx>,
|
||||
place: &mir::Place<'tcx>,
|
||||
place: mir::Place<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let dest = self.eval_place(place)?;
|
||||
|
||||
@ -224,7 +224,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
Len(ref place) => {
|
||||
Len(place) => {
|
||||
// FIXME(CTFE): don't allow computing the length of arrays in const eval
|
||||
let src = self.eval_place(place)?;
|
||||
let mplace = self.force_allocation(src)?;
|
||||
@ -232,7 +232,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.write_scalar(Scalar::from_machine_usize(len, self), dest)?;
|
||||
}
|
||||
|
||||
AddressOf(_, ref place) | Ref(_, _, ref place) => {
|
||||
AddressOf(_, place) | Ref(_, _, place) => {
|
||||
let src = self.eval_place(place)?;
|
||||
let place = self.force_allocation(src)?;
|
||||
if place.layout.size.bytes() > 0 {
|
||||
@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.cast(src, kind, dest)?;
|
||||
}
|
||||
|
||||
Discriminant(ref place) => {
|
||||
Discriminant(place) => {
|
||||
let op = self.eval_place_to_op(place, None)?;
|
||||
let discr_val = self.read_discriminant(op)?.0;
|
||||
let size = dest.layout.size;
|
||||
|
@ -51,7 +51,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.go_to_block(target_block);
|
||||
}
|
||||
|
||||
Call { ref func, ref args, ref destination, ref cleanup, .. } => {
|
||||
Call { ref func, ref args, destination, ref cleanup, .. } => {
|
||||
let func = self.eval_operand(func, None)?;
|
||||
let (fn_val, abi) = match func.layout.ty.kind {
|
||||
ty::FnPtr(sig) => {
|
||||
@ -68,7 +68,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
};
|
||||
let args = self.eval_operands(args)?;
|
||||
let ret = match destination {
|
||||
Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)),
|
||||
Some((dest, ret)) => Some((self.eval_place(dest)?, ret)),
|
||||
None => None,
|
||||
};
|
||||
self.eval_fn_call(
|
||||
@ -81,7 +81,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
)?;
|
||||
}
|
||||
|
||||
Drop { ref location, target, unwind } => {
|
||||
Drop { location, target, unwind } => {
|
||||
// FIXME(CTFE): forbid drop in const eval
|
||||
let place = self.eval_place(location)?;
|
||||
let ty = place.layout.ty;
|
||||
@ -328,7 +328,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// `pass_argument` would be the loop body. It takes care to
|
||||
// not advance `caller_iter` for ZSTs.
|
||||
for local in body.args_iter() {
|
||||
let dest = self.eval_place(&mir::Place::from(local))?;
|
||||
let dest = self.eval_place(mir::Place::from(local))?;
|
||||
if Some(local) == body.spread_arg {
|
||||
// Must be a tuple
|
||||
for i in 0..dest.layout.fields.count() {
|
||||
@ -346,7 +346,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
}
|
||||
// Don't forget to check the return type!
|
||||
if let Some((caller_ret, _)) = ret {
|
||||
let callee_ret = self.eval_place(&mir::Place::return_place())?;
|
||||
let callee_ret = self.eval_place(mir::Place::return_place())?;
|
||||
if !Self::check_argument_compat(
|
||||
rust_abi,
|
||||
caller_ret.layout,
|
||||
|
@ -68,7 +68,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(
|
||||
let terminator = data.terminator();
|
||||
|
||||
match terminator.kind {
|
||||
TerminatorKind::Drop { ref location, .. }
|
||||
TerminatorKind::Drop { location, .. }
|
||||
if util::is_disaligned(tcx, body, param_env, location) =>
|
||||
{
|
||||
add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup);
|
||||
|
@ -191,7 +191,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
let proj_base = &place.projection[..i];
|
||||
|
||||
if context.is_borrow() {
|
||||
if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
|
||||
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
|
||||
let source_info = self.source_info;
|
||||
let lint_root = self.body.source_scopes[source_info.scope]
|
||||
.local_data
|
||||
|
@ -471,7 +471,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_place(&mut self, place: &Place<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
trace!("eval_place(place={:?})", place);
|
||||
self.use_ecx(|this| this.ecx.eval_place_to_op(place, None))
|
||||
}
|
||||
@ -479,7 +479,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
|
||||
match *op {
|
||||
Operand::Constant(ref c) => self.eval_constant(c, source_info),
|
||||
Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place),
|
||||
Operand::Move(place) | Operand::Copy(place) => self.eval_place(place),
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,7 +575,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
place_layout: TyAndLayout<'tcx>,
|
||||
source_info: SourceInfo,
|
||||
place: &Place<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
) -> Option<()> {
|
||||
// #66397: Don't try to eval into large places as that can cause an OOM
|
||||
if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
|
||||
@ -828,7 +828,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
||||
trace!("visit_statement: {:?}", statement);
|
||||
let source_info = statement.source_info;
|
||||
self.source_info = Some(source_info);
|
||||
if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind {
|
||||
if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind {
|
||||
let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty;
|
||||
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
|
||||
if let Some(local) = place.as_local() {
|
||||
|
@ -97,9 +97,8 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
|
||||
if let Some(local) = place.as_local() {
|
||||
if local == dest_local {
|
||||
let maybe_action = match operand {
|
||||
Operand::Copy(ref src_place)
|
||||
| Operand::Move(ref src_place) => {
|
||||
Action::local_copy(&body, &def_use_analysis, src_place)
|
||||
Operand::Copy(src_place) | Operand::Move(src_place) => {
|
||||
Action::local_copy(&body, &def_use_analysis, *src_place)
|
||||
}
|
||||
Operand::Constant(ref src_constant) => {
|
||||
Action::constant(src_constant)
|
||||
@ -195,7 +194,7 @@ impl<'tcx> Action<'tcx> {
|
||||
fn local_copy(
|
||||
body: &Body<'tcx>,
|
||||
def_use_analysis: &DefUseAnalysis,
|
||||
src_place: &Place<'tcx>,
|
||||
src_place: Place<'tcx>,
|
||||
) -> Option<Action<'tcx>> {
|
||||
// The source must be a local.
|
||||
let src_local = if let Some(local) = src_place.as_local() {
|
||||
|
@ -450,7 +450,7 @@ impl Inliner<'tcx> {
|
||||
// Place could result in two different locations if `f`
|
||||
// writes to `i`. To prevent this we need to create a temporary
|
||||
// borrow of the place and pass the destination as `*temp` instead.
|
||||
fn dest_needs_borrow(place: &Place<'_>) -> bool {
|
||||
fn dest_needs_borrow(place: Place<'_>) -> bool {
|
||||
for elem in place.projection.iter() {
|
||||
match elem {
|
||||
ProjectionElem::Deref | ProjectionElem::Index(_) => return true,
|
||||
@ -461,7 +461,7 @@ impl Inliner<'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
let dest = if dest_needs_borrow(&destination.0) {
|
||||
let dest = if dest_needs_borrow(destination.0) {
|
||||
debug!("creating temp for return destination");
|
||||
let dest = Rvalue::Ref(
|
||||
self.tcx.lifetimes.re_erased,
|
||||
|
@ -150,7 +150,7 @@ fn check_rvalue(
|
||||
Rvalue::Len(place)
|
||||
| Rvalue::Discriminant(place)
|
||||
| Rvalue::Ref(_, _, place)
|
||||
| Rvalue::AddressOf(_, place) => check_place(tcx, place, span, def_id, body),
|
||||
| Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body),
|
||||
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
|
||||
use rustc_middle::ty::cast::CastTy;
|
||||
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
|
||||
@ -215,7 +215,7 @@ fn check_statement(
|
||||
let span = statement.source_info.span;
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(box (place, rval)) => {
|
||||
check_place(tcx, place, span, def_id, body)?;
|
||||
check_place(tcx, *place, span, def_id, body)?;
|
||||
check_rvalue(tcx, body, def_id, rval, span)
|
||||
}
|
||||
|
||||
@ -225,10 +225,12 @@ fn check_statement(
|
||||
Err((span, "loops and conditional expressions are not stable in const fn".into()))
|
||||
}
|
||||
|
||||
StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
|
||||
StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body),
|
||||
|
||||
// just an assignment
|
||||
StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body),
|
||||
StatementKind::SetDiscriminant { place, .. } => {
|
||||
check_place(tcx, **place, span, def_id, body)
|
||||
}
|
||||
|
||||
StatementKind::LlvmInlineAsm { .. } => {
|
||||
Err((span, "cannot use inline assembly in const fn".into()))
|
||||
@ -251,7 +253,7 @@ fn check_operand(
|
||||
body: &Body<'tcx>,
|
||||
) -> McfResult {
|
||||
match operand {
|
||||
Operand::Move(place) | Operand::Copy(place) => check_place(tcx, place, span, def_id, body),
|
||||
Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body),
|
||||
Operand::Constant(c) => match c.check_static_ptr(tcx) {
|
||||
Some(_) => Err((span, "cannot access `static` items in const fn".into())),
|
||||
None => Ok(()),
|
||||
@ -261,7 +263,7 @@ fn check_operand(
|
||||
|
||||
fn check_place(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
span: Span,
|
||||
def_id: DefId,
|
||||
body: &Body<'tcx>,
|
||||
@ -330,9 +332,9 @@ fn check_terminator(
|
||||
| TerminatorKind::Return
|
||||
| TerminatorKind::Resume => Ok(()),
|
||||
|
||||
TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body),
|
||||
TerminatorKind::Drop { location, .. } => check_place(tcx, *location, span, def_id, body),
|
||||
TerminatorKind::DropAndReplace { location, value, .. } => {
|
||||
check_place(tcx, location, span, def_id, body)?;
|
||||
check_place(tcx, *location, span, def_id, body)?;
|
||||
check_operand(tcx, value, span, def_id, body)
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
|
||||
StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
|
||||
Rvalue::Use(Operand::Copy(pf)) | Rvalue::Use(Operand::Move(pf)) => {
|
||||
let local_into = place_into.as_local()?;
|
||||
let (local_from, vf) = match_variant_field_place(&pf)?;
|
||||
let (local_from, vf) = match_variant_field_place(*pf)?;
|
||||
Some((local_into, local_from, vf))
|
||||
}
|
||||
_ => None,
|
||||
@ -107,7 +107,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
|
||||
StatementKind::Assign(box (place_from, rvalue_into)) => match rvalue_into {
|
||||
Rvalue::Use(Operand::Move(place_into)) => {
|
||||
let local_into = place_into.as_local()?;
|
||||
let (local_from, vf) = match_variant_field_place(&place_from)?;
|
||||
let (local_from, vf) = match_variant_field_place(*place_from)?;
|
||||
Some((local_into, local_from, vf))
|
||||
}
|
||||
_ => None,
|
||||
@ -137,7 +137,7 @@ struct VarField<'tcx> {
|
||||
}
|
||||
|
||||
/// Match on `((_LOCAL as Variant).FIELD: TY)`.
|
||||
fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
|
||||
fn match_variant_field_place<'tcx>(place: Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
|
||||
match place.as_ref() {
|
||||
PlaceRef {
|
||||
local,
|
||||
|
@ -8,7 +8,7 @@ pub fn is_disaligned<'tcx, L>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
local_decls: &L,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
place: Place<'tcx>,
|
||||
) -> bool
|
||||
where
|
||||
L: HasLocalDecls<'tcx>,
|
||||
@ -34,7 +34,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'tcx>) -> bool
|
||||
fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool
|
||||
where
|
||||
L: HasLocalDecls<'tcx>,
|
||||
{
|
||||
|
@ -526,7 +526,7 @@ where
|
||||
let discr = Place::from(self.new_temp(discr_ty));
|
||||
let discr_rv = Rvalue::Discriminant(self.place);
|
||||
let switch_block = BasicBlockData {
|
||||
statements: vec![self.assign(&discr, discr_rv)],
|
||||
statements: vec![self.assign(discr, discr_rv)],
|
||||
terminator: Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::SwitchInt {
|
||||
@ -557,7 +557,7 @@ where
|
||||
|
||||
let result = BasicBlockData {
|
||||
statements: vec![self.assign(
|
||||
&Place::from(ref_place),
|
||||
Place::from(ref_place),
|
||||
Rvalue::Ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
BorrowKind::Mut { allow_two_phase_borrow: false },
|
||||
@ -604,7 +604,7 @@ where
|
||||
&mut self,
|
||||
succ: BasicBlock,
|
||||
cur: Local,
|
||||
length_or_end: &Place<'tcx>,
|
||||
length_or_end: Place<'tcx>,
|
||||
ety: Ty<'tcx>,
|
||||
unwind: Unwind,
|
||||
ptr_based: bool,
|
||||
@ -614,7 +614,7 @@ where
|
||||
let tcx = self.tcx();
|
||||
|
||||
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
|
||||
let ptr = &Place::from(self.new_temp(ptr_ty));
|
||||
let ptr = Place::from(self.new_temp(ptr_ty));
|
||||
let can_go = Place::from(self.new_temp(tcx.types.bool));
|
||||
|
||||
let one = self.constant_usize(1);
|
||||
@ -628,7 +628,7 @@ where
|
||||
};
|
||||
|
||||
let drop_block = BasicBlockData {
|
||||
statements: vec![self.assign(ptr, ptr_next), self.assign(&Place::from(cur), cur_next)],
|
||||
statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
|
||||
is_cleanup: unwind.is_cleanup(),
|
||||
terminator: Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
@ -640,8 +640,8 @@ where
|
||||
|
||||
let loop_block = BasicBlockData {
|
||||
statements: vec![self.assign(
|
||||
&can_go,
|
||||
Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(*length_or_end)),
|
||||
can_go,
|
||||
Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(length_or_end)),
|
||||
)],
|
||||
is_cleanup: unwind.is_cleanup(),
|
||||
terminator: Some(Terminator {
|
||||
@ -700,9 +700,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let move_ = |place: &Place<'tcx>| Operand::Move(*place);
|
||||
let elem_size = &Place::from(self.new_temp(tcx.types.usize));
|
||||
let len = &Place::from(self.new_temp(tcx.types.usize));
|
||||
let move_ = |place: Place<'tcx>| Operand::Move(place);
|
||||
let elem_size = Place::from(self.new_temp(tcx.types.usize));
|
||||
let len = Place::from(self.new_temp(tcx.types.usize));
|
||||
|
||||
static USIZE_SWITCH_ZERO: &[u128] = &[0];
|
||||
|
||||
@ -745,10 +745,10 @@ where
|
||||
let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
|
||||
|
||||
let unwind = self.unwind.map(|unwind| {
|
||||
self.drop_loop(unwind, cur, &length_or_end, ety, Unwind::InCleanup, ptr_based)
|
||||
self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
|
||||
});
|
||||
|
||||
let loop_block = self.drop_loop(self.succ, cur, &length_or_end, ety, unwind, ptr_based);
|
||||
let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
|
||||
|
||||
let cur = Place::from(cur);
|
||||
let drop_block_stmts = if ptr_based {
|
||||
@ -758,17 +758,17 @@ where
|
||||
// cur = tmp as *mut T;
|
||||
// end = Offset(cur, len);
|
||||
vec![
|
||||
self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
|
||||
self.assign(&cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
|
||||
self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
|
||||
self.assign(cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
|
||||
self.assign(
|
||||
&length_or_end,
|
||||
length_or_end,
|
||||
Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length)),
|
||||
),
|
||||
]
|
||||
} else {
|
||||
// cur = 0 (length already pushed)
|
||||
let zero = self.constant_usize(0);
|
||||
vec![self.assign(&cur, Rvalue::Use(zero))]
|
||||
vec![self.assign(cur, Rvalue::Use(zero))]
|
||||
};
|
||||
let drop_block = self.elaborator.patch().new_block(BasicBlockData {
|
||||
statements: drop_block_stmts,
|
||||
@ -989,7 +989,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
|
||||
Statement { source_info: self.source_info, kind: StatementKind::Assign(box (*lhs, rhs)) }
|
||||
fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
|
||||
Statement { source_info: self.source_info, kind: StatementKind::Assign(box (lhs, rhs)) }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user