authorbors <bors@rust-lang.org> 2026-06-28 11:10:25 UTC
committerbors <bors@rust-lang.org> 2026-06-28 11:10:25 UTC
logb4486cacf58926f02e451d96e71e20882faf5453
tree0c1b4dadca2ec3ba45c683cc93a71d69c97f30a9
parent11823209557bba4f6acb520109c63aa78c041683
parent3d31306f1dc081eeaf46e7890e84274963869305

Auto merge of #157575 - hanna-kruppe:merge-strict-provenance-lints, r=RalfJung

Merge and reframe strict_provenance_lints There does not seem to be any good reason to have separate lints for ptr2int and int2ptr casts. The main reason to enable this lint is to help with replacing `as` casts with strict provenance APIs (if possible) or explicit provenance APIs (when needed). That applies equally to both directions. Merging the lints requires coming up with new name and lint explanation. This is a good chance to reconsider the purpose and messaging of the lints which have been essentially unchanged since the early days of the "strict provenance experiment". For reasons described below, I called the merged lint `implicit_provenance_casts`, rewrote its explanation from scratch, and made some changes to diagnostics. First, the lint is not (only) about strict provenance any more. While strict provenance is often the best fix, migrating `as` casts to exposed provenance APIs also silences the lint. The exposed provenance APIs aren't any better for Miri and CHERI, but at least provenance considerations are made *explicit*, not picked up as side effect of the `as` keyword. (Banning use of exposed provenance APIs can be done with clippy's existing `disallowed_methods` lint.) Second, provenance is now officially part of the language and prominently explained in the `std::ptr` documentation. The new lint refers to those docs and is more consistent with them. Third, while strict provenance is encouraged whenever possible, exposed provenance is also part of the language and here to stay. Indeed, if we eventually enable the lint by default and make it `cargo fix`-able to keep the ecosystem migration manageable, we may want to suggest exposed provenance APIs to err on the side of not introducing UB. Thus, I made the diagnostics more neutral and descriptive. I've kept the suggestions that introduce strict provenance APIs, but we may want to reconsider this later. Tracking issue: rust-lang/rust#130351

28 files changed, 253 insertions(+), 291 deletions(-)

compiler/rustc_lint/src/fuzzy_provenance_casts.rs deleted-79
......@@ -1,79 +0,0 @@
1use rustc_hir as hir;
2use rustc_session::{declare_lint, declare_lint_pass};
3
4use crate::lints::{LossyProvenanceInt2Ptr, LossyProvenanceInt2PtrSuggestion};
5use crate::{LateContext, LateLintPass};
6
7declare_lint! {
8 /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
9 /// and a pointer.
10 ///
11 /// ### Example
12 ///
13 /// ```rust
14 /// #![feature(strict_provenance_lints)]
15 /// #![warn(fuzzy_provenance_casts)]
16 ///
17 /// fn main() {
18 /// let _dangling = 16_usize as *const u8;
19 /// }
20 /// ```
21 ///
22 /// {{produces}}
23 ///
24 /// ### Explanation
25 ///
26 /// This lint is part of the strict provenance effort, see [issue #95228].
27 /// Casting an integer to a pointer is considered bad style, as a pointer
28 /// contains, besides the *address* also a *provenance*, indicating what
29 /// memory the pointer is allowed to read/write. Casting an integer, which
30 /// doesn't have provenance, to a pointer requires the compiler to assign
31 /// (guess) provenance. The compiler assigns "all exposed valid" (see the
32 /// docs of [`ptr::with_exposed_provenance`] for more information about this
33 /// "exposing"). This penalizes the optimiser and is not well suited for
34 /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
35 /// platforms).
36 ///
37 /// It is much better to use [`ptr::with_addr`] instead to specify the
38 /// provenance you want. If using this function is not possible because the
39 /// code relies on exposed provenance then there is as an escape hatch
40 /// [`ptr::with_exposed_provenance`].
41 ///
42 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
43 /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr
44 /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html
45 pub FUZZY_PROVENANCE_CASTS,
46 Allow,
47 "a fuzzy integer to pointer cast is used",
48 @feature_gate = strict_provenance_lints;
49}
50
51declare_lint_pass!(
52 /// Lint for `as` casts between an integer and a pointer.
53 FuzzyProvenanceCasts => [FUZZY_PROVENANCE_CASTS]
54);
55
56impl<'tcx> LateLintPass<'tcx> for FuzzyProvenanceCasts {
57 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
58 let hir::ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind else { return };
59
60 let typeck_results = cx.typeck_results();
61 // Only lint casts from integer to pointer
62 let cast_from_ty = typeck_results.expr_ty(cast_from_expr);
63 if !cast_from_ty.is_integral() {
64 return;
65 }
66 let cast_to_ty = typeck_results.expr_ty(expr);
67 if !cast_to_ty.is_raw_ptr() {
68 return;
69 }
70
71 let sugg =
72 expr.span.can_be_used_for_suggestions().then(|| LossyProvenanceInt2PtrSuggestion {
73 lo: cast_from_expr.span.shrink_to_lo(),
74 hi: cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span),
75 });
76 let lint = LossyProvenanceInt2Ptr { expr_ty: cast_from_ty, cast_ty: cast_to_ty, sugg };
77 cx.tcx.emit_node_span_lint(FUZZY_PROVENANCE_CASTS, expr.hir_id, expr.span, lint)
78 }
79}
compiler/rustc_lint/src/implicit_provenance_casts.rs created+122
......@@ -0,0 +1,122 @@
1use rustc_ast::util::parser::ExprPrecedence;
2use rustc_hir as hir;
3use rustc_middle::ty::Ty;
4use rustc_session::{declare_lint, declare_lint_pass};
5
6use crate::lints::{
7 ImplicitProvenanceCastsInt2Ptr, ImplicitProvenanceCastsPtr2Int, Int2PtrSuggestion,
8 Ptr2IntSuggestion,
9};
10use crate::{LateContext, LateLintPass};
11
12declare_lint! {
13 /// The `implicit_provenance_casts` lint detects integer-to-pointer and pointer-to-integer
14 /// casts.
15 ///
16 /// ### Example
17 ///
18 /// ```rust
19 /// #![feature(strict_provenance_lints)]
20 /// #![warn(implicit_provenance_casts)]
21 ///
22 /// fn main() {
23 /// let x: u8 = 37;
24 /// let addr: usize = &x as *const u8 as usize;
25 /// let _ptr = addr as *const u8;
26 /// }
27 /// ```
28 ///
29 /// {{produces}}
30 ///
31 /// ### Explanation
32 ///
33 /// This lint exists to help migrate code to [*Strict Provenance* APIs][strict-provenance] where
34 /// possible, and make remaining uses of [*Exposed Provenance*][exposed-provenance] explicit.
35 /// For more information on pointer provenance, see the [`std::ptr` documentation][provenance].
36 ///
37 /// Earlier versions of Rust did not have a clear answer how integer-to-pointer and
38 /// pointer-to-integer casts interact with provenance. Such casts are now defined to use the
39 /// exposed provenance model, but in many cases the code can be updated to strict provenance
40 /// APIs, which is preferable as it enables more precise reasoning about unsafe code, both by
41 /// humans and by tools like [Miri].
42 ///
43 /// However, there are situations where exposed provenance is required or following the strict
44 /// provenance model requires major refactorings. In those cases, it's still useful to replace
45 /// the `as` casts with equivalent explicit use of exposed provenance APIs and a comment
46 /// explaining why they are needed.
47 ///
48 /// [provenance]: https://doc.rust-lang.org/core/ptr/index.html#provenance
49 /// [strict-provenance]: https://doc.rust-lang.org/core/ptr/index.html#strict-provenance
50 /// [exposed-provenance]: https://doc.rust-lang.org/core/ptr/index.html#exposed-provenance
51 /// [Miri]: https://github.com/rust-lang/miri
52 pub IMPLICIT_PROVENANCE_CASTS,
53 Allow,
54 "an `as` cast relying on exposed provenance is used",
55 @feature_gate = strict_provenance_lints;
56}
57
58declare_lint_pass!(
59 /// Lint for int2ptr and ptr2int `as` casts.
60 ImplicitProvenanceCasts => [IMPLICIT_PROVENANCE_CASTS]
61);
62
63impl<'tcx> LateLintPass<'tcx> for ImplicitProvenanceCasts {
64 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
65 let hir::ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind else { return };
66
67 let typeck_results = cx.typeck_results();
68 let cast_from_ty = typeck_results.expr_ty(cast_from_expr);
69 if cast_from_ty.is_raw_ptr() {
70 let cast_to_ty = typeck_results.expr_ty(expr);
71 if cast_to_ty.is_integral() {
72 lint_ptr2int(cx, expr, cast_from_expr, cast_from_ty, cast_to_hir, cast_to_ty)
73 }
74 } else if cast_from_ty.is_integral() {
75 let cast_to_ty = typeck_results.expr_ty(expr);
76 if cast_to_ty.is_raw_ptr() {
77 lint_int2ptr(cx, expr, cast_from_expr, cast_from_ty, cast_to_hir, cast_to_ty)
78 }
79 }
80 }
81}
82
83fn lint_ptr2int<'tcx>(
84 cx: &LateContext<'tcx>,
85 expr: &'tcx hir::Expr<'tcx>,
86 cast_from_expr: &'tcx hir::Expr<'tcx>,
87 cast_from_ty: Ty<'tcx>,
88 cast_to_hir: &'tcx hir::Ty<'tcx>,
89 cast_to_ty: Ty<'tcx>,
90) {
91 let sugg = expr.span.can_be_used_for_suggestions().then(|| {
92 let needs_parens = cx.precedence(cast_from_expr) < ExprPrecedence::Unambiguous;
93 let needs_cast = !cast_to_ty.is_usize();
94 let cast_span = cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span);
95 let expr_span = cast_from_expr.span.shrink_to_lo();
96 match (needs_parens, needs_cast) {
97 (true, true) => Ptr2IntSuggestion::NeedsParensCast { expr_span, cast_span, cast_to_ty },
98 (true, false) => Ptr2IntSuggestion::NeedsParens { expr_span, cast_span },
99 (false, true) => Ptr2IntSuggestion::NeedsCast { cast_span, cast_to_ty },
100 (false, false) => Ptr2IntSuggestion::Other { cast_span },
101 }
102 });
103
104 let lint = ImplicitProvenanceCastsPtr2Int { cast_from_ty, cast_to_ty, sugg };
105 cx.tcx.emit_node_span_lint(IMPLICIT_PROVENANCE_CASTS, expr.hir_id, expr.span, lint);
106}
107
108fn lint_int2ptr<'tcx>(
109 cx: &LateContext<'tcx>,
110 expr: &'tcx hir::Expr<'tcx>,
111 cast_from_expr: &'tcx hir::Expr<'tcx>,
112 cast_from_ty: Ty<'tcx>,
113 cast_to_hir: &'tcx hir::Ty<'tcx>,
114 cast_to_ty: Ty<'tcx>,
115) {
116 let sugg = expr.span.can_be_used_for_suggestions().then(|| Int2PtrSuggestion {
117 lo: cast_from_expr.span.shrink_to_lo(),
118 hi: cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span),
119 });
120 let lint = ImplicitProvenanceCastsInt2Ptr { expr_ty: cast_from_ty, cast_ty: cast_to_ty, sugg };
121 cx.tcx.emit_node_span_lint(IMPLICIT_PROVENANCE_CASTS, expr.hir_id, expr.span, lint)
122}
compiler/rustc_lint/src/lib.rs+5-6
......@@ -45,10 +45,10 @@ mod expect;
4545mod for_loops_over_fallibles;
4646mod foreign_modules;
4747mod function_cast_as_integer;
48mod fuzzy_provenance_casts;
4948mod gpukernel_abi;
5049mod if_let_rescope;
5150mod impl_trait_overcaptures;
51mod implicit_provenance_casts;
5252mod interior_mutable_consts;
5353mod internal;
5454mod invalid_from_utf8;
......@@ -57,7 +57,6 @@ mod let_underscore;
5757mod levels;
5858pub mod lifetime_syntax;
5959mod lints;
60mod lossy_provenance_casts;
6160mod macro_expr_fragment_specifier_2024_migration;
6261mod map_unit_fn;
6362mod multiple_supertrait_upcastable;
......@@ -95,16 +94,15 @@ use drop_forget_useless::*;
9594use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
9695use for_loops_over_fallibles::*;
9796use function_cast_as_integer::*;
98use fuzzy_provenance_casts::FuzzyProvenanceCasts;
9997use gpukernel_abi::*;
10098use if_let_rescope::IfLetRescope;
10199use impl_trait_overcaptures::ImplTraitOvercaptures;
100use implicit_provenance_casts::ImplicitProvenanceCasts;
102101use interior_mutable_consts::*;
103102use internal::*;
104103use invalid_from_utf8::*;
105104use let_underscore::*;
106105use lifetime_syntax::*;
107use lossy_provenance_casts::LossyProvenanceCasts;
108106use macro_expr_fragment_specifier_2024_migration::*;
109107use map_unit_fn::*;
110108use multiple_supertrait_upcastable::*;
......@@ -270,8 +268,7 @@ late_lint_methods!(
270268 CheckTransmutes: CheckTransmutes,
271269 LifetimeSyntax: LifetimeSyntax,
272270 InternalEqTraitMethodImpls: InternalEqTraitMethodImpls,
273 FuzzyProvenanceCasts: FuzzyProvenanceCasts,
274 LossyProvenanceCasts: LossyProvenanceCasts,
271 ImplicitProvenanceCasts: ImplicitProvenanceCasts,
275272 ]
276273 ]
277274);
......@@ -410,6 +407,8 @@ fn register_builtins(store: &mut LintStore) {
410407 store.register_renamed("static_mut_ref", "static_mut_refs");
411408 store.register_renamed("temporary_cstring_as_ptr", "dangling_pointers_from_temporaries");
412409 store.register_renamed("elided_named_lifetimes", "mismatched_lifetime_syntaxes");
410 store.register_renamed("fuzzy_provenance_casts", "implicit_provenance_casts");
411 store.register_renamed("lossy_provenance_casts", "implicit_provenance_casts");
413412
414413 // These were moved to tool lints, but rustc still sees them when compiling normally, before
415414 // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use
compiler/rustc_lint/src/lints.rs+13-15
......@@ -2934,23 +2934,24 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
29342934pub(crate) struct EqInternalMethodImplemented;
29352935
29362936#[derive(Diagnostic)]
2937#[diag("strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`")]
2937#[diag("cast from `{$expr_ty}` to `{$cast_ty}` implicitly relies on exposed provenance")]
29382938#[help(
2939 "if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead"
2939 "if conforming to strict provenance is not possible, use `std::ptr::with_exposed_provenance()`"
29402940)]
2941pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
2941#[note("for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>")]
2942pub(crate) struct ImplicitProvenanceCastsInt2Ptr<'tcx> {
29422943 pub expr_ty: Ty<'tcx>,
29432944 pub cast_ty: Ty<'tcx>,
29442945 #[subdiagnostic]
2945 pub sugg: Option<LossyProvenanceInt2PtrSuggestion>,
2946 pub sugg: Option<Int2PtrSuggestion>,
29462947}
29472948
29482949#[derive(Subdiagnostic)]
29492950#[multipart_suggestion(
2950 "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address",
2951 "use `.with_addr()` to adjust the address of a valid pointer in the same allocation",
29512952 applicability = "has-placeholders"
29522953)]
2953pub(crate) struct LossyProvenanceInt2PtrSuggestion {
2954pub(crate) struct Int2PtrSuggestion {
29542955 #[suggestion_part(code = "(...).with_addr(")]
29552956 pub lo: Span,
29562957 #[suggestion_part(code = ")")]
......@@ -2958,21 +2959,18 @@ pub(crate) struct LossyProvenanceInt2PtrSuggestion {
29582959}
29592960
29602961#[derive(Diagnostic)]
2961#[diag(
2962 "under strict provenance it is considered bad style to cast pointer `{$cast_from_ty}` to integer `{$cast_to_ty}`"
2963)]
2964#[help(
2965 "if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead"
2966)]
2967pub(crate) struct LossyProvenancePtr2Int<'tcx> {
2962#[diag("cast from `{$cast_from_ty}` to `{$cast_to_ty}` implicitly exposes pointer provenance")]
2963#[help("if conforming to strict provenance is not possible, use `.expose_provenance()`")]
2964#[note("for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>")]
2965pub(crate) struct ImplicitProvenanceCastsPtr2Int<'tcx> {
29682966 pub cast_from_ty: Ty<'tcx>,
29692967 pub cast_to_ty: Ty<'tcx>,
29702968 #[subdiagnostic]
2971 pub sugg: Option<LossyProvenancePtr2IntSuggestion<'tcx>>,
2969 pub sugg: Option<Ptr2IntSuggestion<'tcx>>,
29722970}
29732971
29742972#[derive(Subdiagnostic)]
2975pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> {
2973pub(crate) enum Ptr2IntSuggestion<'tcx> {
29762974 #[multipart_suggestion(
29772975 "use `.addr()` to obtain the address of a pointer",
29782976 applicability = "maybe-incorrect"
compiler/rustc_lint/src/lossy_provenance_casts.rs deleted-98
......@@ -1,98 +0,0 @@
1use rustc_ast::util::parser::ExprPrecedence;
2use rustc_hir as hir;
3use rustc_session::{declare_lint, declare_lint_pass};
4
5use crate::lints::{LossyProvenancePtr2Int, LossyProvenancePtr2IntSuggestion};
6use crate::{LateContext, LateLintPass};
7
8declare_lint! {
9 /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
10 /// and an integer.
11 ///
12 /// ### Example
13 ///
14 /// ```rust
15 /// #![feature(strict_provenance_lints)]
16 /// #![warn(lossy_provenance_casts)]
17 ///
18 /// fn main() {
19 /// let x: u8 = 37;
20 /// let _addr: usize = &x as *const u8 as usize;
21 /// }
22 /// ```
23 ///
24 /// {{produces}}
25 ///
26 /// ### Explanation
27 ///
28 /// This lint is part of the strict provenance effort, see [issue #95228].
29 /// Casting a pointer to an integer is a lossy operation, because beyond
30 /// just an *address* a pointer may be associated with a particular
31 /// *provenance*. This information is used by the optimiser and for dynamic
32 /// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
33 ///
34 /// Since this cast is lossy, it is considered good style to use the
35 /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
36 /// "expose" the pointer provenance. This improves optimisation potential.
37 /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information
38 /// about exposing pointer provenance.
39 ///
40 /// If your code can't comply with strict provenance and needs to expose
41 /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch,
42 /// which preserves the behaviour of `as usize` casts while being explicit
43 /// about the semantics.
44 ///
45 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
46 /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr
47 /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance
48 pub LOSSY_PROVENANCE_CASTS,
49 Allow,
50 "a lossy pointer to integer cast is used",
51 @feature_gate = strict_provenance_lints;
52}
53
54declare_lint_pass!(
55 /// Lint for `as` casts between a pointer and an integer.
56 LossyProvenanceCasts => [LOSSY_PROVENANCE_CASTS]
57);
58
59impl<'tcx> LateLintPass<'tcx> for LossyProvenanceCasts {
60 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
61 let hir::ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind else { return };
62
63 let typeck_results = cx.typeck_results();
64 // Only lint casts from pointer to integer
65 let cast_from_ty = typeck_results.expr_ty(cast_from_expr);
66 if !cast_from_ty.is_raw_ptr() {
67 return;
68 }
69 let cast_to_ty = typeck_results.expr_ty(expr);
70 if !cast_to_ty.is_integral() {
71 return;
72 }
73
74 let sugg = expr.span.can_be_used_for_suggestions().then(|| {
75 let needs_parens = cx.precedence(cast_from_expr) < ExprPrecedence::Unambiguous;
76 let needs_cast = !cast_to_ty.is_usize();
77 let cast_span = cast_from_expr.span.shrink_to_hi().to(cast_to_hir.span);
78 let expr_span = cast_from_expr.span.shrink_to_lo();
79 match (needs_parens, needs_cast) {
80 (true, true) => LossyProvenancePtr2IntSuggestion::NeedsParensCast {
81 expr_span,
82 cast_span,
83 cast_to_ty,
84 },
85 (true, false) => {
86 LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span }
87 }
88 (false, true) => {
89 LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_to_ty }
90 }
91 (false, false) => LossyProvenancePtr2IntSuggestion::Other { cast_span },
92 }
93 });
94
95 let lint = LossyProvenancePtr2Int { cast_from_ty, cast_to_ty, sugg };
96 cx.tcx.emit_node_span_lint(LOSSY_PROVENANCE_CASTS, expr.hir_id, expr.span, lint);
97 }
98}
library/alloc/src/lib.rs+1-2
......@@ -75,8 +75,7 @@
7575#![needs_allocator]
7676// Lints:
7777#![deny(unsafe_op_in_unsafe_fn)]
78#![deny(fuzzy_provenance_casts)]
79#![deny(lossy_provenance_casts)]
78#![deny(implicit_provenance_casts)]
8079#![warn(deprecated_in_future)]
8180#![warn(missing_debug_implementations)]
8281#![warn(missing_docs)]
library/alloctests/benches/lib.rs+1-2
......@@ -6,8 +6,7 @@
66#![feature(slice_partition_dedup)]
77#![feature(strict_provenance_lints)]
88#![feature(test)]
9#![deny(fuzzy_provenance_casts)]
10#![deny(lossy_provenance_casts)]
9#![deny(implicit_provenance_casts)]
1110
1211extern crate test;
1312
library/alloctests/tests/lib.rs+1-2
......@@ -43,8 +43,7 @@
4343#![feature(vec_try_remove)]
4444#![feature(ptr_cast_slice)]
4545#![allow(internal_features)]
46#![deny(fuzzy_provenance_casts)]
47#![deny(lossy_provenance_casts)]
46#![deny(implicit_provenance_casts)]
4847#![deny(unsafe_op_in_unsafe_fn)]
4948
5049extern crate alloc;
library/core/src/lib.rs+1-2
......@@ -68,8 +68,7 @@
6868// Lints:
6969#![deny(rust_2021_incompatible_or_patterns)]
7070#![deny(unsafe_op_in_unsafe_fn)]
71#![deny(fuzzy_provenance_casts)]
72#![deny(lossy_provenance_casts)]
71#![deny(implicit_provenance_casts)]
7372#![warn(deprecated_in_future)]
7473#![warn(missing_debug_implementations)]
7574#![warn(missing_docs)]
library/core/src/ptr/const_ptr.rs+1-1
......@@ -183,7 +183,7 @@ impl<T: PointeeSized> *const T {
183183 /// [`with_exposed_provenance`]: with_exposed_provenance
184184 #[inline(always)]
185185 #[stable(feature = "exposed_provenance", since = "1.84.0")]
186 #[expect(lossy_provenance_casts, reason = "this *is* the replacement")]
186 #[expect(implicit_provenance_casts, reason = "this *is* the replacement")]
187187 pub fn expose_provenance(self) -> usize {
188188 self.cast::<()>() as usize
189189 }
library/core/src/ptr/mod.rs+2-2
......@@ -1000,7 +1000,7 @@ pub const fn dangling_mut<T>() -> *mut T {
10001000#[stable(feature = "exposed_provenance", since = "1.84.0")]
10011001#[rustc_const_stable(feature = "const_exposed_provenance", since = "1.91.0")]
10021002#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1003#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
1003#[allow(implicit_provenance_casts)] // this *is* the explicit provenance API one should use instead
10041004pub const fn with_exposed_provenance<T>(addr: usize) -> *const T {
10051005 addr as *const T
10061006}
......@@ -1041,7 +1041,7 @@ pub const fn with_exposed_provenance<T>(addr: usize) -> *const T {
10411041#[stable(feature = "exposed_provenance", since = "1.84.0")]
10421042#[rustc_const_stable(feature = "const_exposed_provenance", since = "1.91.0")]
10431043#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1044#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
1044#[allow(implicit_provenance_casts)] // this *is* the explicit provenance API one should use instead
10451045pub const fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T {
10461046 addr as *mut T
10471047}
library/core/src/ptr/mut_ptr.rs+1-1
......@@ -174,7 +174,7 @@ impl<T: PointeeSized> *mut T {
174174 /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
175175 #[inline(always)]
176176 #[stable(feature = "exposed_provenance", since = "1.84.0")]
177 #[expect(lossy_provenance_casts, reason = "this *is* the replacement")]
177 #[expect(implicit_provenance_casts, reason = "this *is* the replacement")]
178178 pub fn expose_provenance(self) -> usize {
179179 self.cast::<()>() as usize
180180 }
library/coretests/tests/lib.rs+1-2
......@@ -128,8 +128,7 @@
128128#![feature(unwrap_infallible)]
129129// tidy-alphabetical-end
130130#![allow(internal_features)]
131#![deny(fuzzy_provenance_casts)]
132#![deny(lossy_provenance_casts)]
131#![deny(implicit_provenance_casts)]
133132#![deny(unsafe_op_in_unsafe_fn)]
134133
135134/// Version of `assert_matches` that ignores fancy runtime printing in const context and uses structural equality.
library/std/src/lib.rs+2-9
......@@ -245,8 +245,7 @@
245245#![allow(explicit_outlives_requirements)]
246246#![allow(unused_lifetimes)]
247247#![allow(internal_features)]
248#![deny(fuzzy_provenance_casts)]
249#![deny(lossy_provenance_casts)]
248#![deny(implicit_provenance_casts)]
250249#![deny(unsafe_op_in_unsafe_fn)]
251250#![allow(rustdoc::redundant_explicit_links)]
252251#![warn(rustdoc::unescaped_backticks)]
......@@ -726,13 +725,7 @@ pub mod alloc;
726725mod panicking;
727726
728727#[path = "../../backtrace/src/lib.rs"]
729#[allow(
730 dead_code,
731 unused_attributes,
732 fuzzy_provenance_casts,
733 lossy_provenance_casts,
734 unsafe_op_in_unsafe_fn
735)]
728#[allow(dead_code, unused_attributes, implicit_provenance_casts, unsafe_op_in_unsafe_fn)]
736729mod backtrace_rs;
737730
738731#[stable(feature = "cfg_select", since = "1.95.0")]
library/std/src/os/unix/thread.rs+2-2
......@@ -34,12 +34,12 @@ impl<T> JoinHandleExt for JoinHandle<T> {
3434 // This is an int2ptr cast on some platforms (e.g., *-musl) where RawPthread
3535 // is an integer but libc::pthread_t is a pointer. Exposed provenance is the
3636 // safe choice here, but `as` also works when it's int2int or ptr2ptr.
37 #[allow(lossy_provenance_casts)]
37 #[allow(implicit_provenance_casts)]
3838 fn as_pthread_t(&self) -> RawPthread {
3939 self.as_inner().id() as RawPthread
4040 }
4141
42 #[allow(lossy_provenance_casts)] // see above for why
42 #[allow(implicit_provenance_casts)] // see above for why
4343 fn into_pthread_t(self) -> RawPthread {
4444 self.into_inner().into_id() as RawPthread
4545 }
library/std/src/os/windows/io/socket.rs+1-1
......@@ -75,7 +75,7 @@ impl OwnedSocket {
7575 }
7676
7777 // FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
78 #[allow(fuzzy_provenance_casts)]
78 #[allow(implicit_provenance_casts)]
7979 #[cfg(not(target_vendor = "uwp"))]
8080 pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
8181 cvt(unsafe {
library/std/src/sys/args/sgx.rs+1-2
......@@ -1,5 +1,4 @@
1// FIXME: this module systematically confuses pointers and integers
2#![allow(fuzzy_provenance_casts, lossy_provenance_casts)]
1#![allow(implicit_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
32
43use crate::ffi::OsString;
54use crate::num::NonZero;
library/std/src/sys/env/sgx.rs+1-2
......@@ -1,5 +1,4 @@
1// FIXME: this module systematically confuses pointers and integers
2#![allow(fuzzy_provenance_casts, lossy_provenance_casts)]
1#![allow(implicit_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
32
43pub use super::common::Env;
54use crate::collections::HashMap;
library/std/src/sys/pal/sgx/mod.rs+1-2
......@@ -3,8 +3,7 @@
33//! This module contains the facade (aka platform-specific) implementations of
44//! OS level functionality for Fortanix SGX.
55#![deny(unsafe_op_in_unsafe_fn)]
6// FIXME: this entire module systematically confuses pointers and integers
7#![allow(fuzzy_provenance_casts, lossy_provenance_casts)]
6#![allow(implicit_provenance_casts)] // FIXME: this entire module systematically confuses pointers and integers
87
98use crate::io;
109use crate::sync::atomic::{Atomic, AtomicBool, Ordering};
src/doc/unstable-book/src/language-features/strict-provenance-lints.md+6-5
......@@ -5,17 +5,18 @@ The tracking issue for this feature is: [#130351]
55[#130351]: https://github.com/rust-lang/rust/issues/130351
66-----
77
8The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
9These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.
8The `strict_provenance_lints` feature allows to enable the `implicit_provenance_casts` lint.
109
1110## Example
1211
1312```rust
1413#![feature(strict_provenance_lints)]
15#![warn(fuzzy_provenance_casts)]
14#![warn(implicit_provenance_casts)]
1615
1716fn main() {
18 let _dangling = 16_usize as *const u8;
19 //~^ WARNING: strict provenance disallows casting integer `usize` to pointer `*const u8`
17 let dangling = 16_usize as *const u8;
18 //~^ WARNING: cast from `usize` to `*const u8` implicitly relies on exposed provenance
19 let _addr = dangling as usize;
20 //~^ WARNING: cast from `*const u8` to `usize` implicitly exposes pointer provenance
2021}
2122```
tests/ui/feature-gates/feature-gate-strict_provenance_lints.rs+8-2
......@@ -1,9 +1,15 @@
11//@ check-pass
22
3#![deny(implicit_provenance_casts)]
4//~^ WARNING unknown lint: `implicit_provenance_casts`
5
6// feature-gating also applies when the old names are helpfully replaced with the new one:
37#![deny(fuzzy_provenance_casts)]
4//~^ WARNING unknown lint: `fuzzy_provenance_casts`
8//~^ WARNING lint `fuzzy_provenance_casts` has been renamed to `implicit_provenance_casts`
9//~| WARNING unknown lint: `implicit_provenance_casts`
510#![deny(lossy_provenance_casts)]
6//~^ WARNING unknown lint: `lossy_provenance_casts`
11//~^ WARNING lint `lossy_provenance_casts` has been renamed to `implicit_provenance_casts`
12//~| WARNING unknown lint: `implicit_provenance_casts`
713
814fn main() {
915 // no warnings emitted since the lints are not activated
tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr+32-7
......@@ -1,25 +1,50 @@
1warning: unknown lint: `fuzzy_provenance_casts`
1warning: unknown lint: `implicit_provenance_casts`
22 --> $DIR/feature-gate-strict_provenance_lints.rs:3:9
33 |
4LL | #![deny(implicit_provenance_casts)]
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7 = note: the `implicit_provenance_casts` lint is unstable
8 = note: see issue #130351 <https://github.com/rust-lang/rust/issues/130351> for more information
9 = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable
10 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
11 = note: `#[warn(unknown_lints)]` on by default
12
13warning: lint `fuzzy_provenance_casts` has been renamed to `implicit_provenance_casts`
14 --> $DIR/feature-gate-strict_provenance_lints.rs:7:9
15 |
16LL | #![deny(fuzzy_provenance_casts)]
17 | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts`
18 |
19 = note: `#[warn(renamed_and_removed_lints)]` on by default
20
21warning: unknown lint: `implicit_provenance_casts`
22 --> $DIR/feature-gate-strict_provenance_lints.rs:7:9
23 |
424LL | #![deny(fuzzy_provenance_casts)]
525 | ^^^^^^^^^^^^^^^^^^^^^^
626 |
7 = note: the `fuzzy_provenance_casts` lint is unstable
27 = note: the `implicit_provenance_casts` lint is unstable
828 = note: see issue #130351 <https://github.com/rust-lang/rust/issues/130351> for more information
929 = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable
1030 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
11 = note: `#[warn(unknown_lints)]` on by default
1231
13warning: unknown lint: `lossy_provenance_casts`
14 --> $DIR/feature-gate-strict_provenance_lints.rs:5:9
32warning: lint `lossy_provenance_casts` has been renamed to `implicit_provenance_casts`
33 --> $DIR/feature-gate-strict_provenance_lints.rs:10:9
34 |
35LL | #![deny(lossy_provenance_casts)]
36 | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `implicit_provenance_casts`
37
38warning: unknown lint: `implicit_provenance_casts`
39 --> $DIR/feature-gate-strict_provenance_lints.rs:10:9
1540 |
1641LL | #![deny(lossy_provenance_casts)]
1742 | ^^^^^^^^^^^^^^^^^^^^^^
1843 |
19 = note: the `lossy_provenance_casts` lint is unstable
44 = note: the `implicit_provenance_casts` lint is unstable
2045 = note: see issue #130351 <https://github.com/rust-lang/rust/issues/130351> for more information
2146 = help: add `#![feature(strict_provenance_lints)]` to the crate attributes to enable
2247 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2348
24warning: 2 warnings emitted
49warning: 5 warnings emitted
2550
tests/ui/lint/lint-strict-provenance-fuzzy-casts.rs+2-2
......@@ -1,7 +1,7 @@
11#![feature(strict_provenance_lints)]
2#![deny(fuzzy_provenance_casts)]
2#![deny(implicit_provenance_casts)]
33
44fn main() {
55 let dangling = 16_usize as *const u8;
6 //~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
6 //~^ ERROR cast from `usize` to `*const u8` implicitly relies on exposed provenance
77}
tests/ui/lint/lint-strict-provenance-fuzzy-casts.stderr+6-5
......@@ -1,16 +1,17 @@
1error: strict provenance disallows casting integer `usize` to pointer `*const u8`
1error: cast from `usize` to `*const u8` implicitly relies on exposed provenance
22 --> $DIR/lint-strict-provenance-fuzzy-casts.rs:5:20
33 |
44LL | let dangling = 16_usize as *const u8;
55 | ^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
7 = help: if conforming to strict provenance is not possible, use `std::ptr::with_exposed_provenance()`
8 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
89note: the lint level is defined here
910 --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
1011 |
11LL | #![deny(fuzzy_provenance_casts)]
12 | ^^^^^^^^^^^^^^^^^^^^^^
13help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
12LL | #![deny(implicit_provenance_casts)]
13 | ^^^^^^^^^^^^^^^^^^^^^^^^^
14help: use `.with_addr()` to adjust the address of a valid pointer in the same allocation
1415 |
1516LL - let dangling = 16_usize as *const u8;
1617LL + let dangling = (...).with_addr(16_usize);
tests/ui/lint/lint-strict-provenance-lossy-casts.rs+5-5
......@@ -1,18 +1,18 @@
11#![feature(strict_provenance_lints)]
2#![deny(lossy_provenance_casts)]
2#![deny(implicit_provenance_casts)]
33
44fn main() {
55 let x: u8 = 37;
66 let addr: usize = &x as *const u8 as usize;
7 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
7 //~^ ERROR cast from `*const u8` to `usize` implicitly exposes pointer provenance
88
99 let addr_32bit = &x as *const u8 as u32;
10 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
10 //~^ ERROR cast from `*const u8` to `u32` implicitly exposes pointer provenance
1111
1212 // don't add unnecessary parens in the suggestion
1313 let ptr = &x as *const u8;
1414 let ptr_addr = ptr as usize;
15 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
15 //~^ ERROR cast from `*const u8` to `usize` implicitly exposes pointer provenance
1616 let ptr_addr_32bit = ptr as u32;
17 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
17 //~^ ERROR cast from `*const u8` to `u32` implicitly exposes pointer provenance
1818}
tests/ui/lint/lint-strict-provenance-lossy-casts.stderr+14-10
......@@ -1,34 +1,36 @@
1error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
1error: cast from `*const u8` to `usize` implicitly exposes pointer provenance
22 --> $DIR/lint-strict-provenance-lossy-casts.rs:6:23
33 |
44LL | let addr: usize = &x as *const u8 as usize;
55 | ^^^^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
7 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
8 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
89note: the lint level is defined here
910 --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
1011 |
11LL | #![deny(lossy_provenance_casts)]
12 | ^^^^^^^^^^^^^^^^^^^^^^
12LL | #![deny(implicit_provenance_casts)]
13 | ^^^^^^^^^^^^^^^^^^^^^^^^^
1314help: use `.addr()` to obtain the address of a pointer
1415 |
1516LL - let addr: usize = &x as *const u8 as usize;
1617LL + let addr: usize = (&x as *const u8).addr();
1718 |
1819
19error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
20error: cast from `*const u8` to `u32` implicitly exposes pointer provenance
2021 --> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
2122 |
2223LL | let addr_32bit = &x as *const u8 as u32;
2324 | ^^^^^^^^^^^^^^^^^^^^^^
2425 |
25 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
26 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
27 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
2628help: use `.addr()` to obtain the address of a pointer
2729 |
2830LL | let addr_32bit = (&x as *const u8).addr() as u32;
2931 | + ++++++++
3032
31error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
33error: cast from `*const u8` to `usize` implicitly exposes pointer provenance
3234 --> $DIR/lint-strict-provenance-lossy-casts.rs:14:20
3335 |
3436LL | let ptr_addr = ptr as usize;
......@@ -36,9 +38,10 @@ LL | let ptr_addr = ptr as usize;
3638 | |
3739 | help: use `.addr()` to obtain the address of a pointer: `.addr()`
3840 |
39 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
41 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
42 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
4043
41error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
44error: cast from `*const u8` to `u32` implicitly exposes pointer provenance
4245 --> $DIR/lint-strict-provenance-lossy-casts.rs:16:26
4346 |
4447LL | let ptr_addr_32bit = ptr as u32;
......@@ -46,7 +49,8 @@ LL | let ptr_addr_32bit = ptr as u32;
4649 | |
4750 | help: use `.addr()` to obtain the address of a pointer: `.addr() as u32`
4851 |
49 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
52 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
53 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
5054
5155error: aborting due to 4 previous errors
5256
tests/ui/lint/lint-strict-provenance-macro-casts.rs+5-6
......@@ -1,23 +1,22 @@
11#![feature(strict_provenance_lints)]
2#![deny(lossy_provenance_casts)]
3#![deny(fuzzy_provenance_casts)]
2#![deny(implicit_provenance_casts)]
43
54macro_rules! cast {
65 ($e:expr, $t:ty) => {
76 $e as $t
8 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
9 //~| ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
7 //~^ ERROR cast from `*const u8` to `usize`
8 //~| ERROR cast from `usize` to `*const u8`
109 };
1110}
1211
1312macro_rules! p2i {
1413 ($e:expr) => { $e as usize };
15 //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
14 //~^ ERROR cast from `*const u8` to `usize`
1615}
1716
1817macro_rules! i2p {
1918 ($e:expr) => { $e as *const () };
20 //~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const ()`
19 //~^ ERROR cast from `usize` to `*const ()`
2120}
2221
2322fn main() {
tests/ui/lint/lint-strict-provenance-macro-casts.stderr+18-19
......@@ -1,5 +1,5 @@
1error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
2 --> $DIR/lint-strict-provenance-macro-casts.rs:7:9
1error: cast from `*const u8` to `usize` implicitly exposes pointer provenance
2 --> $DIR/lint-strict-provenance-macro-casts.rs:6:9
33 |
44LL | $e as $t
55 | ^^^^^^^^
......@@ -7,16 +7,17 @@ LL | $e as $t
77LL | let _addr = cast!(ptr, usize);
88 | ----------------- in this macro invocation
99 |
10 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
10 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
11 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
1112note: the lint level is defined here
1213 --> $DIR/lint-strict-provenance-macro-casts.rs:2:9
1314 |
14LL | #![deny(lossy_provenance_casts)]
15 | ^^^^^^^^^^^^^^^^^^^^^^
15LL | #![deny(implicit_provenance_casts)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^
1617 = note: this error originates in the macro `cast` (in Nightly builds, run with -Z macro-backtrace for more info)
1718
18error: strict provenance disallows casting integer `usize` to pointer `*const u8`
19 --> $DIR/lint-strict-provenance-macro-casts.rs:7:9
19error: cast from `usize` to `*const u8` implicitly relies on exposed provenance
20 --> $DIR/lint-strict-provenance-macro-casts.rs:6:9
2021 |
2122LL | $e as $t
2223 | ^^^^^^^^
......@@ -24,16 +25,12 @@ LL | $e as $t
2425LL | let _ptr = cast!(0usize, *const u8);
2526 | ------------------------ in this macro invocation
2627 |
27 = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
28note: the lint level is defined here
29 --> $DIR/lint-strict-provenance-macro-casts.rs:3:9
30 |
31LL | #![deny(fuzzy_provenance_casts)]
32 | ^^^^^^^^^^^^^^^^^^^^^^
28 = help: if conforming to strict provenance is not possible, use `std::ptr::with_exposed_provenance()`
29 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
3330 = note: this error originates in the macro `cast` (in Nightly builds, run with -Z macro-backtrace for more info)
3431
35error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
36 --> $DIR/lint-strict-provenance-macro-casts.rs:14:20
32error: cast from `*const u8` to `usize` implicitly exposes pointer provenance
33 --> $DIR/lint-strict-provenance-macro-casts.rs:13:20
3734 |
3835LL | ($e:expr) => { $e as usize };
3936 | ^^^^^^^^^^^
......@@ -41,11 +38,12 @@ LL | ($e:expr) => { $e as usize };
4138LL | p2i!(&raw const x);
4239 | ------------------ in this macro invocation
4340 |
44 = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
41 = help: if conforming to strict provenance is not possible, use `.expose_provenance()`
42 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
4543 = note: this error originates in the macro `p2i` (in Nightly builds, run with -Z macro-backtrace for more info)
4644
47error: strict provenance disallows casting integer `usize` to pointer `*const ()`
48 --> $DIR/lint-strict-provenance-macro-casts.rs:19:20
45error: cast from `usize` to `*const ()` implicitly relies on exposed provenance
46 --> $DIR/lint-strict-provenance-macro-casts.rs:18:20
4947 |
5048LL | ($e:expr) => { $e as *const () };
5149 | ^^^^^^^^^^^^^^^
......@@ -53,7 +51,8 @@ LL | ($e:expr) => { $e as *const () };
5351LL | i2p!(0x42);
5452 | ---------- in this macro invocation
5553 |
56 = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
54 = help: if conforming to strict provenance is not possible, use `std::ptr::with_exposed_provenance()`
55 = note: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html#provenance>
5756 = note: this error originates in the macro `i2p` (in Nightly builds, run with -Z macro-backtrace for more info)
5857
5958error: aborting due to 4 previous errors