diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 9b0d34b8979..5bfb48cb5e0 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -307,24 +307,17 @@ fn adjust_for_rust_scalar<'tcx>( attrs.set(ArgAttribute::ReadOnly); } } - } - // If this is the argument to `drop_in_place`, the contents of which we fully control as the - // compiler, then we may be able to mark that argument `noalias`. Currently, we're conservative - // and do so only if `drop_in_place` results in a direct call to the programmer's `drop` method. - // The `drop` method requires `&mut self`, so we're effectively just propagating the `noalias` - // guarantee from `drop` upward to `drop_in_place` in this case. - if is_drop_target { - match *layout.ty.kind() { - ty::RawPtr(inner) => { - if let ty::Adt(adt_def, _) = inner.ty.kind() { - if adt_def.destructor(cx.tcx()).is_some() { - debug!("marking drop_in_place argument as noalias"); - attrs.set(ArgAttribute::NoAlias); - } - } - } - _ => bug!("drop target isn't a raw pointer"), + // If this is the argument to `drop_in_place`, the contents of which we fully control as the + // compiler, then we mark this argument as `noalias`, aligned, and dereferenceable. (The + // standard library documents the necessary requirements to uphold these attributes for code + // that calls this method directly.) This can enable better optimizations, such as argument + // promotion. + if is_drop_target { + attrs.set(ArgAttribute::NoAlias); + attrs.set(ArgAttribute::NonNull); + attrs.pointee_size = pointee.size; + attrs.pointee_align = Some(pointee.align); } } } diff --git a/tests/codegen/drop-in-place-noalias.rs b/tests/codegen/drop-in-place-noalias.rs index bd9de4ad972..64ac8760456 100644 --- a/tests/codegen/drop-in-place-noalias.rs +++ b/tests/codegen/drop-in-place-noalias.rs @@ -4,7 +4,7 @@ use std::hint::black_box; -// CHECK: define{{.*}}drop_in_place{{.*}}Foo{{.*}}({{.*}}noalias{{.*}}) +// CHECK: define{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}Foo{{.*}}({{.*}}noalias {{.*}} align 4 dereferenceable(12){{.*}}) #[repr(C)] pub struct Foo {