Skip to content

Commit 095aaff

Browse files
authored
Merge pull request #22582 from Veykril/lukaswirth/push-myksxrlknmnl
fix: Only run `Drop::drop` when implemented
2 parents 738b571 + 9b26191 commit 095aaff

2 files changed

Lines changed: 71 additions & 5 deletions

File tree

crates/hir-ty/src/mir/eval.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,7 +3046,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
30463046
ty: Ty<'db>,
30473047
locals: &Locals<'a>,
30483048
addr: Address,
3049-
_metadata: &[u8],
3049+
metadata: &[u8],
30503050
span: MirSpan,
30513051
) -> Result<'db, ()> {
30523052
let Some(drop_fn) = self.lang_items().Drop_drop else {
@@ -3056,13 +3056,23 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
30563056
};
30573057

30583058
let generic_args = GenericArgs::new_from_slice(&[ty.into()]);
3059-
if let Ok(MirOrDynIndex::Mir(body)) =
3060-
self.get_mir_or_dyn_index(drop_fn, generic_args, locals, span)
3059+
let (drop_impl, drop_args) = self.db.lookup_impl_method(
3060+
ParamEnvAndCrate { param_env: self.param_env.param_env, krate: self.crate_id },
3061+
drop_fn,
3062+
generic_args,
3063+
);
3064+
if let Either::Left(drop_impl) = drop_impl
3065+
&& matches!(drop_impl.lookup(self.db).container, ItemContainerId::ImplId(_))
3066+
&& let Ok(body) = self.db.monomorphized_mir_body(
3067+
drop_impl.into(),
3068+
drop_args.store(),
3069+
self.param_env.store(),
3070+
)
30613071
{
30623072
self.exec_looked_up_function(
30633073
body,
30643074
locals,
3065-
drop_fn,
3075+
drop_impl,
30663076
iter::once(IntervalOrOwned::Owned(addr.to_bytes().to_vec())),
30673077
span,
30683078
Interval { addr: Address::Invalid(0), size: 0 },
@@ -3103,6 +3113,12 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
31033113
AdtId::EnumId(_) => (),
31043114
}
31053115
}
3116+
TyKind::Dynamic(..) => {
3117+
if !metadata.is_empty() {
3118+
let concrete_ty = self.vtable_map.ty_of_bytes(metadata)?;
3119+
self.run_drop_glue_deep(concrete_ty, locals, addr, &[], span)?;
3120+
}
3121+
}
31063122
TyKind::Bool
31073123
| TyKind::Char
31083124
| TyKind::Int(_)
@@ -3125,7 +3141,6 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
31253141
| TyKind::Error(_)
31263142
| TyKind::Param(_)
31273143
| TyKind::Placeholder(_)
3128-
| TyKind::Dynamic(..)
31293144
| TyKind::FnPtr(..)
31303145
| TyKind::Bound(..)
31313146
| TyKind::Infer(..)

crates/hir-ty/src/mir/eval/tests.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,28 @@ fn main() {
229229
);
230230
}
231231

232+
#[test]
233+
fn drop_glue_for_type_without_drop_impl_does_not_recurse() {
234+
check_pass(
235+
r#"
236+
//- minicore: drop, pin
237+
238+
struct HasDrop;
239+
impl Drop for HasDrop {
240+
fn drop(&mut self) {}
241+
}
242+
243+
struct WithDropGlue {
244+
field: HasDrop,
245+
}
246+
247+
fn main() {
248+
let _c = WithDropGlue { field: HasDrop };
249+
}
250+
"#,
251+
);
252+
}
253+
232254
#[test]
233255
fn drop_if_let() {
234256
check_pass(
@@ -358,6 +380,35 @@ fn main() {
358380
);
359381
}
360382

383+
#[test]
384+
fn drop_glue_for_trait_object() {
385+
check_panic(
386+
r#"
387+
//- minicore: manually_drop, coerce_unsized, fmt, panic, drop, pin
388+
use core::mem::ManuallyDrop;
389+
use core::ptr::drop_in_place;
390+
391+
struct X;
392+
impl Drop for X {
393+
fn drop(&mut self) {
394+
panic!("concrete drop ran");
395+
}
396+
}
397+
398+
trait T {}
399+
impl T for X {}
400+
401+
fn main() {
402+
let mut x = ManuallyDrop::new(X);
403+
let p = &mut x as *mut ManuallyDrop<X> as *mut X;
404+
let obj: &mut dyn T = unsafe { &mut *p };
405+
drop_in_place(obj);
406+
}
407+
"#,
408+
"concrete drop ran",
409+
);
410+
}
411+
361412
#[test]
362413
fn manually_drop() {
363414
check_pass(

0 commit comments

Comments
 (0)