Skip to content

Commit

Permalink
Don't require Drop for [PhantomData<T>; N] where N and T are …
Browse files Browse the repository at this point in the history
…generic, if `T` requires `Drop`
  • Loading branch information
oli-obk committed Sep 7, 2023
1 parent 61efe9d commit 320bb81
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
24 changes: 22 additions & 2 deletions compiler/rustc_ty_utils/src/needs_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,32 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
// needs drop.
let adt_has_dtor =
|adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant);
let res =
drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some();
let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false)
.filter(filter_array_elements(tcx, query.param_env))
.next()
.is_some();

debug!("needs_drop_raw({:?}) = {:?}", query, res);
res
}

/// HACK: in order to not mistakenly assume that `[PhantomData<T>; N]` requires drop glue
/// we check the element type for drop glue. The correct fix would be looking at the
/// entirety of the code around `needs_drop_components` and this file and come up with
/// logic that is easier to follow while not repeating any checks that may thus diverge.
fn filter_array_elements<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> impl Fn(&Result<Ty<'tcx>, AlwaysRequiresDrop>) -> bool {
move |ty| match ty {
Ok(ty) => match *ty.kind() {
ty::Array(elem, _) => tcx.needs_drop_raw(param_env.and(elem)),
_ => true,
},
Err(AlwaysRequiresDrop) => true,
}
}

fn has_significant_drop_raw<'tcx>(
tcx: TyCtxt<'tcx>,
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
Expand All @@ -37,6 +56,7 @@ fn has_significant_drop_raw<'tcx>(
adt_consider_insignificant_dtor(tcx),
true,
)
.filter(filter_array_elements(tcx, query.param_env))
.next()
.is_some();
debug!("has_significant_drop_raw({:?}) = {:?}", query, res);
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/consts/drop-maybe_uninit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// build-pass

pub const fn f<T, const N: usize>(_: [std::mem::MaybeUninit<T>; N]) {}

pub struct Blubb<T>(*const T);

pub const fn g<T, const N: usize>(_: [Blubb<T>; N]) {}

pub struct Blorb<const N: usize>([String; N]);

pub const fn h(_: Blorb<0>) {}

pub struct Wrap(Blorb<0>);

pub const fn i(_: Wrap) {}

fn main() {}

0 comments on commit 320bb81

Please sign in to comment.