@@ -238,7 +238,7 @@ fn adjust_for_rust_scalar<'tcx>(
238238 layout : TyAndLayout < ' tcx > ,
239239 offset : Size ,
240240 is_return : bool ,
241- is_drop_target : bool ,
241+ drop_target_pointee : Option < Ty < ' tcx > > ,
242242) {
243243 // Booleans are always a noundef i1 that needs to be zero-extended.
244244 if scalar. is_bool ( ) {
@@ -252,14 +252,24 @@ fn adjust_for_rust_scalar<'tcx>(
252252 }
253253
254254 // Only pointer types handled below.
255- let Scalar :: Initialized { value : Pointer ( _) , valid_range} = scalar else { return } ;
255+ let Scalar :: Initialized { value : Pointer ( _) , valid_range } = scalar else { return } ;
256256
257- if !valid_range. contains ( 0 ) {
257+ // Set `nonnull` if the validity range excludes zero, or for the argument to `drop_in_place`,
258+ // which must be nonnull per its documented safety requirements.
259+ if !valid_range. contains ( 0 ) || drop_target_pointee. is_some ( ) {
258260 attrs. set ( ArgAttribute :: NonNull ) ;
259261 }
260262
261263 if let Some ( pointee) = layout. pointee_info_at ( & cx, offset) {
262- if let Some ( kind) = pointee. safe {
264+ let kind = if let Some ( kind) = pointee. safe {
265+ Some ( kind)
266+ } else if let Some ( pointee) = drop_target_pointee {
267+ // The argument to `drop_in_place` is semantically equivalent to a mutable reference.
268+ Some ( PointerKind :: MutableRef { unpin : pointee. is_unpin ( cx. tcx , cx. param_env ( ) ) } )
269+ } else {
270+ None
271+ } ;
272+ if let Some ( kind) = kind {
263273 attrs. pointee_align = Some ( pointee. align ) ;
264274
265275 // `Box` are not necessarily dereferenceable for the entire duration of the function as
@@ -307,18 +317,6 @@ fn adjust_for_rust_scalar<'tcx>(
307317 attrs. set ( ArgAttribute :: ReadOnly ) ;
308318 }
309319 }
310-
311- // If this is the argument to `drop_in_place`, the contents of which we fully control as the
312- // compiler, then we mark this argument as `noalias`, aligned, and dereferenceable. (The
313- // standard library documents the necessary requirements to uphold these attributes for code
314- // that calls this method directly.) This can enable better optimizations, such as argument
315- // promotion.
316- if is_drop_target {
317- attrs. set ( ArgAttribute :: NoAlias ) ;
318- attrs. set ( ArgAttribute :: NonNull ) ;
319- attrs. pointee_size = pointee. size ;
320- attrs. pointee_align = Some ( pointee. align ) ;
321- }
322320 }
323321}
324322
@@ -383,6 +381,10 @@ fn fn_abi_new_uncached<'tcx>(
383381 let _entered = span. enter ( ) ;
384382 let is_return = arg_idx. is_none ( ) ;
385383 let is_drop_target = is_drop_in_place && arg_idx == Some ( 0 ) ;
384+ let drop_target_pointee = is_drop_target. then ( || match ty. kind ( ) {
385+ ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) => * ty,
386+ _ => bug ! ( "argument to drop_in_place is not a raw ptr: {:?}" , ty) ,
387+ } ) ;
386388
387389 let layout = cx. layout_of ( ty) ?;
388390 let layout = if force_thin_self_ptr && arg_idx == Some ( 0 ) {
@@ -403,7 +405,7 @@ fn fn_abi_new_uncached<'tcx>(
403405 * layout,
404406 offset,
405407 is_return,
406- is_drop_target ,
408+ drop_target_pointee ,
407409 ) ;
408410 attrs
409411 } ) ;
0 commit comments