Taking a raw ref (`&raw (const|mut)`) of a deref of pointer (`*ptr`) is always safe
T-opsem decided in https://github.com/rust-lang/reference/pull/1387 that `*ptr` is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read.
This also relaxes the `DEREF_NULLPTR` lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification.
This does not change the behavior of `addr_of!((*ptr).field)`, since field projections still require the projection is in-bounds.
I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc `@rust-lang/opsem`
Improve test coverage for `unit_bindings` lint
Follow-up to #112380, apparently at the time I didn't add much of any test coverage outside of just "generally works as intended on the test suites and in the crater run".
r? compiler
stabilize Strict Provenance and Exposed Provenance APIs
Given that [RFC 3559](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html) has been accepted, t-lang has approved the concept of provenance to exist in the language. So I think it's time that we stabilize the strict provenance and exposed provenance APIs, and discuss provenance explicitly in the docs:
```rust
// core::ptr
pub const fn without_provenance<T>(addr: usize) -> *const T;
pub const fn dangling<T>() -> *const T;
pub const fn without_provenance_mut<T>(addr: usize) -> *mut T;
pub const fn dangling_mut<T>() -> *mut T;
pub fn with_exposed_provenance<T>(addr: usize) -> *const T;
pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T;
impl<T: ?Sized> *const T {
pub fn addr(self) -> usize;
pub fn expose_provenance(self) -> usize;
pub fn with_addr(self, addr: usize) -> Self;
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self;
}
impl<T: ?Sized> *mut T {
pub fn addr(self) -> usize;
pub fn expose_provenance(self) -> usize;
pub fn with_addr(self, addr: usize) -> Self;
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self;
}
impl<T: ?Sized> NonNull<T> {
pub fn addr(self) -> NonZero<usize>;
pub fn with_addr(self, addr: NonZero<usize>) -> Self;
pub fn map_addr(self, f: impl FnOnce(NonZero<usize>) -> NonZero<usize>) -> Self;
}
```
I also did a pass over the docs to adjust them, because this is no longer an "experiment". The `ptr` docs now discuss the concept of provenance in general, and then they go into the two families of APIs for dealing with provenance: Strict Provenance and Exposed Provenance. I removed the discussion of how pointers also have an associated "address space" -- that is not actually tracked in the pointer value, it is tracked in the type, so IMO it just distracts from the core point of provenance. I also adjusted the docs for `with_exposed_provenance` to make it clear that we cannot guarantee much about this function, it's all best-effort.
There are two unstable lints associated with the strict_provenance feature gate; I moved them to a new [strict_provenance_lints](https://github.com/rust-lang/rust/issues/130351) feature since I didn't want this PR to have an even bigger FCP. ;)
`@rust-lang/opsem` Would be great to get some feedback on the docs here. :)
Nominating for `@rust-lang/libs-api.`
Part of https://github.com/rust-lang/rust/issues/95228.
[FCP comment](https://github.com/rust-lang/rust/pull/130350#issuecomment-2395114536)
Finish stabilization of `result_ffi_guarantees`
The internal linting has been changed, so all that is left is making sure we stabilize what we want to stabilize.
Allow `#[deny]` inside `#[forbid]` as a no-op
Forbid cannot be overriden. When someome tries to do this anyways, it results in a hard error. That makes sense.
Except it doesn't, because macros. Macros may reasonably use `#[deny]` (or `#[warn]` for an allow-by-default lint) in their expansion to assert that their expanded code follows the lint. This is doesn't work when the output gets expanded into a `forbid()` context. This is pretty silly, since both the macros and the code agree on the lint!
By making it a warning instead, we remove the problem with the macro, which is now nothing as warnings are suppressed in macro expanded code, while still telling users that something is up.
fixes#121483
Stop inverting expectation in normalization errors
We have some funky special case logic to invert the expectation and actual type for normalization errors depending on their cause code. IMO most of the error messages get better, except for `try {}` blocks' type expectations. I think that these need to be special cased in some other way, rather than via this hack.
Fixes#131763
Forbid cannot be overriden. When someome tries to do this anyways,
it results in a hard error. That makes sense.
Except it doesn't, because macros. Macros may reasonably use `#[deny]`
in their expansion to assert
that their expanded code follows the lint. This is doesn't work when the
output gets expanded into a `forbid()` context. This is pretty silly,
since both the macros and the code agree on the lint!
Therefore, we allow `#[deny(..)]`ing a lint that's already forbidden,
keeping the level at forbid.
The lint-non-snake-case-crate test may emit a warning in stderr if the
target does not support unwinding
```
warning: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
```
Consequently, the test will fail on targets that don't support unwinding
as written.
This change prevents lint-non-snake-case-crate#proc_macro_ from running
on targets that don't support unwind by using the needs-unwind
directive.
Remove deprecation note in the `non_local_definitions` lint
This PR removes the edition deprecation note emitted by the `non_local_definitions` lint.
Specifically this part:
```
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
```
because it [didn't make the cut](https://github.com/rust-lang/rust/issues/120363#issuecomment-2407833300) for the 2024 edition.
`@rustbot` label +L-non_local_definitions
Make unused_parens's suggestion considering expr's attributes.
For the expr with attributes,
like `let _ = (#[inline] || println!("Hello!"));`,
the suggestion's span should contains the attributes, or the suggestion will remove them.
fixes#129833
For the expr with attributes, like `let _ = (#[inline] || println!("Hello!"));`, the suggestion's span should contains the attributes, or the suggestion will remove them.
fixes#129833
Rename a few tests to make tidy happier
A somewhat random smattering of tests that I have recently looked at, and thus had cause to research and write down the reason for their existence.
Make clashing_extern_declarations considering generic args for ADT field
In following example, G<u16> should be recognized as different from G<u32> :
```rust
#[repr(C)] pub struct G<T> { g: [T; 4] }
pub mod x { extern "C" { pub fn g(_: super::G<u16>); } }
pub mod y { extern "C" { pub fn g(_: super::G<u32>); } }
```
fixes#130851
Revert "Add recursion limit to FFI safety lint"
It's not necessarily clear if warning when we hit the recursion limit is the right thing to do, first of all.
**More importantly**, this PR was implemented incorrectly in the first place; it was not decrementing the recursion limit when stepping out of a type, so it would trigger when a ctype has more than RECURSION_LIMIT fields *anywhere* in the type's set of recursively reachable fields.
Reverts #130598Reopens#130310Fixes#130757
Rework `non_local_definitions` lint to only use a syntactic heuristic
This PR reworks the `non_local_definitions` lint to only use a syntactic heuristic, i.e. not use a type-system logic for whenever an `impl` is local or not.
Instead the new logic wanted by T-lang in https://github.com/rust-lang/rust/issues/126768#issuecomment-2192634762, which is to consider every paths in `Self` and `Trait` and to no longer use the type-system inference trick.
`@rustbot` labels +L-non_local_definitions
Fixes#126768
tests: Test that `extern "C" fn` ptrs lint on slices
This seems to have slipped past the `improper_ctypes_definitions` lint at some point. I found similar tests but not one with this exact combination, so test the semi-unique combination.