Skip to content

Invalid suggestions from strict provenance lint with macros #156850

@hanna-kruppe

Description

@hanna-kruppe

Code

#![feature(strict_provenance_lints)]
#![deny(fuzzy_provenance_casts, lossy_provenance_casts)]

macro_rules! p2i {
    ($e:expr) => { $e as usize };
}

macro_rules! i2p {
    ($e:expr) => { $e as *const () };
}

pub fn foo() {
    p2i!(&raw const 1u8);
    i2p!(0x42);
}

Current output

error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
  --> src/lib.rs:5:20
   |
 5 |     ($e:expr) => { $e as usize };
   |                    ^^^^^^^^^^^
...
14 |     p2i!(&raw const x);
   |     ------------------ in this macro invocation
   |
   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
note: the lint level is defined here
  --> src/lib.rs:2:33
   |
 2 | #![deny(fuzzy_provenance_casts, lossy_provenance_casts)]
   |                                 ^^^^^^^^^^^^^^^^^^^^^^
   = note: this error originates in the macro `p2i` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `.addr()` to obtain the address of a pointer
   |
 5 ~     ($e:expr) => { $e as ).addr() };
 6 | }
...
13 |     let x = 0u8;
14 ~     p2i!((&raw const x);
   |

error: strict provenance disallows casting integer `usize` to pointer `*const ()`
  --> src/lib.rs:9:20
   |
 9 |     ($e:expr) => { $e as *const () };
   |                    ^^^^^^^^^^^^^^^
...
15 |     i2p!(0x42);
   |     ---------- in this macro invocation
   |
   = 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
note: the lint level is defined here
  --> src/lib.rs:2:9
   |
 2 | #![deny(fuzzy_provenance_casts, lossy_provenance_casts)]
   |         ^^^^^^^^^^^^^^^^^^^^^^
   = note: this error originates in the macro `i2p` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
   |
 9 ~     ($e:expr) => { $e as ) };
10 | }
...
14 |     p2i!(&raw const x);
15 ~     i2p!((...).with_addr(0x42);
   |

error: aborting due to 2 previous errors

Desired output

Rationale and extra context

No response

Other cases

Rust Version

$ rustc +nightly -vV
rustc 1.98.0-nightly (54333ff07 2026-05-22)
binary: rustc
commit-hash: 54333ff079780f803f65dcee30c544050b35f544
commit-date: 2026-05-22
host: x86_64-unknown-linux-gnu
release: 1.98.0-nightly
LLVM version: 22.1.6

Anything else?

This is likely caused by the span manipulation in code that emits the lints, may need some span.can_be_used_for_suggestions() guards:

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions