Rollup merge of #130350 - RalfJung:strict-provenance, r=dtolnay · qinheping/verify-rust-std@7f91dbe (original) (raw)

`@@ -137,10 +137,11 @@ impl<T: ?Sized> *const T {

`

137

137

``

138

138

`/// Gets the "address" portion of the pointer.

`

139

139

`///

`

140

``

`` -

/// This is similar to self as usize, which semantically discards provenance and

``

141

``

`` -

/// address-space information. However, unlike self as usize, casting the returned address

``

142

``

`-

/// back to a pointer yields a [pointer without provenance][without_provenance], which is undefined behavior to dereference. To

`

143

``

`-

/// properly restore the lost information and obtain a dereferenceable pointer, use

`

``

140

`` +

/// This is similar to self as usize, except that the [provenance][crate::ptr#provenance] of

``

``

141

`+

/// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that

`

``

142

`+

/// casting the returned address back to a pointer yields a [pointer without

`

``

143

`+

/// provenance][without_provenance], which is undefined behavior to dereference. To properly

`

``

144

`+

/// restore the lost information and obtain a dereferenceable pointer, use

`

144

145

`` /// [with_addr][pointer::with_addr] or [map_addr][pointer::map_addr].

``

145

146

`///

`

146

147

`/// If using those APIs is not possible because there is no way to preserve a pointer with the

`

`@@ -155,90 +156,81 @@ impl<T: ?Sized> *const T {

`

155

156

`/// perform a change of representation to produce a value containing only the address

`

156

157

`/// portion of the pointer. What that means is up to the platform to define.

`

157

158

`///

`

158

``

`-

/// This API and its claimed semantics are part of the Strict Provenance experiment, and as such

`

159

``

`-

/// might change in the future (including possibly weakening this so it becomes wholly

`

160

``

`` -

/// equivalent to self as usize). See the [module documentation][crate::ptr] for details.

``

``

159

`+

/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.

`

161

160

`#[must_use]

`

162

161

`#[inline(always)]

`

163

``

`-

#[unstable(feature = "strict_provenance", issue = "95228")]

`

``

162

`+

#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]

`

164

163

`pub fn addr(self) -> usize {

`

165

``

`-

// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.

`

``

164

`+

// A pointer-to-integer transmute currently has exactly the right semantics: it returns the

`

``

165

`+

// address without exposing the provenance. Note that this is not a stable guarantee about

`

``

166

`+

// transmute semantics, it relies on sysroot crates having special status.

`

166

167

`// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the

`

167

168

`// provenance).

`

168

169

`unsafe { mem::transmute(self.cast::<()>()) }

`

169

170

`}

`

170

171

``

171

``

`-

/// Exposes the "provenance" part of the pointer for future use in

`

172

``

`` -

/// [with_exposed_provenance][] and returns the "address" portion.

``

``

172

`+

/// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in

`

``

173

`` +

/// [with_exposed_provenance] and returns the "address" portion.

``

173

174

`///

`

174

``

`` -

/// This is equivalent to self as usize, which semantically discards provenance and

``

175

``

`` -

/// address-space information. Furthermore, this (like the as cast) has the implicit

``

176

``

`-

/// side-effect of marking the provenance as 'exposed', so on platforms that support it you can

`

177

``

`` -

/// later call [with_exposed_provenance][] to reconstitute the original pointer including its

``

178

``

`-

/// provenance. (Reconstructing address space information, if required, is your responsibility.)

`

``

175

`` +

/// This is equivalent to self as usize, which semantically discards provenance information.

``

``

176

`` +

/// Furthermore, this (like the as cast) has the implicit side-effect of marking the

``

``

177

`+

/// provenance as 'exposed', so on platforms that support it you can later call

`

``

178

`` +

/// [with_exposed_provenance] to reconstitute the original pointer including its provenance.

``

179

179

`///

`

180

``

`-

/// Using this method means that code is not following [Strict

`

181

``

`-

/// Provenance][super#strict-provenance] rules. Supporting

`

182

``

`` -

/// [with_exposed_provenance][] complicates specification and reasoning and may not be supported by

``

183

``

`-

/// tools that help you to stay conformant with the Rust memory model, so it is recommended to

`

184

``

`` -

/// use [addr][pointer::addr] wherever possible.

``

``

180

`` +

/// Due to its inherent ambiguity, [with_exposed_provenance] may not be supported by tools

``

``

181

`+

/// that help you to stay conformant with the Rust memory model. It is recommended to use

`

``

182

`` +

/// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [with_addr][pointer::with_addr]

``

``

183

`` +

/// wherever possible, in which case [addr][pointer::addr] should be used instead of expose_provenance.

``

185

184

`///

`

186

185

`/// On most platforms this will produce a value with the same bytes as the original pointer,

`

187

186

`/// because all the bytes are dedicated to describing the address. Platforms which need to store

`

188

187

`/// additional information in the pointer may not support this operation, since the 'expose'

`

189

``

`` -

/// side-effect which is required for [with_exposed_provenance][] to work is typically not

``

``

188

`` +

/// side-effect which is required for [with_exposed_provenance] to work is typically not

``

190

189

`/// available.

`

191

190

`///

`

192

``

`-

/// It is unclear whether this method can be given a satisfying unambiguous specification. This

`

193

``

`-

/// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].

`

``

191

`+

/// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.

`

194

192

`///

`

195

193

`` /// [with_exposed_provenance]: with_exposed_provenance

``

196

194

`#[must_use]

`

197

195

`#[inline(always)]

`

198

``

`-

#[unstable(feature = "exposed_provenance", issue = "95228")]

`

``

196

`+

#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]

`

199

197

`pub fn expose_provenance(self) -> usize {

`

200

``

`-

// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.

`

201

198

`self.cast::<()>() as usize

`

202

199

`}

`

203

200

``

204

``

`-

/// Creates a new pointer with the given address.

`

``

201

`+

/// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of

`

``

202

`` +

/// self.

``

205

203

`///

`

206

``

`` -

/// This performs the same operation as an addr as ptr cast, but copies

``

207

``

`` -

/// the address-space and provenance of self to the new pointer.

``

208

``

`-

/// This allows us to dynamically preserve and propagate this important

`

209

``

`-

/// information in a way that is otherwise impossible with a unary cast.

`

``

204

`` +

/// This is similar to a addr as *const T cast, but copies

``

``

205

`` +

/// the provenance of self to the new pointer.

``

``

206

`+

/// This avoids the inherent ambiguity of the unary cast.

`

210

207

`///

`

211

208

`` /// This is equivalent to using [wrapping_offset][pointer::wrapping_offset] to offset

``

212

209

`` /// self to the given address, and therefore has all the same capabilities and restrictions.

``

213

210

`///

`

214

``

`-

/// This API and its claimed semantics are part of the Strict Provenance experiment,

`

215

``

`-

/// see the [module documentation][crate::ptr] for details.

`

``

211

`+

/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.

`

216

212

`#[must_use]

`

217

213

`#[inline]

`

218

``

`-

#[unstable(feature = "strict_provenance", issue = "95228")]

`

``

214

`+

#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]

`

219

215

`pub fn with_addr(self, addr: usize) -> Self {

`

220

``

`-

// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.

`

221

``

`-

//

`

222

``

`-

// In the mean-time, this operation is defined to be "as if" it was

`

223

``

`-

// a wrapping_offset, so we can emulate it as such. This should properly

`

224

``

`-

// restore pointer provenance even under today's compiler.

`

``

216

`+

// This should probably be an intrinsic to avoid doing any sort of arithmetic, but

`

``

217

`` +

// meanwhile, we can implement it with wrapping_offset, which preserves the pointer's

``

``

218

`+

// provenance.

`

225

219

`let self_addr = self.addr() as isize;

`

226

220

`let dest_addr = addr as isize;

`

227

221

`let offset = dest_addr.wrapping_sub(self_addr);

`

228

``

-

229

``

`-

// This is the canonical desugaring of this operation

`

230

222

`self.wrapping_byte_offset(offset)

`

231

223

`}

`

232

224

``

233

``

`` -

/// Creates a new pointer by mapping self's address to a new one.

``

``

225

`` +

/// Creates a new pointer by mapping self's address to a new one, preserving the

``

``

226

`` +

/// [provenance][crate::ptr#provenance] of self.

``

234

227

`///

`

235

228

`` /// This is a convenience for [with_addr][pointer::with_addr], see that method for details.

``

236

229

`///

`

237

``

`-

/// This API and its claimed semantics are part of the Strict Provenance experiment,

`

238

``

`-

/// see the [module documentation][crate::ptr] for details.

`

``

230

`+

/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.

`

239

231

`#[must_use]

`

240

232

`#[inline]

`

241

``

`-

#[unstable(feature = "strict_provenance", issue = "95228")]

`

``

233

`+

#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]

`

242

234

`pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {

`

243

235

`self.with_addr(f(self.addr()))

`

244

236

`}

`

`@@ -379,7 +371,7 @@ impl<T: ?Sized> *const T {

`

379

371

`` /// * The offset in bytes, count * size_of::<T>(), computed on mathematical integers (without

``

380

372

`` /// "wrapping around"), must fit in an isize.

``

381

373

`///

`

382

``

`` -

/// * If the computed offset is non-zero, then self must be derived from a pointer to some

``

``

374

`` +

/// * If the computed offset is non-zero, then self must be [derived from][crate::ptr#provenance] a pointer to some

``

383

375

`` /// [allocated object], and the entire memory range between self and the result must be in

``

384

376

`/// bounds of that allocated object. In particular, this range must not "wrap around" the edge

`

385

377

`/// of the address space.

`

`@@ -560,7 +552,7 @@ impl<T: ?Sized> *const T {

`

560

552

`/// ## Examples

`

561

553

`///

`

562

554

```` /// ```

````

563

``

`-

/// #![feature(ptr_mask, strict_provenance)]

`

``

555

`+

/// #![feature(ptr_mask)]

`

564

556

`/// let v = 17_u32;

`

565

557

`/// let ptr: *const u32 = &v;

`

566

558

`///

`

`@@ -611,7 +603,7 @@ impl<T: ?Sized> *const T {

`

611

603

`` /// * self and origin must either

``

612

604

`///

`

613

605

`/// * point to the same address, or

`

614

``

`-

/// * both be derived from a pointer to the same [allocated object], and the memory range between

`

``

606

`+

/// * both be [derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between

`

615

607

`/// the two pointers must be in bounds of that object. (See below for an example.)

`

616

608

`///

`

617

609

`/// * The distance between the pointers, in bytes, must be an exact multiple

`

`@@ -871,7 +863,7 @@ impl<T: ?Sized> *const T {

`

871

863

`` /// * The offset in bytes, count * size_of::<T>(), computed on mathematical integers (without

``

872

864

`` /// "wrapping around"), must fit in an isize.

``

873

865

`///

`

874

``

`` -

/// * If the computed offset is non-zero, then self must be derived from a pointer to some

``

``

866

`` +

/// * If the computed offset is non-zero, then self must be [derived from][crate::ptr#provenance] a pointer to some

``

875

867

`` /// [allocated object], and the entire memory range between self and the result must be in

``

876

868

`/// bounds of that allocated object. In particular, this range must not "wrap around" the edge

`

877

869

`/// of the address space.

`

`@@ -978,7 +970,7 @@ impl<T: ?Sized> *const T {

`

978

970

`` /// * The offset in bytes, count * size_of::<T>(), computed on mathematical integers (without

``

979

971

`` /// "wrapping around"), must fit in an isize.

``

980

972

`///

`

981

``

`` -

/// * If the computed offset is non-zero, then self must be derived from a pointer to some

``

``

973

`` +

/// * If the computed offset is non-zero, then self must be [derived from][crate::ptr#provenance] a pointer to some

``

982

974

`` /// [allocated object], and the entire memory range between self and the result must be in

``

983

975

`/// bounds of that allocated object. In particular, this range must not "wrap around" the edge

`

984

976

`/// of the address space.

`