Minor improvement on else-no-if diagnostic
Don't suggest wrapping in block since it's highly likely to be a missing `if` after `else`. Also rework message a bit (open to further suggestions).
cc: https://github.com/rust-lang/rust/pull/97298#discussion_r880933431
r? `@estebank`
[RFC 2011] Library code
CC https://github.com/rust-lang/rust/pull/96496
Based on https://github.com/dtolnay/case-studies/tree/master/autoref-specialization.
Basically creates two traits with the same method name. One trait is generic over any `T` and the other is specialized to any `T: Printable`.
The compiler will then call the corresponding trait method through auto reference.
```rust
fn main() {
let mut a = Capture::new();
let mut b = Capture::new();
(&Wrapper(&1i32)).try_capture(&mut a); // `try_capture` from `TryCapturePrintable`
(&Wrapper(&vec![1i32])).try_capture(&mut b); // `try_capture` from `TryCaptureGeneric`
assert_eq!(format!("{:?}", a), "1");
assert_eq!(format!("{:?}", b), "N/A");
}
```
r? `@scottmcm`
RFC3239: Implement `cfg(target)` - Part 2
This pull-request implements the compact `cfg(target(..))` part of [RFC 3239](https://github.com/rust-lang/rust/issues/96901).
I recommend reviewing this PR on a per commit basics, because of some moving parts.
cc `@GuillaumeGomez`
r? `@petrochenkov`
Modify MIR building to drop repeat expressions with length zero
Closes#74836 .
Previously, when a user wrote `[foo; 0]` we used to simply leak `foo`. The goal is to fix that. This PR changes MIR building to make `[foo; 0]` equivalent to `{ drop(foo); [] }` in all cases. Of course, this is a breaking change (see below). A crater run did not indicate any regressions though, and given that the previous behavior was almost definitely not what any user wanted, it seems unlikely that anyone was relying on this.
Note that const generics are in general unaffected by this. Inserting the extra `drop` is only meaningful/necessary when `foo` is of a non-`Copy` type, and array repeat expressions with const generic repetition count must always be `Copy`.
Besides the obvious change to behavior associated with the additional drop, there are three categories of examples where this also changes observable behavior. In all of these cases, the new behavior is consistent with what you would get by replacing `[foo; 0]` with `{ drop(foo); [] }`. As such, none of these give the user new powers to express more things.
**No longer allowed in const (breaking)**:
```rust
const _: [String; 0] = [String::new(); 0];
```
This compiles on stable today. Because we now introduce the drop of `String`, this no longer compiles as `String` may not be dropped in a const context.
**Reduced dataflow (non-breaking)**:
```rust
let mut x: i32 = 0;
let r = &x;
let a = [r; 0];
x = 5;
let _b = a;
```
Borrowck rejects this code on stable because it believes there is dataflow between `a` and `r`, and so the lifetime of `r` has to extend to the last statement. This change removes the dataflow and the above code is allowed to compile.
**More const promotion (non-breaking)**:
```rust
let _v: &'static [String; 0] = &[String::new(); 0];
```
This does not compile today because `String` having drop glue keeps it from being const promoted (despite that drop glue never being executed). After this change, this is allowed to compile.
### Alternatives
A previous attempt at this tried to reduce breakage by various tricks. This is still a possibility, but given that crater showed no regressions it seems unclear why we would want to introduce this complexity.
Disallowing `[foo; 0]` completely is also an option, but obviously this is more of a breaking change. I do not know how often this is actually used though.
r? `@oli-obk`
add a deep fast_reject routine
continues the work on #97136.
r? `@nnethercote`
Actually agree with you on the match structure 😆 let's see how that impacted perf 😅
Rollup of 5 pull requests
Successful merges:
- #93604 (Make llvm-libunwind a per-target option)
- #97026 (Change orderings of `Debug` for the Atomic types to `Relaxed`.)
- #97105 (Add tests for lint on type dependent on consts)
- #97323 (Introduce stricter checks for might_permit_raw_init under a debug flag )
- #97379 (Add aliases for `current_dir`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
`match_impl` has two call sites. For one of them (within `rematch_impl`)
the fast reject test isn't necessary, because any rejection would
represent a compiler bug.
This commit moves the fast reject test to the other `match_impl` call
site, in `assemble_candidates_from_impls`. This lets us move the fast
reject test outside the `probe` call in that function. This avoids the
taking of useless snapshots when the fast reject test succeeds, which
gives a performance win when compiling the `bitmaps` and `nalgebra`
crates.
Co-authored-by: name <n.nethercote@gmail.com>
Add aliases for `current_dir`
Aliases were added for the equivalent C/C++ APIs for POSIX and Windows. Also, I added one for `pwd` which users may be more familiar with, from the command line.
Introduce stricter checks for might_permit_raw_init under a debug flag
This is intended to be a version of the strict checks tried out in #79296, but also checking number validity (under the assumption that `let _ = std::mem::uninitialized::<u32>()` is UB, which seems to be what https://github.com/rust-lang/unsafe-code-guidelines/issues/71 is leaning towards.)
Change orderings of `Debug` for the Atomic types to `Relaxed`.
This reduces synchronization between threads when debugging the atomic types. Reducing the synchronization means that executions with and without the debug calls will be more consistent, making it easier to debug.
We discussed this on the Rust Community Discord with `@ibraheemdev` before.
Make `Lazy*<T>` types in `rustc_metadata` not care about lifetimes until decode
This allows us to remove the `'tcx` lifetime from `CrateRoot`. This is necessary because of #97287, which makes the `'tcx` lifetime on `Ty` invariant instead of covariant, so [this hack](0a437b2ca0/compiler/rustc_metadata/src/rmeta/decoder.rs (L89-92)) no longer holds under that PR.
Introduces a trait called `ParameterizedOverTcx` which has a generic associated type that allows a type to be parameterized over that lifetime. This means we can decode, for example, `Lazy<Ty<'static>>` into any `Ty<'tcx>` depending on the `TyCtxt<'tcx>` we pass into the decode function.
Make weird name lints trigger behind cfg_attr
The weird name lints (`unknown_lints`, `renamed_and_removed_lints`), the lints that lint the linting, were previously not firing for lint level declarations behind `cfg_attr`, as they were only running before expansion.
Now, this will give a `unknown_lints` warning:
```Rust
#[cfg_attr(all(), allow(this_lint_does_not_exist))]
fn foo() {}
```
Lint level declarations behind a `cfg_attr` whose condition is not applying are still ignored. So this still won't give a warning:
```Rust
#[cfg_attr(any(), allow(this_lint_does_not_exist))]
fn foo() {}
```
Furthermore, this PR also makes the weird name lints respect level delcarations for *them* that were hidden by `cfg_attr`, making them consistent to other lints. So this will now not issue a warning:
```Rust
#[cfg_attr(all(), allow(unknown_lints))]
mod foo {
#[allow(does_not_exist)]
fn foo() {
}
}
```
Fixes#97094
Rollup of 4 pull requests
Successful merges:
- #97288 (Lifetime variance fixes for rustdoc)
- #97298 (Parse expression after `else` as a condition if followed by `{`)
- #97308 (Stabilize `cell_filter_map`)
- #97321 (explain how to turn integers into fn ptrs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Previously, we were emitting weird name lints (for renamed or unknown lints)
before expansion, most importantly before cfg expansion.
This meant that the weird name lints would not fire
for lint attributes hidden inside cfg_attr. The same applied
for lint level specifications of those lints.
By moving the lints for the lint names to the post-expansion
phase, these issues are resolved.
explain how to turn integers into fn ptrs
(with an intermediate raw ptr, not a direct transmute)
Direct int2ptr transmute, under the semantics I am imagining, will produce a ptr with "invalid" provenance that is invalid to deref or call. We cannot give it the same semantics as int2ptr casts since those do [something complicated](https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html).
To my great surprise, that is already what the example in the `transmute` docs does. :) I still added a comment to say that that part is important, and I added a section explicitly talking about this to the `fn()` type docs.
With https://github.com/rust-lang/miri/pull/2151, Miri will start complaining about direct int-to-fnptr transmutes (in the sense that it is UB to call the resulting pointer).
Parse expression after `else` as a condition if followed by `{`
Fixes#49361.
Two things:
1. This wording needs help. I can never find a natural/intuitive phrasing when I write diagnostics 😅
2. Do we even want to show the "wrap in braces" case? I would assume most of the time the "add an `if`" case is the right one.
Lifetime variance fixes for rustdoc
#97287 migrates rustc to a `Ty` type that is invariant over its lifetime `'tcx`, so I need to fix a bunch of places that assume that `Ty<'a>` and `Ty<'b>` can be unified by shortening both to some common lifetime.
This is doable, since everything is already `'tcx`, so all this PR does is be a bit more explicit that elided lifetimes are actually `'tcx`.
Split out from #97287 so the rustdoc team can review independently.