@@ -242,12 +242,20 @@ impl<T: ?Sized> *const T {
242
242
// In the mean-time, this operation is defined to be "as if" it was
243
243
// a wrapping_offset, so we can emulate it as such. This should properly
244
244
// restore pointer provenance even under today's compiler.
245
- let self_addr = self . addr ( ) as isize ;
246
- let dest_addr = addr as isize ;
247
- let offset = dest_addr. wrapping_sub ( self_addr) ;
248
-
249
- // This is the canonical desugarring of this operation
250
- self . cast :: < u8 > ( ) . wrapping_offset ( offset) . cast :: < T > ( )
245
+ let self_addr = self . addr ( ) ;
246
+ // Unfortunately, the CHERI-compatible way of defining this operation
247
+ // optimizes worse, so we special case it... in a somewhat ad-hoc way
248
+ // (checking for 128 bit pointers) because at the time of this writing,
249
+ // we don't actually support CHERI yet. Ideally this would be
250
+ // `cfg!(target_supports_large_wrapping_offsets)` or something, see
251
+ // #96152 for details.
252
+ if cfg ! ( target_pointer_width = "128" ) {
253
+ let offset = ( addr as isize ) . wrapping_sub ( self_addr as isize ) ;
254
+ // This is the canonical desugarring of this operation
255
+ self . cast :: < u8 > ( ) . wrapping_offset ( offset) . cast :: < T > ( )
256
+ } else {
257
+ self . cast :: < u8 > ( ) . wrapping_sub ( self_addr) . wrapping_add ( addr) . cast :: < T > ( )
258
+ }
251
259
}
252
260
253
261
/// Creates a new pointer by mapping `self`'s address to a new one.
0 commit comments