Rollup merge of #65389 - ecstatic-morse:zero-sized-array-no-drop, r=eddyb
Return `false` from `needs_drop` for all zero-sized arrays. Resolves #65348. This changes the result of the `needs_drop` query from `true` to `false` for types such as `[Box<i32>; 0]`. I believe this change to be sound because a zero-sized array can never actually hold a value. This is an elegant way of resolving #65348 and #64945, but obviously it has much broader implications.
This commit is contained in:
commit
bbcf66a4a1
3 changed files with 30 additions and 13 deletions
|
@ -1109,6 +1109,9 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
|
|||
|
||||
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
|
||||
|
||||
// Zero-length arrays never contain anything to drop.
|
||||
ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false,
|
||||
|
||||
// Structural recursion.
|
||||
ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty),
|
||||
|
||||
|
|
|
@ -104,25 +104,16 @@ impl<'tcx> TransferFunction<'_, '_, 'tcx> {
|
|||
kind: mir::BorrowKind,
|
||||
borrowed_place: &mir::Place<'tcx>,
|
||||
) -> bool {
|
||||
let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty;
|
||||
|
||||
// Zero-sized types cannot be mutated, since there is nothing inside to mutate.
|
||||
//
|
||||
// FIXME: For now, we only exempt arrays of length zero. We need to carefully
|
||||
// consider the effects before extending this to all ZSTs.
|
||||
if let ty::Array(_, len) = borrowed_ty.kind {
|
||||
if len.try_eval_usize(self.tcx, self.param_env) == Some(0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
match kind {
|
||||
mir::BorrowKind::Mut { .. } => true,
|
||||
|
||||
| mir::BorrowKind::Shared
|
||||
| mir::BorrowKind::Shallow
|
||||
| mir::BorrowKind::Unique
|
||||
=> !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP),
|
||||
=> !borrowed_place
|
||||
.ty(self.body, self.tcx)
|
||||
.ty
|
||||
.is_freeze(self.tcx, self.param_env, DUMMY_SP),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
src/test/ui/consts/issue-65348.rs
Normal file
23
src/test/ui/consts/issue-65348.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// check-pass
|
||||
|
||||
struct Generic<T>(T);
|
||||
|
||||
impl<T> Generic<T> {
|
||||
const ARRAY: [T; 0] = [];
|
||||
const NEWTYPE_ARRAY: Generic<[T; 0]> = Generic([]);
|
||||
const ARRAY_FIELD: Generic<(i32, [T; 0])> = Generic((0, []));
|
||||
}
|
||||
|
||||
pub const fn array<T>() -> &'static T {
|
||||
&Generic::<T>::ARRAY[0]
|
||||
}
|
||||
|
||||
pub const fn newtype_array<T>() -> &'static T {
|
||||
&Generic::<T>::NEWTYPE_ARRAY.0[0]
|
||||
}
|
||||
|
||||
pub const fn array_field<T>() -> &'static T {
|
||||
&(Generic::<T>::ARRAY_FIELD.0).1[0]
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Reference in a new issue