diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 37a16a43acdeb..d3a1ed52d2e62 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -42,8 +42,15 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::Foreign(..) | ty::Error(_) => true, - // `T is PAT`, `[T; N]`, and `[T]` have same properties as T. - ty::Pat(ty, _) | ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, *ty), + // `T is PAT` and `[T]` have same properties as T. + ty::Pat(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, *ty), + ty::Array(ty, size) => { + // Empty array never has a dtor. See issue #110288. + match size.try_to_target_usize(tcx) { + Some(0) => true, + _ => trivial_dropck_outlives(tcx, *ty), + } + } // (T1..Tn) and closures have same properties as T1..Tn -- // check if *all* of them are trivial. diff --git a/tests/ui/dropck/dropck-empty-array.rs b/tests/ui/dropck/dropck-empty-array.rs new file mode 100644 index 0000000000000..f3eca6aed8d5e --- /dev/null +++ b/tests/ui/dropck/dropck-empty-array.rs @@ -0,0 +1,23 @@ +//@ run-pass + +#[allow(dead_code)] +struct Struct<'s>(&'s str); + +impl<'s> Drop for Struct<'s> { + fn drop(&mut self) {} +} + +fn to_array_zero(_: T) -> [T; 0] { + [] +} + +pub fn array_zero_in_tuple() { + let mut x = ([], String::new()); + { + let s = String::from("temporary"); + let p = Struct(&s); + x.0 = to_array_zero(p); + } +} + +fn main() {}