diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 7ef2e95542bba..2c17317b85d1a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -242,12 +242,25 @@ impl *const T { // In the mean-time, this operation is defined to be "as if" it was // a wrapping_offset, so we can emulate it as such. This should properly // restore pointer provenance even under today's compiler. - let self_addr = self.addr() as isize; - let dest_addr = addr as isize; - let offset = dest_addr.wrapping_sub(self_addr); - - // This is the canonical desugarring of this operation - self.cast::().wrapping_offset(offset).cast::() + let self_addr = self.addr(); + // In an ideal world (err, an ideal world we'd have an intrinsic, but + // short of that), we'd implement this as follows: + // ``` + // let offset = (addr as isize).wrapping_sub(self_addr as isize); + // self.cast::().wrapping_offset(offset).cast::() + // ``` + // This is the canonical desugaring of this operation, and is compatible + // with targets which don't allow large wrapping add/sub/offset + // operations, including CHERI. + // + // Unfortunately, this causes worse codegen than the following + // implementation, which should be correct on all targets we currently + // support (at the moment AFAICT, we don't yet support CHERI, or we'd + // special-case it to use the desugaring listed above). + // + // As a result, we use the following implementation, which would be + // wrong on CHERI, but right everywhere else. + self.cast::().wrapping_add(addr).wrapping_sub(self_addr).cast::() } /// Creates a new pointer by mapping `self`'s address to a new one. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 56f9c84f5af6f..30f0c71da98f9 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -246,12 +246,25 @@ impl *mut T { // In the mean-time, this operation is defined to be "as if" it was // a wrapping_offset, so we can emulate it as such. This should properly // restore pointer provenance even under today's compiler. - let self_addr = self.addr() as isize; - let dest_addr = addr as isize; - let offset = dest_addr.wrapping_sub(self_addr); - - // This is the canonical desugarring of this operation - self.cast::().wrapping_offset(offset).cast::() + let self_addr = self.addr(); + // In an ideal world (err, an ideal world we'd have an intrinsic, but + // short of that), we'd implement this as follows: + // ``` + // let offset = (addr as isize).wrapping_sub(self_addr as isize); + // self.cast::().wrapping_offset(offset).cast::() + // ``` + // This is the canonical desugaring of this operation, and is compatible + // with targets which don't allow large wrapping add/sub/offset + // operations, including CHERI. + // + // Unfortunately, this causes worse codegen than the following + // implementation, which should be correct on all targets we currently + // support (at the moment AFAICT, we don't yet support CHERI, or we'd + // special-case it to use the desugaring listed above). + // + // As a result, we use the following implementation, which would be + // wrong on CHERI, but right everywhere else. + self.cast::().wrapping_add(addr).wrapping_sub(self_addr).cast::() } /// Creates a new pointer by mapping `self`'s address to a new one.