summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_dataflow/src/move_paths
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_mir_dataflow/src/move_paths
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/move_paths')
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs150
2 files changed, 117 insertions, 34 deletions
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
index 7806e8f45..2a7f23ef6 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
@@ -57,6 +57,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
ProjectionElem::ConstantIndex { offset, min_length, from_end }
}
ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
+ ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()),
}
}
}
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 5052de991..7a5b3585d 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -115,44 +115,126 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
let body = self.builder.body;
let tcx = self.builder.tcx;
let place_ty = place_ref.ty(body, tcx).ty;
- match place_ty.kind() {
- ty::Ref(..) | ty::RawPtr(..) => {
- return Err(MoveError::cannot_move_out_of(
- self.loc,
- BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
- ));
- }
- ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
- return Err(MoveError::cannot_move_out_of(
- self.loc,
- InteriorOfTypeWithDestructor { container_ty: place_ty },
- ));
- }
- ty::Adt(adt, _) if adt.is_union() => {
- union_path.get_or_insert(base);
- }
- ty::Slice(_) => {
- return Err(MoveError::cannot_move_out_of(
- self.loc,
- InteriorOfSliceOrArray {
- ty: place_ty,
- is_index: matches!(elem, ProjectionElem::Index(..)),
- },
- ));
+ match elem {
+ ProjectionElem::Deref => match place_ty.kind() {
+ ty::Ref(..) | ty::RawPtr(..) => {
+ return Err(MoveError::cannot_move_out_of(
+ self.loc,
+ BorrowedContent {
+ target_place: place_ref.project_deeper(&[elem], tcx),
+ },
+ ));
+ }
+ ty::Adt(adt, _) => {
+ if !adt.is_box() {
+ bug!("Adt should be a box type when Place is deref");
+ }
+ }
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Foreign(_)
+ | ty::Str
+ | ty::Array(_, _)
+ | ty::Slice(_)
+ | ty::FnDef(_, _)
+ | ty::FnPtr(_)
+ | ty::Dynamic(_, _, _)
+ | ty::Closure(_, _)
+ | ty::Generator(_, _, _)
+ | ty::GeneratorWitness(..)
+ | ty::Never
+ | ty::Tuple(_)
+ | ty::Alias(_, _)
+ | ty::Param(_)
+ | ty::Bound(_, _)
+ | ty::Infer(_)
+ | ty::Error(_)
+ | ty::Placeholder(_) => {
+ bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
+ }
+ },
+ ProjectionElem::Field(_, _) => match place_ty.kind() {
+ ty::Adt(adt, _) => {
+ if adt.has_dtor(tcx) {
+ return Err(MoveError::cannot_move_out_of(
+ self.loc,
+ InteriorOfTypeWithDestructor { container_ty: place_ty },
+ ));
+ }
+ if adt.is_union() {
+ union_path.get_or_insert(base);
+ }
+ }
+ ty::Closure(_, _) | ty::Generator(_, _, _) | ty::Tuple(_) => (),
+ ty::Bool
+ | ty::Char
+ | ty::Int(_)
+ | ty::Uint(_)
+ | ty::Float(_)
+ | ty::Foreign(_)
+ | ty::Str
+ | ty::Array(_, _)
+ | ty::Slice(_)
+ | ty::RawPtr(_)
+ | ty::Ref(_, _, _)
+ | ty::FnDef(_, _)
+ | ty::FnPtr(_)
+ | ty::Dynamic(_, _, _)
+ | ty::GeneratorWitness(..)
+ | ty::Never
+ | ty::Alias(_, _)
+ | ty::Param(_)
+ | ty::Bound(_, _)
+ | ty::Infer(_)
+ | ty::Error(_)
+ | ty::Placeholder(_) => bug!(
+ "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
+ ),
+ },
+ ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
+ match place_ty.kind() {
+ ty::Slice(_) => {
+ return Err(MoveError::cannot_move_out_of(
+ self.loc,
+ InteriorOfSliceOrArray {
+ ty: place_ty,
+ is_index: matches!(elem, ProjectionElem::Index(..)),
+ },
+ ));
+ }
+ ty::Array(_, _) => (),
+ _ => bug!("Unexpected type {:#?}", place_ty.is_array()),
+ }
}
-
- ty::Array(..) => {
- if let ProjectionElem::Index(..) = elem {
+ ProjectionElem::Index(_) => match place_ty.kind() {
+ ty::Array(..) => {
return Err(MoveError::cannot_move_out_of(
self.loc,
InteriorOfSliceOrArray { ty: place_ty, is_index: true },
));
}
- }
-
- _ => {}
- };
-
+ ty::Slice(_) => {
+ return Err(MoveError::cannot_move_out_of(
+ self.loc,
+ InteriorOfSliceOrArray {
+ ty: place_ty,
+ is_index: matches!(elem, ProjectionElem::Index(..)),
+ },
+ ));
+ }
+ _ => bug!("Unexpected type {place_ty:#?}"),
+ },
+ // `OpaqueCast`:Only transmutes the type, so no moves there.
+ // `Downcast` :Only changes information about a `Place` without moving.
+ // `Subtype` :Only transmutes the type, so moves.
+ // So it's safe to skip these.
+ ProjectionElem::OpaqueCast(_)
+ | ProjectionElem::Subtype(_)
+ | ProjectionElem::Downcast(_, _) => (),
+ }
if union_path.is_none() {
// inlined from add_move_path because of a borrowck conflict with the iterator
base =
@@ -370,8 +452,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
// this that could possibly access the return place, this doesn't
// need recording.
| TerminatorKind::Return
- | TerminatorKind::Resume
- | TerminatorKind::Terminate
+ | TerminatorKind::UnwindResume
+ | TerminatorKind::UnwindTerminate(_)
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. } => {}