@@ -254,15 +254,15 @@ fn adjust_for_rust_scalar<'tcx>(
254
254
if let Some ( kind) = pointee. safe {
255
255
attrs. pointee_align = Some ( pointee. align ) ;
256
256
257
- // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable
258
- // for the entire duration of the function as they can be deallocated
259
- // at any time. Same for shared mutable references . If LLVM had a
260
- // way to say "dereferenceable on entry" we could use it here.
257
+ // `Box` are not necessarily dereferenceable for the entire duration of the function as
258
+ // they can be deallocated at any time. Same for non-frozen shared references (see
259
+ // <https://github.com/rust-lang/rust/pull/98017>) . If LLVM had a way to say
260
+ // "dereferenceable on entry" we could use it here.
261
261
attrs. pointee_size = match kind {
262
- PointerKind :: UniqueBorrowed
263
- | PointerKind :: UniqueBorrowedPinned
264
- | PointerKind :: Frozen => pointee. size ,
265
- PointerKind :: SharedMutable | PointerKind :: UniqueOwned => Size :: ZERO ,
262
+ PointerKind :: Box | PointerKind :: SharedRef { frozen : false } => Size :: ZERO ,
263
+ PointerKind :: SharedRef { frozen : true } | PointerKind :: MutableRef { .. } => {
264
+ pointee. size
265
+ }
266
266
} ;
267
267
268
268
// The aliasing rules for `Box<T>` are still not decided, but currently we emit
@@ -278,23 +278,22 @@ fn adjust_for_rust_scalar<'tcx>(
278
278
// `&mut` pointer parameters never alias other parameters,
279
279
// or mutable global data
280
280
//
281
- // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
282
- // and can be marked as both `readonly` and `noalias`, as
283
- // LLVM's definition of `noalias` is based solely on memory
284
- // dependencies rather than pointer equality
281
+ // `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as both
282
+ // `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely on memory
283
+ // dependencies rather than pointer equality. However this only applies to arguments,
284
+ // not return values.
285
285
let no_alias = match kind {
286
- PointerKind :: SharedMutable | PointerKind :: UniqueBorrowedPinned => false ,
287
- PointerKind :: UniqueBorrowed => noalias_mut_ref,
288
- PointerKind :: UniqueOwned => noalias_for_box,
289
- PointerKind :: Frozen => true ,
286
+ PointerKind :: SharedRef { frozen } => frozen,
287
+ PointerKind :: MutableRef { unpin } => unpin && noalias_mut_ref,
288
+ PointerKind :: Box => noalias_for_box,
290
289
} ;
291
290
// We can never add `noalias` in return position; that LLVM attribute has some very surprising semantics
292
291
// (see <https://github.com/rust-lang/unsafe-code-guidelines/issues/385#issuecomment-1368055745>).
293
292
if no_alias && !is_return {
294
293
attrs. set ( ArgAttribute :: NoAlias ) ;
295
294
}
296
295
297
- if kind == PointerKind :: Frozen && !is_return {
296
+ if matches ! ( kind, PointerKind :: SharedRef { frozen : true } ) && !is_return {
298
297
attrs. set ( ArgAttribute :: ReadOnly ) ;
299
298
}
300
299
}
0 commit comments