cmse: add test for `async` and `const` functions
tracking issue: https://github.com/rust-lang/rust/issues/81391
tracking issue: https://github.com/rust-lang/rust/issues/75835
Some additional tests that seemed useful while working on the RFC text.
`async` functions are disallowed (because `-> impl Trait` is not supported).
`const` entry functions are allowed, `nonsecure-call` does not make sense, because this abi can only be used on function pointers, which cannot be evaluated during constant evaluation.
The async test is in the `c-variadic.rs` file because it has the minicore-compatible machinery for defining an async function. Splitting that logic out (like `minisimd.rs`) turns out to be complicated because the async stuff relies on types defined by minicore.
r? `````@davidtwco`````
Adjust spans into the `for` loops context before creating the new desugaring spans.
When lowering `for` loops, the spans for the `into_iter` call and the `Some` pattern used the span of the provided pattern and head expression. If either of those came from a different `SyntaxContext` this would result in some very strange contexts. e.g.:
```rust
macro_rules! m { ($e:expr) => { { $e } } }
for _ in m!(expr) {}
```
This would result in the `into_iter` call have a context chain of `desugar => m!() => root` which is completely nonsensical; `m!()` does not have a `for` loop. The `into_iter` call also ends up located at `{ $e }` rather than inside the `for _ in _` part.
This fixes that by walking the spans up to the `for` loop's context first. This will not handle adjusting the location of macro variable expansions (e.g. `for _ in $e`), but this does adjust the context to match the `for` loops.
---
This ended up causing rust-lang/rust-clippy#16008. Clippy should be using a `debug_assert` rather than `unreachable`, but it still results in a bug either way.
[rustdoc] Fix invalid jump to def macro link generation
Follow-up of https://github.com/rust-lang/rust/issues/147820.
I realized that when there was no intra-doc link linking to the same item, then the generated link for macros in jump to def would be invalid.
To make the code less redundant, I merged the "registering" of items and the href generation use the same code for macros.
r? `````@notriddle`````
Improve diagnostics for buffer reuse with borrowed references
Addresses rust-lang/rust#147694
I'm not sure the current note wording is the best so I appreciate any feedback.
This is useful when you have two dependencies that use different trait for
the same thing and with the same name. The user can accidentally implement
the bad one which might be confusing. This commits refactorizes existing
diagnostics about multiple different crates with the same version and adds
a note when similarly named traits are found. All diagnostics are merged
into a single one.
Document (and test) a problem with `Clone`/`Copy` deriving.
I think this is useful information. I have worked on `derive` impls quite a bit and didn't know about this issue until today.
r? `@saethlin`
Port `cfg_select!` to the new attribute parsing system
Best reviewed commit by commit, since it involves some moving around of code
r? `````@jdonszelmann`````
Check unsafety for non-macro attributes in `validate_attr`
r? `````@jdonszelmann`````
Also adds a test for a previously untested case, unnecessary unsafe on a proc macro attribute
In preparation for https://github.com/rust-lang/rust/issues/148453
Provide more context when mutably borrowing an imutably borrowed value
Point at statics and consts being mutable borrowed or written to:
```
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:4:5
|
LL | static NUM: i32 = 18;
| --------------- this `static` cannot be written to
...
LL | NUM = 20;
| ^^^^^^^^ cannot assign
```
Point at the expression that couldn't be mutably borrowed from a pattern:
```
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/mut-pattern-of-immutable-borrow.rs:19:14
|
LL | match &arg.field {
| ---------- this cannot be borrowed as mutable
LL | Some(ref mut s) => s.push('a'),
| ^^^^^^^^^ cannot borrow as mutable
```
Partially address rust-lang/rust#74617.
Special case detecting `'static` lifetime requirement coming from `-> Box<dyn Trait>`
```
error[E0310]: the parameter type `R` may not live long enough
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:10:5
|
LL | fn bb<R>(r: R) -> Box<dyn Foo> {
| ------- this `dyn Trait` has an implicit `'static` lifetime bound
LL | Box::new(Bar(r))
| ^^^^^^^^^^^^^^^^
| |
| the parameter type `R` must be valid for the static lifetime...
| ...so that the type `R` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
LL | fn bb<R: 'static>(r: R) -> Box<dyn Foo> {
| +++++++++
```
Partly address rust-lang/rust#41966 and rust-lang/rust#54753. rust-lang/rust#103849, which shows a case where there's an intermediary binding, is not addressed at all, as aren't cases *other* than `Box<dyn Trait>` return type.
rustdoc: Erase `#![doc(document_private_items)]`
I just found out about the existence of `#![doc(document_private_items)]`. Apparently it was added by PR rust-lang/rust#50669 back in 2018 without any tests or docs as a replacement for some specific forms of the removed `#![doc(passes)]` / `#![doc(no_default_passes)]`.
However, rustc and rustdoc actually emit the deny-by-default lint `invalid_doc_attributes` for it (but if you allow it, the attribute does function)! To be more precise since PR rust-lang/rust#82708 (1.52, May 2021) which introduced lint `invalid_doc_attributes`, rust{,do}c has emitted a future-incompat warning for this attribute. And since PR rust-lang/rust#111505 (1.78, May 2024) that lint is deny by default. I presume nobody knew this attribute existed and thus it was never allowlisted.
Given the fact that since 2021 nobody has ever opened a ticket ([via](https://github.com/rust-lang/rust/issues?q=is%3Aissue+document_private_items)) complaining about the lint emission and the fact that GitHub code search doesn't yield any actual uses ([via](https://github.com/search?q=%2F%23%21%5C%5Bdoc%5C%28.*%3Fdocument_private_items%2F+language%3ARust&type=code&ref=advsearch)), I'm led to believe that nobody knows about and uses this attribute.
I don't find the existence of this attribute to be justified since in my view the flag `--document-private-items` is strictly superior: In most if not all cases, you don't want to "couple" your crate with this "mode" even if you gate it behind a cfg; instead, you most likely want to set this manually at invocation time, via a build config file like `.cargo/config.toml` or via a command runner like `just` I'd say.
Because of this I propose to wipe this attribute from existence. I don't believe it's worth cratering this (i.e., temporarily emitting a hard error for this attribute and running crater) given the fact that it's been undocumented since forever and led to a warning for years.
`c_variadic`: Add future-incompatibility warning for `...` arguments without a pattern outside of `extern` blocks
This PR makes `...` arguments without a pattern in non-foreign functions (such as the argument in `unsafe extern "C" fn f(...) {}`) a future-compatibility warning; making this error would be consistent with how `unsafe extern "C" fn f(u32) {}` is handled. Allowing `...` arguments without a pattern in non-foreign functions is a source of confusion for programmers coming from C, where the `...` parameter is never named and instead calling `va_start` is required; disallowing `...` arguments without a pattern also improves the overall consistency of the Rust language by matching the treatment of other arguments without patterns. `...` arguments without a pattern in `extern` blocks (such as `unsafe extern "C" { fn f(...); }`) continue to compile without warnings after this PR, as they are already stable and heavily used (and don't cause the mentioned confusion as they are just being used in function declarations).
As all the syntax gating for `c_variadic` has been done post-expansion, this is technically a breaking change. In particular, code like this has compiled on stable since Rust 1.35.0:
```rust
#[cfg(any())] // Equivalent to the more recent #[cfg(false)]
unsafe extern "C" fn bar(_: u32, ...) {}
```
Since this is more or less a stability hole and a Crater run shows only the `binrw` crate is using this, I think it would be ok to break this. This will require a lang FCP.
The idea of rejecting `...` pre-expansion was first raised here https://github.com/rust-lang/rust/pull/143546#issuecomment-3043142052.
Tracking issue: rust-lang/rust#44930
cc `@folkertdev` `@workingjubilee`
r? `@joshtriplett`
Add new `function_casts_as_integer` lint
The `function_casts_as_integer` lint detects cases where users cast a function pointer into an integer.
*warn-by-default*
### Example
```rust
fn foo() {}
let x = foo as usize;
```
```
warning: casting a function into an integer implicitly
--> $DIR/function_casts_as_integer.rs:9:17
|
LL | let x = foo as usize;
| ^^^^^^^^
|
help: add `fn() as usize`
|
LL | let x = foo as fn() as usize;
| +++++++
```
### Explanation
You should never cast a function directly into an integer but go through a cast as `fn` first to make it obvious what's going on. It also allows to prevent confusion with (associated) constants.
Related to https://github.com/rust-lang/rust/issues/81686 and https://stackoverflow.com/questions/68701177/whats-the-meaning-of-casting-a-rust-enum-variant-to-a-numeric-data-type
r? ````@urgau````
Implement `&pin` patterns and `ref pin` binding modes
Implement `&pin` patterns and `ref pin` binding modes, part of [pin ergonomics](https://github.com/rust-lang/rust/issues/130494).
r? `@Nadrieril`
cc `@traviscross` `@eholk`
stop specializing on `Copy`
fixes https://github.com/rust-lang/rust/issues/132442
`std` specializes on `Copy` to optimize certain library functions such as `clone_from_slice`. This is unsound, however, as the `Copy` implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not `Copy`. For instance, this code:
```rust
struct SometimesCopy<'a>(&'a Cell<bool>);
impl<'a> Clone for SometimesCopy<'a> {
fn clone(&self) -> Self {
self.0.set(true);
Self(self.0)
}
}
impl Copy for SometimesCopy<'static> {}
let clone_called = Cell::new(false);
// As SometimesCopy<'clone_called> is not 'static, this must run `clone`,
// setting the value to `true`.
let _ = [SometimesCopy(&clone_called)].clone();
assert!(clone_called.get());
```
should not panic, but does ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6be7a48cad849d8bd064491616fdb43c)).
To solve this, this PR introduces a new `unsafe` trait: `TrivialClone`. This trait may be implemented whenever the `Clone` implementation is equivalent to copying the value (so e.g. `fn clone(&self) -> Self { *self }`). Because of lifetime erasure, there is no way for the `Clone` implementation to observe lifetime bounds, meaning that even if the `TrivialClone` has stricter bounds than the `Clone` implementation, its invariant still holds. Therefore, it is sound to specialize on `TrivialClone`.
I've changed all `Copy` specializations in the standard library to specialize on `TrivialClone` instead. Unfortunately, the unsound `#[rustc_unsafe_specialization_marker]` attribute on `Copy` cannot be removed in this PR as `hashbrown` still depends on it. I'll make a PR updating `hashbrown` once this lands.
With `Copy` no longer being considered for specialization, this change alone would result in the standard library optimizations not being applied for user types unaware of `TrivialClone`. To avoid this and restore the optimizations in most cases, I have changed the expansion of `#[derive(Clone)]`: Currently, whenever both `Clone` and `Copy` are derived, the `clone` method performs a copy of the value. With this PR, the derive macro also adds a `TrivialClone` implementation to make this case observable using specialization. I anticipate that most users will use `#[derive(Clone, Copy)]` whenever both are applicable, so most users will still profit from the library optimizations.
Unfortunately, Hyrum's law applies to this PR: there are some popular crates which rely on the precise specialization behaviour of `core` to implement "specialization at home", e.g. [`libAFL`](89cff63702/libafl_bolts/src/tuples.rs (L27-L49)). I have no remorse for breaking such horrible code, but perhaps we should open other, better ways to satisfy their needs – for example by dropping the `'static` bound on `TypeId::of`...
Point at statics and consts being mutable borrowed or written to:
```
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:4:5
|
LL | static NUM: i32 = 18;
| --------------- this `static` cannot be written to
...
LL | NUM = 20;
| ^^^^^^^^ cannot assign
```
Point at the expression that couldn't be mutably borrowed from a pattern:
```
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/mut-pattern-of-immutable-borrow.rs:19:14
|
LL | match &arg.field {
| ---------- this cannot be borrowed as mutable
LL | Some(ref mut s) => s.push('a'),
| ^^^^^^^^^ cannot borrow as mutable
```
mgca: Finish implementation of `#[type_const]`
tracking issue: rust-lang/rust#132980fixesrust-lang/rust#140729fixesrust-lang/rust#140860
- **Fix `#[type_const]` attribute placement validation**
- **Perform WF-checking on type_const RHS's**
- **Check type_const type is ConstParamTy_ and that RHS matches it**
- **Check that impls of `#[type_const]` consts also have the attr**
r? ```@BoxyUwU```
Remove `#[const_trait]`
Remove `#[const_trait]` since we now have `const trait`. Update all structured diagnostics that still suggested the attribute.
r? ```@rust-lang/project-const-traits```