Use attributes for `dangling_pointers_from_temporaries` lint
Checking for dangling pointers by function name isn't ideal, and leaves out certain pointer-returning methods that don't follow the `as_ptr` naming convention. Using an attribute for this lint cleans things up and allows more thorough coverage of other methods, such as `UnsafeCell::get()`.
Drop debug info instead of panicking if we exceed LLVM's capability to represent it
Recapping a bit of history here:
In #128861 I made debug info correctly represent parameters to inline functions by removing a fake lexical block that had been inserted to suppress LLVM assertions and by deduplicating those parameters.
LLVM, however, expects to see a single parameter _with distinct locations_, particularly distinct inlinedAt values on the DILocations. This generally worked because no matter how deep the chain of inlines it takes two different call sites in the original function to result in the same function being present multiple times, and a function call requires a non-zero number of characters, but macros threw a wrench in that in #131944. At the time I thought the issue there was limited to proc-macros, where an arbitrary amount of code can be generated at a single point in the source text.
In #132613 I added discriminators to DILocations that would otherwise be the same to repair #131944[^1]. This works, but LLVM's capacity for discriminators is not infinite (LLVM actually only allocates 12 bits for this internally). At the time I thought it would be very rare for anyone to hit the limit, but #132900 proved me wrong. In the relatively-minimized test case it also became clear to me that the issue affects regular macros too, because the call to the inlined function will (without collapse_debuginfo on the macro) be attributed to the (repeated, if the macro is used more than once) textual callsite in the macro definition.
This PR fixes the panic by dropping debug info when we exceed LLVM's maximum discriminator value. There's also a preceding commit for a related but distinct issue: macros that use collapse_debuginfo should in fact have their inlinedAts collapsed to the macro callsite and thus not need discriminators at all (and not panic/warn accordingly when the discriminator limit is exhausted).
Fixes#132900
r? `@jieyouxu`
[^1]: Editor's note: `fix` is a magic keyword in PR description that apparently will close the linked issue (it's closed already in this case, but still).
Rollup of 4 pull requests
Successful merges:
- #131081 (Use `ConstArgKind::Path` for all single-segment paths, not just params under `min_generic_const_args`)
- #132577 (Report the `unexpected_cfgs` lint in external macros)
- #133023 (Merge `-Zhir-stats` into `-Zinput-stats`)
- #133200 (ignore an occasionally-failing test in Miri)
r? `@ghost`
`@rustbot` modify labels: rollup
The maximum discriminator value LLVM can currently encode is 2^12. If macro use
results in more than 2^12 calls to the same function attributed to the same
callsite, and those calls are MIR-inlined, we will require more than the maximum
discriminator value to completely represent the debug information. Once we reach
that point drop the debug info instead.
The test relies on the fact that inlining more than 2^12 calls at the same
callsite will trigger a panic (and after the following commit, a warning) due to
LLVM limitations but with collapse_debuginfo the callsites should not be the
same.
Merge `-Zhir-stats` into `-Zinput-stats`
Currently `-Z hir-stats` prints the size and count of various kinds of nodes, and the total size of all the nodes it counted, but not the total count of nodes. So, before this PR:
```
$ git clone https://github.com/BurntSushi/ripgrep
$ cd ripgrep
$ cargo +nightly rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 93_576
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 2_430_648
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total 3_678_512
hir-stats
```
For consistency, this PR adds a total for the count as well:
```
$ cargo +stage1 rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 93_576 1_877
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 2_430_648 48_625
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total 3_678_512 73_418
hir-stats
```
I wasn't sure if I was supposed to update `tests/ui/stats/hir-stats.stderr` to reflect this. I ran it locally, thinking it would fail, but it didn't:
```
$ ./x test tests/ui/stats
...
running 2 tests
i.
test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 17949 filtered out
```
Also: is there a reason `-Z hir-stats` and `-Z input-stats` both exist? The former seems like it should completely supercede the latter. But strangely, the two give very different numbers for node counts:
```
$ cargo +nightly rustc -- -Z input-stats
...
Lines of code: 483
Pre-expansion node count: 2386
Post-expansion node count: 63844
```
That's a 30% difference in this case. Is it intentional that these numbers are so different? I see comments for both saying that they are merely approximations and should not be expected to be correct:
bd0826a452/compiler/rustc_ast_passes/src/node_count.rs (L1)bd0826a452/compiler/rustc_passes/src/hir_stats.rs (L1-L3)
Report the `unexpected_cfgs` lint in external macros
This PR marks the `unexpected_cfgs` lint as being reportable in external macros, as it's probably not the intention of the macro author to leave ineffective cfgs in the users code.
Fixes#132572
try-job: aarch64-gnu-debug
Add reference annotations for diagnostic attributes
This adds reference annotations for `diagnostic::on_unimplmented` and the `diagnostic` namespace in general.
There's also a rename for a test that looks like it was put in the wrong location.
stability: remove skip_stability_check_due_to_privacy
This was added in https://github.com/rust-lang/rust/pull/38689 to deal with https://github.com/rust-lang/rust/issues/38412. However, even after removing the check, the relevant tests still pass. Let's see if CI finds any other tests that rely on this. If not, it seems like logic elsewhere in the compiler changed so this is not required any more.
rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirect
In https://github.com/rust-lang/rust/pull/120370 this name caused confusion as the author thought the intrinsic was stable. So let's try a different name...
If we can land this before the beta cutoff we can avoid needing `cfg(bootstrap)` for this. ;)
Cc `@compiler-errors` `@saethlin`
Overhaul the `-l` option parser (for linking to native libs)
The current parser for `-l` options has accumulated over time, making it hard to follow. This PR tries to clean it up in several ways.
Key changes:
- This code now gets its own submodule, to slightly reduce clutter in `rustc_session::config`.
- Cleaner division between iterating over multiple `-l` options, and processing each individual one.
- Separate “split” step that breaks up the value string into `[KIND[:MODIFIERS]=]NAME[:NEW_NAME]`, but leaves parsing/validating those parts to later steps.
- This step also gets its own (disposable) unit test, to make sure it works as expected.
- A context struct reduces the burden of parameter passing, and makes it easier to write error messages that adapt to nightly/stable compilers.
- Fewer calls to `nightly_options` helper functions, because at this point we can get the same information from `UnstableOptions` and `UnstableFeatures` (which are downstream of earlier calls to those helper functions).
There should be no overall change in compiler behaviour.
Fixup some test directives
- A random comment had somehow been turned into an `//`@`` directive.
- More dubiously I also removed leading spaces from directives in 3 UI tests for consistency. These are the only rustc tests that use that formatting.
r? `@jieyouxu`
Diagnostics for let mut in item context
The diagnostics for `let` at the top level did not account for `let mut`, which [made the error unclear](https://users.rust-lang.org/t/create-a-vector-of-constants-outside-main/121251/1).
I've made the diagnostic always display a link to valid items. I've added dedicated help for `let mut` case that suggests using a `Mutex` (to steer novice users away from the `static mut` trap). Unfortunately, neither the Rust book, nor libstd docs have dedicated section listing all other types for interior-mutable `static`s.
`suggest_borrow_generic_arg`: instantiate clauses properly
This simplifies and fixes the way `suggest_borrow_generic_arg` instantiates callees' predicates when testing them to see if a moved argument can instead be borrowed. Previously, it would ICE if the moved argument's type included a region variable, since it was getting passed to a call of `EarlyBinder::instantiate`. This makes the instantiation much more straightforward, which also fixes the ICE.
Fixes#133118
This also modifies `tests/ui/moves/moved-value-on-as-ref-arg.rs` to have more useful bounds on the tests for suggestions to borrow `Borrow` and `BorrowMut` arguments. With its old tautological `T: BorrowMut<T>` bound, this fix would make it suggest a shared borrow for that argument.
Make rustc consider itself a stable compiler when `RUSTC_BOOTSTRAP=-1`
Addresses https://github.com/rust-lang/rust/issues/123404 to allow test writers to specify `//@ rustc-env:RUSTC_BOOTSTRAP=-1` to have a given rustc consider itself a stable rustc. This is only intended for testing usages.
I did not use `RUSTC_BOOTSTRAP=0` because that can be confusing, i.e. one might think that means "not bootstrapping", but "forcing a given rustc to consider itself a stable compiler" is a different use case.
I also added a specific test to check `RUSTC_BOOTSTRAP`'s various values and how that interacts with rustc's stability story w.r.t. features and cli flags.
Noticed when trying to write a test for enabling ICE file dumping on stable.
Dunno if this needs a compiler FCP or MCP, but I can file an MCP or ask someone to start an FCP if needed. Note that `RUSTC_BOOTSTRAP` is a perma-unstable env var and has no stability guarantees (heh) whatsoever. This does not affect bootstrapping because bootstrap never sets `RUSTC_BOOTSTRAP=-1`. If someone does set that when bootstrapping, it is considered PEBKAC.
Accompanying dev-guide PR: https://github.com/rust-lang/rustc-dev-guide/pull/2136
cc `@estebank` and `@rust-lang/wg-diagnostics` for FYI
Check `use<..>` in RPITIT for refinement
`#![feature(precise_capturing_in_traits)]` allows users to write `+ use<>` bounds on RPITITs to control what lifetimes are captured by the RPITIT.
Since RPITITs currently also warn for refinement in implementations, this PR extends that refinement check for cases where we *undercapture* in an implementation, since that may be indirectly "promising" a more relaxed outlives bound than the impl author intended.
For an opaque to be refining, we need to capture *fewer* parameters than those mentioned in the captured params of the trait. For example:
```
trait TypeParam<T> {
fn test() -> impl Sized;
}
// Indirectly capturing a lifetime param through a type param substitution.
impl<'a> TypeParam<&'a ()> for i32 {
fn test() -> impl Sized + use<> {}
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait
}
```
Since the opaque in the method (implicitly) captures `use<Self, T>`, and `Self = i32, T = &'a ()` in the impl, we must mention `'a` in our `use<..>` on the impl.
Tracking:
* https://github.com/rust-lang/rust/issues/130044
Fixes issue 133118.
This also modifies `tests/ui/moves/moved-value-on-as-ref-arg.rs` to have more
useful bounds on the tests for suggestions to borrow `Borrow` and `BorrowMut`
arguments. With its old tautological `T: BorrowMut<T>` bound, this fix would
make it suggest a shared borrow for that argument.
Let chains tests
Filing this as this marks off two of the open issues in #132833:
* extending the tests for `move-guard-if-let-chain.rs` and `conflicting_bindings.rs` to have chains with multiple let's (one implementation could for example search for the first `let` and then terminate).
* An instance where a temporary lives shorter than with nested ifs, breaking compilation: #103476. This was fixed in the end by the if let rescoping work.
Closes#103476
Trim whitespace in RemoveLet primary span
Separate `RemoveLet` span into primary span for `let` and removal suggestion span for `let `, so that primary span does not include whitespace.
Fixes: #133031
Increase accuracy of `if` condition misparse suggestion
Fix#132656.
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body".
```
error: expected `{`, found `map`
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
|
LL | for _ in [1, 2, 3].iter()map(|x| x) {}
| ^^^ expected `{`
|
help: you might have meant to write a method call
|
LL | for _ in [1, 2, 3].iter().map(|x| x) {}
| +
```
If a macro statement has been parsed after `else`, suggest a missing `if`:
```
error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:47:12
|
LL | } else falsy! {} {
| ---- ^^^^^
| |
| expected an `if` or a block after this `else`
|
help: add an `if` if this is the condition of a chained `else if` statement
|
LL | } else if falsy! {} {
| ++
```
Deny capturing late-bound ty/const params in nested opaques
First, this reverts a7f609504c. I can't exactly remember why I approved this specific bit of https://github.com/rust-lang/rust/pull/132466; specifically, I don't know that the purpose of that commit is, and afaict we will never have an opaque that captures late-bound params through a const because opaques can't be used inside of anon consts. Am I missing something `@cjgillot?` Since I can't see a case where this matters, and no tests seem to fail.
The second commit adds a `deny_late_regions: bool` to distinguish `Scope::LateBoundary` which should deny *any* late-bound params or just ty/consts. Then, when resolving opaques we wrap ourselves in a `Scope::LateBoundary { deny_late_regions: false }` so that we deny late-bound ty/const, which fixes a bunch of ICEs that all vaguely look like `impl for<T> Trait<Assoc = impl OtherTrait<T>>`.
I guess this could be achieved other ways; for example, with a different scope kind, or maybe we could just reuse `Scope::Opaque`. But this seems a bit more verbose. I'm open to feedback anyways.
Fixes#131535Fixes#131637Fixes#132530
I opted to remove those crashes tests ^ without adding them as regular tests, since they're basically triggering uninteresting late-bound ICEs far off in the trait solver, and the reason that existing tests such as `tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs` don't ICE are kinda just coincidental (i.e. due to a missing impl block). I don't really feel motivated to add random permutations to tests just to exercise non-lifetime binders.
r? cjgillot
mark is_val_statically_known intrinsic as stably const-callable
The intrinsic doesn't actually "do" anything in terms of language semantics, and we are already using it in stable const fn. So let's just properly mark it as stably const-callable to avoid needing `rustc_allow_const_fn_unstable` (and thus reducing noise and keeping the remaining `rustc_allow_const_fn_unstable` as a more clear signal).
Cc `@rust-lang/lang` usually you have to approve exposing intrinsics in const, but this intrinsic is basically just a compiler implementation detail. So FCP doesn't seem necessary.
Cc `@rust-lang/wg-const-eval`
If a macro statement has been parsed after `else`, suggest a missing `if`:
```
error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:47:12
|
LL | } else falsy! {} {
| ---- ^^^^^
| |
| expected an `if` or a block after this `else`
|
help: add an `if` if this is the condition of a chained `else if` statement
|
LL | } else if falsy! {} {
| ++
```
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body".
```
error: expected `{`, found `map`
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
|
LL | for _ in [1, 2, 3].iter()map(|x| x) {}
| ^^^ expected `{`
|
help: you might have meant to write a method call
|
LL | for _ in [1, 2, 3].iter().map(|x| x) {}
| +
```