Skip to content

Commit 7dfa028

Browse files
authored
Unrolled build for rust-lang#115770
Rollup merge of rust-lang#115770 - ouz-a:match_elem_builder, r=lcnr Match on elem first while building move paths While working on rust-lang#115025 `@lcnr` and I observed "move_paths_for" function matched on the `Ty` instead of `Projection` which seems flawed as it's the `Projection`s that cause the problem not the type. r? `@lcnr`
2 parents aadb571 + 63df126 commit 7dfa028

File tree

1 file changed

+113
-32
lines changed
  • compiler/rustc_mir_dataflow/src/move_paths

1 file changed

+113
-32
lines changed

Diff for: compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+113-32
Original file line numberDiff line numberDiff line change
@@ -115,44 +115,125 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
115115
let body = self.builder.body;
116116
let tcx = self.builder.tcx;
117117
let place_ty = place_ref.ty(body, tcx).ty;
118-
match place_ty.kind() {
119-
ty::Ref(..) | ty::RawPtr(..) => {
120-
return Err(MoveError::cannot_move_out_of(
121-
self.loc,
122-
BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
123-
));
124-
}
125-
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
126-
return Err(MoveError::cannot_move_out_of(
127-
self.loc,
128-
InteriorOfTypeWithDestructor { container_ty: place_ty },
129-
));
130-
}
131-
ty::Adt(adt, _) if adt.is_union() => {
132-
union_path.get_or_insert(base);
133-
}
134-
ty::Slice(_) => {
135-
return Err(MoveError::cannot_move_out_of(
136-
self.loc,
137-
InteriorOfSliceOrArray {
138-
ty: place_ty,
139-
is_index: matches!(elem, ProjectionElem::Index(..)),
140-
},
141-
));
118+
match elem {
119+
ProjectionElem::Deref => match place_ty.kind() {
120+
ty::Ref(..) | ty::RawPtr(..) => {
121+
return Err(MoveError::cannot_move_out_of(
122+
self.loc,
123+
BorrowedContent {
124+
target_place: place_ref.project_deeper(&[elem], tcx),
125+
},
126+
));
127+
}
128+
ty::Adt(adt, _) => {
129+
if !adt.is_box() {
130+
bug!("Adt should be a box type when Place is deref");
131+
}
132+
}
133+
ty::Bool
134+
| ty::Char
135+
| ty::Int(_)
136+
| ty::Uint(_)
137+
| ty::Float(_)
138+
| ty::Foreign(_)
139+
| ty::Str
140+
| ty::Array(_, _)
141+
| ty::Slice(_)
142+
| ty::FnDef(_, _)
143+
| ty::FnPtr(_)
144+
| ty::Dynamic(_, _, _)
145+
| ty::Closure(_, _)
146+
| ty::Generator(_, _, _)
147+
| ty::GeneratorWitness(_)
148+
| ty::GeneratorWitnessMIR(_, _)
149+
| ty::Never
150+
| ty::Tuple(_)
151+
| ty::Alias(_, _)
152+
| ty::Param(_)
153+
| ty::Bound(_, _)
154+
| ty::Infer(_)
155+
| ty::Error(_)
156+
| ty::Placeholder(_) => {
157+
bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
158+
}
159+
},
160+
ProjectionElem::Field(_, _) => match place_ty.kind() {
161+
ty::Adt(adt, _) => {
162+
if adt.has_dtor(tcx) {
163+
return Err(MoveError::cannot_move_out_of(
164+
self.loc,
165+
InteriorOfTypeWithDestructor { container_ty: place_ty },
166+
));
167+
}
168+
if adt.is_union() {
169+
union_path.get_or_insert(base);
170+
}
171+
}
172+
ty::Closure(_, _) | ty::Generator(_, _, _) | ty::Tuple(_) => (),
173+
ty::Bool
174+
| ty::Char
175+
| ty::Int(_)
176+
| ty::Uint(_)
177+
| ty::Float(_)
178+
| ty::Foreign(_)
179+
| ty::Str
180+
| ty::Array(_, _)
181+
| ty::Slice(_)
182+
| ty::RawPtr(_)
183+
| ty::Ref(_, _, _)
184+
| ty::FnDef(_, _)
185+
| ty::FnPtr(_)
186+
| ty::Dynamic(_, _, _)
187+
| ty::GeneratorWitness(_)
188+
| ty::GeneratorWitnessMIR(_, _)
189+
| ty::Never
190+
| ty::Alias(_, _)
191+
| ty::Param(_)
192+
| ty::Bound(_, _)
193+
| ty::Infer(_)
194+
| ty::Error(_)
195+
| ty::Placeholder(_) => bug!(
196+
"When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
197+
),
198+
},
199+
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
200+
match place_ty.kind() {
201+
ty::Slice(_) => {
202+
return Err(MoveError::cannot_move_out_of(
203+
self.loc,
204+
InteriorOfSliceOrArray {
205+
ty: place_ty,
206+
is_index: matches!(elem, ProjectionElem::Index(..)),
207+
},
208+
));
209+
}
210+
ty::Array(_, _) => (),
211+
_ => bug!("Unexpected type {:#?}", place_ty.is_array()),
212+
}
142213
}
143-
144-
ty::Array(..) => {
145-
if let ProjectionElem::Index(..) = elem {
214+
ProjectionElem::Index(_) => match place_ty.kind() {
215+
ty::Array(..) => {
146216
return Err(MoveError::cannot_move_out_of(
147217
self.loc,
148218
InteriorOfSliceOrArray { ty: place_ty, is_index: true },
149219
));
150220
}
151-
}
152-
153-
_ => {}
154-
};
155-
221+
ty::Slice(_) => {
222+
return Err(MoveError::cannot_move_out_of(
223+
self.loc,
224+
InteriorOfSliceOrArray {
225+
ty: place_ty,
226+
is_index: matches!(elem, ProjectionElem::Index(..)),
227+
},
228+
));
229+
}
230+
_ => bug!("Unexpected type {place_ty:#?}"),
231+
},
232+
// `OpaqueCast` only transmutes the type, so no moves there and
233+
// `Downcast` only changes information about a `Place` without moving
234+
// So it's safe to skip these.
235+
ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
236+
}
156237
if union_path.is_none() {
157238
// inlined from add_move_path because of a borrowck conflict with the iterator
158239
base =

0 commit comments

Comments
 (0)