| Age | Commit message (Collapse) | Author | Lines |
|
Use `splice` to avoid shifting the other items twice.
Put `extern crate std;` first so it's already resolved when we resolve `::std::prelude::rust_20XX`.
|
|
Stop compilation early if macro expansion failed
Fixes rust-lang/rust#116180.
So there isn't really a type that is central for macro expansion and some errors are actually emitted (because the resolution happens after the expansion I suppose) after the expansion pass (like "not found macro"). Sometimes, errors are only emitted on the second "try" (to improve error output). So I couldn't reach a similar solution than what was done in https://github.com/rust-lang/rust/pull/133937 and suggested by ````@estebank```` in https://github.com/rust-lang/rust/issues/116180#issuecomment-3109468922. But maybe I missed something?
So in the end, I realized that there is method called every time (except one, described below) a macro error is actually emitted: `ExtCtxt::trace_macros_diag`. Considering I updated what it did, I renamed it into `macro_error_and_trace_macros_diag` to better reflect it.
There is only one call of `trace_macros_diag` which isn't reporting an error but just used for `macro_trace` feature, so I kept it as is.
r? ````@oli-obk````
|
|
Add `ignore-backends` annotations in failing GCC backend ui tests
Follow-up of https://github.com/rust-lang/rust/pull/144125.
In the GCC backend, we don't support all ui tests yet and we have a list of tests we currently ignore available [here](https://github.com/rust-lang/rustc_codegen_gcc/blob/master/tests/failing-ui-tests.txt).
This PR adds the `ignore-backends` annotations to the corresponding ui tests.
The second commit is a fix to compiletest, complaining about `ignore-backends`.
r? ```@jieyouxu```
|
|
|
|
|
|
|
|
|
|
Remove let_chains unstable feature
Per https://github.com/rust-lang/rust/issues/53667#issuecomment-3016742982 (but then I also noticed rust-lang/rust#140722)
This replaces the feature gate with a parser error that says let chains require 2024.
A lot of tests were using the unstable feature. I either added edition:2024 to the test or split out the parts that require 2024.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r=traviscross,jieyouxu
Add a new `mismatched-lifetime-syntaxes` lint
The lang-team [discussed this](https://hackmd.io/nf4ZUYd7Rp6rq-1svJZSaQ) and I attempted to [summarize](https://github.com/rust-lang/rust/pull/120808#issuecomment-2701863833) their decision. The summary-of-the-summary is:
- Using two different kinds of syntax for elided lifetimes is confusing. In rare cases, it may even [lead to unsound code](https://github.com/rust-lang/rust/issues/48686)! Some examples:
```rust
// Lint will warn about these
fn(v: ContainsLifetime) -> ContainsLifetime<'_>;
fn(&'static u8) -> &u8;
```
- Matching up references with no lifetime syntax, references with anonymous lifetime syntax, and paths with anonymous lifetime syntax is an exception to the simplest possible rule:
```rust
// Lint will not warn about these
fn(&u8) -> &'_ u8;
fn(&'_ u8) -> &u8;
fn(&u8) -> ContainsLifetime<'_>;
```
- Having a lint for consistent syntax of elided lifetimes will make the [future goal](https://github.com/rust-lang/rust/issues/91639) of warning-by-default for paths participating in elision much simpler.
---
This new lint attempts to accomplish the goal of enforcing consistent syntax. In the process, it supersedes and replaces the existing `elided-named-lifetimes` lint, which means it starts out life as warn-by-default.
|
|
This is useful for C/C++ APIs which expect the const char* returned
from __FILE__ or std::source_location::file_name.
|
|
|
|
based on tests/ui/rfcs/rfc-2497-if-let-chains/temporary-early-drop.rs
|
|
|
|
|
|
Remove global `next_disambiguator` state and handle it with a `DisambiguatorState` type
This removes `Definitions.next_disambiguator` as it doesn't guarantee deterministic def paths when `create_def` is called in parallel. Instead a new `DisambiguatorState` type is passed as a mutable reference to `create_def` to help create unique def paths. `create_def` calls with distinct `DisambiguatorState` instances must ensure that that the def paths are unique without its help.
Anon associated types did rely on this global state for uniqueness and are changed to use (method they're defined in + their position in the method return type) as the `DefPathData` to ensure uniqueness. This also means that the method they're defined in appears in error messages, which is nicer.
`DefPathData::NestedStatic` is added to use for nested data inside statics instead of reusing `DefPathData::AnonConst` to avoid conflicts with those.
cc `@oli-obk`
|
|
|
|
`DisambiguatorState` type
|
|
|
|
Stabilize let chains in the 2024 edition
# Stabilization report
This proposes the stabilization of `let_chains` ([tracking issue], [RFC 2497]) in the [2024 edition] of Rust.
[tracking issue]: https://github.com/rust-lang/rust/issues/53667
[RFC 2497]: https://github.com/rust-lang/rfcs/pull/2497
[2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html
## What is being stabilized
The ability to `&&`-chain `let` statements inside `if` and `while` is being stabilized, allowing intermixture with boolean expressions. The patterns inside the `let` sub-expressions can be irrefutable or refutable.
```Rust
struct FnCall<'a> {
fn_name: &'a str,
args: Vec<i32>,
}
fn is_legal_ident(s: &str) -> bool {
s.chars()
.all(|c| ('a'..='z').contains(&c) || ('A'..='Z').contains(&c))
}
impl<'a> FnCall<'a> {
fn parse(s: &'a str) -> Option<Self> {
if let Some((fn_name, after_name)) = s.split_once("(")
&& !fn_name.is_empty()
&& is_legal_ident(fn_name)
&& let Some((args_str, "")) = after_name.rsplit_once(")")
{
let args = args_str
.split(',')
.map(|arg| arg.parse())
.collect::<Result<Vec<_>, _>>();
args.ok().map(|args| FnCall { fn_name, args })
} else {
None
}
}
fn exec(&self) -> Option<i32> {
let iter = self.args.iter().copied();
match self.fn_name {
"sum" => Some(iter.sum()),
"max" => iter.max(),
"min" => iter.min(),
_ => None,
}
}
}
fn main() {
println!("{:?}", FnCall::parse("sum(1,2,3)").unwrap().exec());
println!("{:?}", FnCall::parse("max(4,5)").unwrap().exec());
}
```
The feature will only be stabilized for the 2024 edition and future editions. Users of past editions will get an error with a hint to update the edition.
closes #53667
## Why 2024 edition?
Rust generally tries to ship new features to all editions. So even the oldest editions receive the newest features. However, sometimes a feature requires a breaking change so much that offering the feature without the breaking change makes no sense. This occurs rarely, but has happened in the 2018 edition already with `async` and `await` syntax. It required an edition boundary in order for `async`/`await` to become keywords, and the entire feature foots on those keywords.
In the instance of let chains, the issue is the drop order of `if let` chains. If we want `if let` chains to be compatible with `if let`, drop order makes it hard for us to [generate correct MIR]. It would be strange to have different behaviour for `if let ... {}` and `if true && let ... {}`. So it's better to [stay consistent with `if let`].
In edition 2024, [drop order changes] have been introduced to make `if let` temporaries be lived more shortly. These changes also affected `if let` chains. These changes make sense even if you don't take the `if let` chains MIR generation problem into account. But if we want to use them as the solution to the MIR generation problem, we need to restrict let chains to edition 2024 and beyond: for let chains, it's not just a change towards more sensible behaviour, but one required for correct function.
[generate correct MIR]: https://github.com/rust-lang/rust/issues/104843
[stay consistent with `if let`]: https://github.com/rust-lang/rust/pull/103293#issuecomment-1293408574
[drop order changes]: https://github.com/rust-lang/rust/issues/124085
## Introduction considerations
As edition 2024 is very new, this stabilization PR only makes it possible to use let chains on 2024 without that feature gate, it doesn't mark that feature gate as stable/removed. I would propose to continue offering the `let_chains` feature (behind a feature gate) for a limited time (maybe 3 months after stabilization?) on older editions to allow nightly users to adopt edition 2024 at their own pace. After that, the feature gate shall be marked as *stabilized*, not removed, and replaced by an error on editions 2021 and below.
## Implementation history
* History from before March 14, 2022 can be found in the [original stabilization PR] that was reverted.
* https://github.com/rust-lang/rust/pull/94927
* https://github.com/rust-lang/rust/pull/94951
* https://github.com/rust-lang/rust/pull/94974
* https://github.com/rust-lang/rust/pull/95008
* https://github.com/rust-lang/rust/pull/97295
* https://github.com/rust-lang/rust/pull/98633
* https://github.com/rust-lang/rust/pull/99731
* https://github.com/rust-lang/rust/pull/102394
* https://github.com/rust-lang/rust/pull/100526
* https://github.com/rust-lang/rust/pull/100538
* https://github.com/rust-lang/rust/pull/102998
* https://github.com/rust-lang/rust/pull/103405
* https://github.com/rust-lang/rust/pull/103293
* https://github.com/rust-lang/rust/pull/107251
* https://github.com/rust-lang/rust/pull/110568
* https://github.com/rust-lang/rust/pull/115677
* https://github.com/rust-lang/rust/pull/117743
* https://github.com/rust-lang/rust/pull/117770
* https://github.com/rust-lang/rust/pull/118191
* https://github.com/rust-lang/rust/pull/119554
* https://github.com/rust-lang/rust/pull/129394
* https://github.com/rust-lang/rust/pull/132828
* https://github.com/rust-lang/reference/pull/1179
* https://github.com/rust-lang/reference/pull/1251
* https://github.com/rust-lang/rustfmt/pull/5910
[original stabilization PR]: https://github.com/rust-lang/rust/pull/94927
## Adoption history
### In the compiler
* History before March 14, 2022 can be found in the [original stabilization PR].
* https://github.com/rust-lang/rust/pull/115983
* https://github.com/rust-lang/rust/pull/116549
* https://github.com/rust-lang/rust/pull/116688
### Outside of the compiler
* https://github.com/rust-lang/rust-clippy/pull/11750
* [rspack](https://github.com/web-infra-dev/rspack)
* [risingwave](https://github.com/risingwavelabs/risingwave)
* [dylint](https://github.com/trailofbits/dylint)
* [convex-backend](https://github.com/get-convex/convex-backend)
* [tikv](https://github.com/tikv/tikv)
* [Daft](https://github.com/Eventual-Inc/Daft)
* [greptimedb](https://github.com/GreptimeTeam/greptimedb)
## Tests
<details>
### Intentional restrictions
[`partially-macro-expanded.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs), [`macro-expanded.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs): it is possible to use macros to expand to both the pattern and the expression inside a let chain, but not to the entire `let pat = expr` operand.
[`parens.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs): `if (let pat = expr)` is not allowed in chains
[`ensure-that-let-else-does-not-interact-with-let-chains.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs): `let...else` doesn't support chaining.
### Overlap with match guards
[`move-guard-if-let-chain.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs): test for the `use moved value` error working well in match guards. could maybe be extended with let chains that have more than one `let`
[`shadowing.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs): shadowing in if let guards works as expected
[`ast-validate-guards.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs): let chains in match guards require the match guards feature gate
### Simple cases from the early days
PR #88642 has added some tests with very simple usages of `let else`, mostly as regression tests to early bugs.
[`then-else-blocks.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/then-else-blocks.rs)
[`ast-lowering-does-not-wrap-let-chains.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs)
[`issue-90722.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/issue-90722.rs)
[`issue-92145.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/issue-92145.rs)
### Drop order/MIR scoping tests
[`issue-100276.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/drop/issue-100276.rs): let expressions on RHS aren't terminating scopes
[`drop_order.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/drop/drop_order.rs): exhaustive temporary drop order test for various Rust constructs, including let chains
[`scope.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs): match guard scoping test
[`drop-scope.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2294-if-let-guard/drop-scope.rs): another match guard scoping test, ensuring that temporaries in if-let guards live for the arm
[`drop_order_if_let_rescope.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/drop/drop_order_if_let_rescope.rs): if let rescoping on edition 2024, including chains
[`mir_let_chains_drop_order.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/mir/mir_let_chains_drop_order.rs): comprehensive drop order test for let chains, distinguishes editions 2021 and 2024.
[`issue-99938.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/issue-99938.rs), [`issue-99852.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/mir/issue-99852.rs) both bad MIR ICEs fixed by #102394
### Linting
[`irrefutable-lets.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs): trailing and leading irrefutable let patterns get linted for, others don't. The lint is turned off for `else if`.
[`issue-121070-let-range.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/lint/issue-121070-let-range.rs): regression test for false positive of the unused parens lint, precedence requires the `()`s here
### Parser: intentional restrictions
[`disallowed-positions.rs`](https://github.com/rust-lang/rust/blob/2128d8df0e858edcbe6a0861bac948b88b7fabc3/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs): `let` in expression context is rejected everywhere except at the top level
[`invalid-let-in-a-valid-let-context.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs): nested `let` is not allowed (let's are no legal expressions just because they are allowed in `if` and `while`).
### Parser: recovery
[`issue-103381.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/parser/issues/issue-103381.rs): Graceful recovery of incorrect chaining of `if` and `if let`
[`semi-in-let-chain.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/parser/semi-in-let-chain.rs): Ensure that stray `;`s in let chains give nice errors (`if_chain!` users might be accustomed to `;`s)
[`deli-ident-issue-1.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/parser/deli-ident-issue-1.rs), [`brace-in-let-chain.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/parser/brace-in-let-chain.rs): Ensure that stray unclosed `{`s in let chains give nice errors and hints
### Misc
[`conflicting_bindings.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/pattern/usefulness/conflicting_bindings.rs): the conflicting bindings check also works in let chains. Personally, I'd extend it to chains with multiple let's as well.
[`let-chains-attr.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/expr/if/attrs/let-chains-attr.rs): attributes work on let chains
### Tangential tests with `#![feature(let_chains)]`
[`if-let.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/coverage/branch/if-let.rs): MC/DC coverage tests for let chains
[`logical_or_in_conditional.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/mir-opt/building/logical_or_in_conditional.rs): not really about let chains, more about dropping/scoping behaviour of `||`
[`stringify.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/macros/stringify.rs): exhaustive test of the `stringify` macro
[`expanded-interpolation.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/unpretty/expanded-interpolation.rs), [`expanded-exhaustive.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/unpretty/expanded-exhaustive.rs): Exhaustive test of `-Zunpretty`
[`diverges-not.rs`](https://github.com/rust-lang/rust/blob/4adafcf40aa6064d2bbcb44bc1a50b3b1e86e5e0/tests/ui/rfcs/rfc-0000-never_patterns/diverges-not.rs): Never type, mostly tangential to let chains
</details>
## Possible future work
* There is proposals to allow `if let Pat(bindings) = expr {}` to be written as `if expr is Pat(bindings) {}` ([RFC 3573]). `if let` chains are a natural extension of the already existing `if let` syntax, and I'd argue orthogonal towards `is` syntax.
* https://github.com/rust-lang/lang-team/issues/297
* One could have similar chaining inside `let ... else` statements. There is no proposed RFC for this however, nor is it implemented on nightly.
* Match guards have the `if` keyword as well, but on stable Rust, they don't support `let`. The functionality is available via an unstable feature ([`if_let_guard` tracking issue]). Stabilization of let chains affects this feature in so far as match guards containing let chains now only need the `if_let_guard` feature gate be present instead of also the `let_chains` feature (NOTE: this PR doesn't implement this simplification, it's left for future work).
[RFC 3573]: https://github.com/rust-lang/rfcs/pull/3573
[`if_let_guard` tracking issue]: https://github.com/rust-lang/rust/issues/51114
## Open questions / blockers
- [ ] bad recovery if you don't put a `let` (I don't think this is a blocker): [#117977](https://github.com/rust-lang/rust/issues/117977)
- [x] An instance where a temporary lives shorter than with nested ifs, breaking compilation: [#103476](https://github.com/rust-lang/rust/issues/103476). Personally I don't think this is a blocker either, as it's an edge case. Edit: turns out to not reproduce in edition 2025 any more, due to let rescoping. regression test added in #133093
- [x] One should probably extend the tests for `move-guard-if-let-chain.rs` and `conflicting_bindings.rs` to have chains with multiple let's: done in 133093
- [x] Parsing rejection tests: addressed by https://github.com/rust-lang/rust/pull/132828
- [x] [Style](https://rust-lang.zulipchat.com/#narrow/channel/346005-t-style/topic/let.20chains.20stabilization.20and.20formatting): https://github.com/rust-lang/rust/pull/139456
- [x] https://github.com/rust-lang/rust/issues/86730 explicitly mentions `let_else`. I think we can live with `let pat = expr` not evaluating as `expr` for macro_rules macros, especially given that `let pat = expr` is not a legal expression anywhere except inside `if` and `while`.
- [x] Documentation in the reference: https://github.com/rust-lang/reference/pull/1740
- [x] Add chapter to the Rust 2024 [edition guide]: https://github.com/rust-lang/edition-guide/pull/337
- [x] Resolve open questions on desired drop order.
[original reference PR]: https://github.com/rust-lang/reference/pull/1179
[edition guide]: https://github.com/rust-lang/edition-guide
|
|
|
|
|
|
|
|
The edition gate is a bit stricter than the drop behaviour,
which is fine. The cases we want to avoid are the opposite:
not gated but 2021 drop behaviour.
|
|
Explicitly annotate edition for `unpretty=expanded` and `unpretty=hir` tests
These emit prelude imports which means they are always edition dependent and so running them with a different `--edition` will fail.
|
|
r=davidtwco,Urgau,traviscross
Stabilize `cfg_boolean_literals`
Closes #131204
`@rustbot` labels +T-lang +I-lang-nominated
This will end up conflicting with the test in #138293 so whichever doesn't land first will need updating
--
# Stabilization Report
## General design
### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized?
[RFC 3695](https://github.com/rust-lang/rfcs/pull/3695), none.
### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con.
None
### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those?
None
## Has a call-for-testing period been conducted? If so, what feedback was received?
Yes; only positive feedback was received.
## Implementation quality
### Summarize the major parts of the implementation and provide links into the code (or to PRs)
Implemented in [#131034](https://github.com/rust-lang/rust/pull/131034).
### Summarize existing test coverage of this feature
- [Basic usage, including `#[cfg()]`, `cfg!()` and `#[cfg_attr()]`](https://github.com/rust-lang/rust/blob/6d71251cf9e40326461f90f8ff9a7024706aea87/tests/ui/cfg/true-false.rs)
- [`--cfg=true/false` on the command line being accessible via `r#true/r#false`](https://github.com/rust-lang/rust/blob/6d71251cf9e40326461f90f8ff9a7024706aea87/tests/ui/cfg/raw-true-false.rs)
- [Interaction with the unstable `#[doc(cfg(..))]` feature](https://github.com/rust-lang/rust/tree/6d71251/tests/rustdoc-ui/cfg-boolean-literal.rs)
- [Denying `--check-cfg=cfg(true/false)`](https://github.com/rust-lang/rust/tree/6d71251/tests/ui/check-cfg/invalid-arguments.rs)
- Ensuring `--cfg false` on the command line doesn't change the meaning of `cfg(false)`: `tests/ui/cfg/cmdline-false.rs`
- Ensuring both `cfg(true)` and `cfg(false)` on the same item result in it being disabled: `tests/ui/cfg/both-true-false.rs`
### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking?
The above mentioned issue; it should not block as it interacts with another unstable feature.
### What FIXMEs are still in the code for that feature and why is it ok to leave them there?
None
### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization
- `@clubby789` (RFC)
- `@Urgau` (Implementation in rustc)
### Which tools need to be adjusted to support this feature. Has this work been done?
`rustdoc`'s unstable`#[doc(cfg(..)]` has been updated to respect it. `cargo` has been updated with a forward compatibility lint to enable supporting it in cargo once stabilized.
## Type system and execution rules
### What updates are needed to the reference/specification? (link to PRs when they exist)
A few lines to be added to the reference for configuration predicates, specified in the RFC.
|
|
These emit prelude imports which means they are always edition dependent
|
|
|
|
Give them their own symbol `anon_assoc`, as is done for all the other
anonymous `DefPathData` variants.
|
|
|
|
|
|
|
|
Notes about tests:
- tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs: some messages are
now duplicated due to repeated parsing.
- tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs: ditto.
- `tests/ui/proc-macro/macro-rules-derive-cfg.rs`: the diff looks large
but the only difference is the insertion of a single
invisible-delimited group around a metavar.
- `tests/ui/attributes/nonterminal-expansion.rs`: a slight span
degradation, somehow related to the recent massive attr parsing
rewrite (#135726). I couldn't work out exactly what is going wrong,
but I don't think it's worth holding things up for a single slightly
suboptimal error message.
|
|
|
|
|
|
For macros that are implemented on the compiler, we do *not* mention the `-Zmacro-backtrace` flag. This includes `derive`s and standard macros.
|
|
|
|
raw-dylib is a link kind that allows rustc to link against a library
without having any library files present.
This currently only exists on Windows. rustc will take all the symbols
from raw-dylib link blocks and put them in an import library, where they
can then be resolved by the linker.
While import libraries don't exist on ELF, it would still be convenient
to have this same functionality. Not having the libraries present at
build-time can be convenient for several reasons, especially
cross-compilation. With raw-dylib, code linking against a library can be
cross-compiled without needing to have these libraries available on the
build machine. If the libc crate makes use of this, it would allow
cross-compilation without having any libc available on the build
machine. This is not yet possible with this implementation, at least
against libc's like glibc that use symbol versioning.
The raw-dylib kind could be extended with support for symbol versioning
in the future.
This implementation is very experimental and I have not tested it very
well. I have tested it for a toy example and the lz4-sys crate, where it
was able to successfully link a binary despite not having a
corresponding library at build-time.
|
|
|
|
|
|
|
|
|
|
Always perform discr read for never pattern in EUV
Always perform a read of `!` discriminants to ensure that it's captured by closures in expr use visitor
Fixes #136852
r? Nadrieril or reassign
|
|
Stabilize target_feature_11
# Stabilization report
This is an updated version of https://github.com/rust-lang/rust/pull/116114, which is itself a redo of https://github.com/rust-lang/rust/pull/99767. Most of this commit and report were copied from those PRs. Thanks ```@LeSeulArtichaut``` and ```@calebzulawski!```
## Summary
Allows for safe functions to be marked with `#[target_feature]` attributes.
Functions marked with `#[target_feature]` are generally considered as unsafe functions: they are unsafe to call, cannot *generally* be assigned to safe function pointers, and don't implement the `Fn*` traits.
However, calling them from other `#[target_feature]` functions with a superset of features is safe.
```rust
// Demonstration function
#[target_feature(enable = "avx2")]
fn avx2() {}
fn foo() {
// Calling `avx2` here is unsafe, as we must ensure
// that AVX is available first.
unsafe {
avx2();
}
}
#[target_feature(enable = "avx2")]
fn bar() {
// Calling `avx2` here is safe.
avx2();
}
```
Moreover, once https://github.com/rust-lang/rust/pull/135504 is merged, they can be converted to safe function pointers in a context in which calling them is safe:
```rust
// Demonstration function
#[target_feature(enable = "avx2")]
fn avx2() {}
fn foo() -> fn() {
// Converting `avx2` to fn() is a compilation error here.
avx2
}
#[target_feature(enable = "avx2")]
fn bar() -> fn() {
// `avx2` coerces to fn() here
avx2
}
```
See the section "Closures" below for justification of this behaviour.
## Test cases
Tests for this feature can be found in [`tests/ui/target_feature/`](https://github.com/rust-lang/rust/tree/f6cb952dc115fd1311b02b694933e31d8dc8b002/tests/ui/target-feature).
## Edge cases
### Closures
* [target-feature 1.1: should closures inherit target-feature annotations? #73631](https://github.com/rust-lang/rust/issues/73631)
Closures defined inside functions marked with #[target_feature] inherit the target features of their parent function. They can still be assigned to safe function pointers and implement the appropriate `Fn*` traits.
```rust
#[target_feature(enable = "avx2")]
fn qux() {
let my_closure = || avx2(); // this call to `avx2` is safe
let f: fn() = my_closure;
}
```
This means that in order to call a function with #[target_feature], you must guarantee that the target-feature is available while the function, any closures defined inside it, as well as any safe function pointers obtained from target-feature functions inside it, execute.
This is usually ensured because target features are assumed to never disappear, and:
- on any unsafe call to a `#[target_feature]` function, presence of the target feature is guaranteed by the programmer through the safety requirements of the unsafe call.
- on any safe call, this is guaranteed recursively by the caller.
If you work in an environment where target features can be disabled, it is your responsibility to ensure that no code inside a target feature function (including inside a closure) runs after this (until the feature is enabled again).
**Note:** this has an effect on existing code, as nowadays closures do not inherit features from the enclosing function, and thus this strengthens a safety requirement. It was originally proposed in #73631 to solve this by adding a new type of UB: “taking a target feature away from your process after having run code that uses that target feature is UB” .
This was motivated by userspace code already assuming in a few places that CPU features never disappear from a program during execution (see i.e. https://github.com/rust-lang/stdarch/blob/2e29bdf90832931ea499755bb4ad7a6b0809295a/crates/std_detect/src/detect/arch/x86.rs); however, concerns were raised in the context of the Linux kernel; thus, we propose to relax that requirement to "causing the set of usable features to be reduced is unsafe; when doing so, the programmer is required to ensure that no closures or safe fn pointers that use removed features are still in scope".
* [Fix #[inline(always)] on closures with target feature 1.1 #111836](https://github.com/rust-lang/rust/pull/111836)
Closures accept `#[inline(always)]`, even within functions marked with `#[target_feature]`. Since these attributes conflict, `#[inline(always)]` wins out to maintain compatibility.
### ABI concerns
* [The extern "C" ABI of SIMD vector types depends on target features #116558](https://github.com/rust-lang/rust/issues/116558)
The ABI of some types can change when compiling a function with different target features. This could have introduced unsoundness with target_feature_11, but recent fixes (#133102, #132173) either make those situations invalid or make the ABI no longer dependent on features. Thus, those issues should no longer occur.
### Special functions
The `#[target_feature]` attribute is forbidden from a variety of special functions, such as main, current and future lang items (e.g. `#[start]`, `#[panic_handler]`), safe default trait implementations and safe trait methods.
This was not disallowed at the time of the first stabilization PR for target_features_11, and resulted in the following issues/PRs:
* [`#[target_feature]` is allowed on `main` #108645](https://github.com/rust-lang/rust/issues/108645)
* [`#[target_feature]` is allowed on default implementations #108646](https://github.com/rust-lang/rust/issues/108646)
* [#[target_feature] is allowed on #[panic_handler] with target_feature 1.1 #109411](https://github.com/rust-lang/rust/issues/109411)
* [Prevent using `#[target_feature]` on lang item functions #115910](https://github.com/rust-lang/rust/pull/115910)
## Documentation
* Reference: [Document the `target_feature_11` feature reference#1181](https://github.com/rust-lang/reference/pull/1181)
---
cc tracking issue https://github.com/rust-lang/rust/issues/69098
cc ```@workingjubilee```
cc ```@RalfJung```
r? ```@rust-lang/lang```
|
|
|