Skip to content

Commit 95cfbe4

Browse files
committed
2229: Early exit when we see an insigificant drop
1 parent e7958d3 commit 95cfbe4

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

Diff for: compiler/rustc_ty_utils/src/needs_drop.rs

+33-9
Original file line numberDiff line numberDiff line change
@@ -171,22 +171,40 @@ where
171171
}
172172
}
173173

174+
enum DtorType {
175+
/// Type has a `Drop` but it is considered insignificant.
176+
/// Check the query `adt_significant_drop_tys` for understanding
177+
/// "significant" / "insignificant".
178+
Insignificant,
179+
180+
/// Type has a `Drop` implentation.
181+
Significant,
182+
}
183+
174184
// This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`.
175185
// Depending on the implentation of `adt_has_dtor`, it is used to check if the
176186
// ADT has a destructor or if the ADT only has a significant destructor. For
177187
// understanding significant destructor look at `adt_significant_drop_tys`.
178188
fn adt_drop_tys_helper(
179189
tcx: TyCtxt<'_>,
180190
def_id: DefId,
181-
adt_has_dtor: impl Fn(&ty::AdtDef) -> bool,
191+
adt_has_dtor: impl Fn(&ty::AdtDef) -> Option<DtorType>,
182192
) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
183193
let adt_components = move |adt_def: &ty::AdtDef| {
184194
if adt_def.is_manually_drop() {
185195
debug!("adt_drop_tys: `{:?}` is manually drop", adt_def);
186196
return Ok(Vec::new().into_iter());
187-
} else if adt_has_dtor(adt_def) {
188-
debug!("adt_drop_tys: `{:?}` implements `Drop`", adt_def);
189-
return Err(AlwaysRequiresDrop);
197+
} else if let Some(dtor_info) = adt_has_dtor(adt_def) {
198+
match dtor_info {
199+
DtorType::Significant => {
200+
debug!("adt_drop_tys: `{:?}` implements `Drop`", adt_def);
201+
return Err(AlwaysRequiresDrop);
202+
}
203+
DtorType::Insignificant => {
204+
debug!("adt_drop_tys: `{:?}` drop is insignificant", adt_def);
205+
return Ok(Vec::new().into_iter());
206+
}
207+
}
190208
} else if adt_def.is_union() {
191209
debug!("adt_drop_tys: `{:?}` is a union", adt_def);
192210
return Ok(Vec::new().into_iter());
@@ -204,7 +222,10 @@ fn adt_drop_tys_helper(
204222
}
205223

206224
fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
207-
let adt_has_dtor = |adt_def: &ty::AdtDef| adt_def.destructor(tcx).is_some();
225+
// This is for the "needs_drop" query, that considers all `Drop` impls, therefore all dtors are
226+
// significant.
227+
let adt_has_dtor =
228+
|adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
208229
adt_drop_tys_helper(tcx, def_id, adt_has_dtor)
209230
}
210231

@@ -213,10 +234,13 @@ fn adt_significant_drop_tys(
213234
def_id: DefId,
214235
) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
215236
let adt_has_dtor = |adt_def: &ty::AdtDef| {
216-
adt_def
217-
.destructor(tcx)
218-
.map(|dtor| !tcx.has_attr(dtor.did, sym::rustc_insignificant_dtor))
219-
.unwrap_or(false)
237+
adt_def.destructor(tcx).map(|dtor| {
238+
if tcx.has_attr(dtor.did, sym::rustc_insignificant_dtor) {
239+
DtorType::Insignificant
240+
} else {
241+
DtorType::Significant
242+
}
243+
})
220244
};
221245
adt_drop_tys_helper(tcx, def_id, adt_has_dtor)
222246
}

0 commit comments

Comments
 (0)