Turns out, this has some really bad perf implications in large types (issue #88862). While we technically can handle them fine, it doesn't change test output either way. For now, revert with an added benchmark. Future attempts to change this back will have to consider perf.
Validate builtin attributes for macro args.
This adds some validation for `path`, `crate_type`, and `recursion_limit` attributes so that they will now return an error if you attempt to pass a macro into them (such as `#[path = foo!()]`). Previously, the attribute would be completely ignored. These attributes are special because their values need to be known before/during expansion.
cc #87681
Now `Fields` is just a `Vec` of patterns, with some extra info on the
side to reconstruct patterns when needed. This emphasizes that this
extra info is not central to the algorithm.
Once this anonymization has performed, we have no
way of recovering the original names during NLL
borrow checking. Keeping the original names allows
error messages in full NLL mode to contain the original
bound region names.
As a result, the typeck results may contain types that
differ only in the names used for their bound regions. However,
anonimization of bound regions does not guarantee that
all distinct types are unqual (e.g. not subtypes of each other).
For example, `for<'a> fn(&'a u32, &'a u32)` and
`for<'b, 'c> fn(&'b u32, &'c u32)` are subtypes of each other,
as explained here:
63cc2bb3d0/compiler/rustc_infer/src/infer/nll_relate/mod.rs (L682-L690)
Therefore, any code handling types with higher-ranked regions already
needs to handle the case where two distinct `Ty`s are 'actually'
equal.
Currently, we use a relatively 'small' span for THIR
expressions generated by an 'adjustment' (e.g. an autoderef,
autoborrow, unsizing). As a result, if a borrow generated
by an adustment ends up causing a borrowcheck error, for example:
```rust
let mut my_var = String::new();
let my_ref = &my_var
my_var.push('a');
my_ref;
```
then the span for the mutable borrow may end up referring
to only the base expression (e.g. `my_var`), rather than
the method call which triggered the mutable borrow
(e.g. `my_var.push('a')`)
Due to a quirk of the MIR borrowck implementation,
this doesn't always get exposed in migration mode,
but it does in many cases.
This commit makes THIR building consistently use 'larger'
spans for adjustment expressions
The intent of this change it make it clearer to users
when it's the specific way in which a variable is
used (for example, in a method call) that produdes
a borrowcheck error. For example, an error message
claiming that a 'mutable borrow occurs here' might
be confusing if it just points at a usage of a variable
(e.g. `my_var`), when no `&mut` is in sight. Pointing
at the entire expression should help to emphasize
that the method call itself is responsible for
the mutable borrow.
In several cases, this makes the `#![feature(nll)]` diagnostic
output match up exactly with the default (migration mode) output.
As a result, several `.nll.stderr` files end up getting removed
entirely.
Enable new pass manager with LLVM 13
The new pass manager is enabled by default in clang since Clang/LLVM 13. Per the recent discussion on llvm-dev (https://lists.llvm.org/pipermail/llvm-dev/2021-August/152305.html) the legacy pass manager will be unmaintained in LLVM 14 and removed entirely in LLVM 15.
This switches us to use the new pass manager if LLVM >= 13 is used. It's possible to still use the old pass manager using `-Z new-llvm-pass-manager=no`.
Introduce `Rvalue::ShallowInitBox`
Polished version of #88700.
Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.
In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.
`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.
Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
The new pass manager is enabled by default in clang since
Clang/LLVM 13. While the discussion about this is still ongoing
(https://lists.llvm.org/pipermail/llvm-dev/2021-August/152305.html)
it's expected that support for the legacy pass manager will be
dropped either in LLVM 14 or 15.
This switches us to use the new pass manager if LLVM >= 13 is used.
make `#[track_caller]` actually do stuff in `Steal::borrow`
makes this ICE message useful:
``thread 'rustc' panicked at 'attempted to read from stolen value', /rustc/ac2d9fc509e36d1b32513744adf58c34bcc4f43c\compiler\rustc_data_structures\src\steal.rs:37:21``
Rollup of 8 pull requests
Successful merges:
- #88893 (Add 1.56.0 release notes)
- #89001 (Be explicit about using Binder::dummy)
- #89072 (Avoid a couple of Symbol::as_str calls in cg_llvm )
- #89104 (Simplify scoped_thread)
- #89208 ([rfc 2229] Drop fully captured upvars in the same order as the regular drop code)
- #89210 (Add missing time complexities to linked_list.rs)
- #89217 (Enable "generate-link-to-definition" option on rust tools docs as well)
- #89221 (Give better error for `macro_rules! name!`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Add basic checks for well-formedness of `fn`/`fn_mut` lang items
This pull request fixes#83471. Lang items are never actually checked for well-formedness (#9307). This means that one can get an ICE quite easily, e.g. as follows:
```rust
#![feature(lang_items)]
#[lang = "fn"]
trait MyFn {
const call: i32 = 42;
}
fn main() {
(|| 42)();
}
```
or this:
```rust
#![feature(lang_items)]
#[lang = "fn"]
trait MyFn {
fn call(i: i32, j: i32);
}
fn main() {
(|| 42)();
}
```
Ideally, there should probably be a more comprehensive strategy for checking lang items for well-formedness, but for the time being, I have added some rudimentary well-formedness checks that prevent #83471 and similar issues.
[rfc 2229] Drop fully captured upvars in the same order as the regular drop code
Currently, with the new 2021 edition, if a closure captures all of the
fields of an upvar, we'll drop those fields in the order they are used
within the closure instead of the normal drop order (the definition
order of the fields in the type).
This changes that so we sort the captured fields by the definition order
which causes them to drop in that same order as well.
Fixesrust-lang/project-rfc-2229#42
r? `@nikomatsakis`
Avoid a couple of Symbol::as_str calls in cg_llvm
This should improve performance a tiny bit. Also remove `Symbol::len` and make `SymbolIndex` private.
Be explicit about using Binder::dummy
This is somewhat of a late followup to the binder refactor PR. It removes `ToPredicate` and `ToPolyTraitImpls` that hide the use of `Binder::dummy`. While this does make code a bit more verbose, it allows us be more careful about where we create binders.
Another alternative here might be to add a new trait `ToBinder` or something with a `dummy()` fn. Which could still allow grepping but allows doing something like `trait_ref.dummy()` (but I also wonder if longer-term, it would be better to be even more explicit with a `bind_with_vars(ty::List::empty())` *but* that's not clear yet.
r? ``@nikomatsakis``
The `Option<Module>` version is supported for the case where we don't know whether the `DefId` refers to a module or not.
Non-local traits and enums are also correctly found now.
Revise never type fallback algorithm
This is a rebase of https://github.com/rust-lang/rust/pull/84573, but dropping the stabilization of never type (and the accompanying large test diff).
Each commit builds & has tests updated alongside it, and could be reviewed in a more or less standalone fashion. But it may make more sense to review the PR as a whole, I'm not sure. It should be noted that tests being updated isn't really a good indicator of final behavior -- never_type_fallback is not enabled by default in this PR, so we can't really see the full effects of the commits here.
This combines the work by Niko, which is [documented in this gist](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660), with some additional rules largely derived to target specific known patterns that regress with the algorithm solely derived by Niko. We build these from an intuition that:
* In general, fallback to `()` is *sound* in all cases
* But, in general, we *prefer* fallback to `!` as it accepts more code, particularly that written to intentionally use `!` (e.g., Result's with a Infallible/! variant).
When evaluating Niko's proposed algorithm, we find that there are certain cases where fallback to `!` leads to compilation failures in real-world code, and fallback to `()` fixes those errors. In order to allow for stabilization, we need to fix a good portion of these patterns.
The final rule set this PR proposes is that, by default, we fallback from `?T` to `!`, with the following exceptions:
1. `?T: Foo` and `Bar::Baz = ?T` and `(): Foo`, then fallback to `()`
2. Per [Niko's algorithm](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660#proposal-fallback-chooses-between--and--based-on-the-coercion-graph), the "live" `?T` also fallback to `()`.
The first rule is necessary to address a fairly common pattern which boils down to something like the snippet below. Without rule 1, we do not see the closure's return type as needing a () fallback, which leads to compilation failure.
```rust
#![feature(never_type_fallback)]
trait Bar { }
impl Bar for () { }
impl Bar for u32 { }
fn foo<R: Bar>(_: impl Fn() -> R) {}
fn main() {
foo(|| panic!());
}
```
r? `@jackh726`
Currently, with the new 2021 edition, if a closure captures all of the
fields of an upvar, we'll drop those fields in the order they are used
within the closure instead of the normal drop order (the definition
order of the fields in the type).
This changes that so we sort the captured fields by the definition order
which causes them to drop in that same order as well.
Fixes https://github.com/rust-lang/project-rfc-2229/issues/42
Lazy TAIT preparation cleanups
Check that TAIT generics are fully generic in mir typeck instead of wf-check, as wf-check can by definition only check TAIT in return position and not account for TAITs defined in the body of the function
r? `@spastorino` `@nikomatsakis`
fix non_blanket_impls iteration order
We sometimes iterate over all `non_blanket_impls`, not sure if this is observable outside
of error messages (i.e. as incremental bugs). This should fix the underlying issue of #86986.
second attempt of #88718
r? `@nikomatsakis`
Support `#[track_caller]` on closures and generators
## Lang team summary
This PR adds support for placing the `#[track_caller]` attribute on closure and generator expressions. This attribute's addition behaves identically (from a users perspective) to the attribute being placed on the method in impl Fn/FnOnce/FnMut for ... generated by compiler.
The attribute is currently "double" feature gated -- both `stmt_expr_attributes` (preexisting) and `closure_track_caller` (newly added) must be enabled in order to place these attributes on closures.
As the Fn* traits lack a `#[track_caller]` attribute in their definition, caller information does not propagate when invoking closures through dyn Fn*. There is no limitation that this PR adds in supporting this; it can be added in the future.
# Implementation details
This is implemented in the same way as for functions - an extra
location argument is appended to the end of the ABI. For closures,
this argument is *not* part of the 'tupled' argument storing the
parameters - the final closure argument for `#[track_caller]` closures
is no longer a tuple.
For direct (monomorphized) calls, the necessary support was already
implemented - we just needeed to adjust some assertions around checking
the ABI and argument count to take closures into account.
For calls through a trait object, more work was needed.
When creating a `ReifyShim`, we need to create a shim
for the trait method (e.g. `FnOnce::call_mut`) - unlike normal
functions, closures are never invoked directly, and always go through a
trait method.
Additional handling was needed for `InstanceDef::ClosureOnceShim`. In
order to pass location information throgh a direct (monomorphized) call
to `FnOnce::call_once` on an `FnMut` closure, we need to make
`ClosureOnceShim` aware of `#[tracked_caller]`. A new field
`track_caller` is added to `ClosureOnceShim` - this is used by
`InstanceDef::requires_caller` location, allowing codegen to
pass through the extra location argument.
Since `ClosureOnceShim.track_caller` is only used by codegen,
we end up generating two identical MIR shims - one for
`track_caller == true`, and one for `track_caller == false`. However,
these two shims are used by the entire crate (i.e. it's two shims total,
not two shims per unique closure), so this shouldn't a big deal.
This PR allows applying a `#[track_caller]` attribute to a
closure/generator expression. The attribute as interpreted as applying
to the compiler-generated implementation of the corresponding trait
method (`FnOnce::call_once`, `FnMut::call_mut`, `Fn::call`, or
`Generator::resume`).
This feature does not have its own feature gate - however, it requires
`#![feature(stmt_expr_attributes)]` in order to actually apply
an attribute to a closure or generator.
This is implemented in the same way as for functions - an extra
location argument is appended to the end of the ABI. For closures,
this argument is *not* part of the 'tupled' argument storing the
parameters - the final closure argument for `#[track_caller]` closures
is no longer a tuple.
For direct (monomorphized) calls, the necessary support was already
implemented - we just needeed to adjust some assertions around checking
the ABI and argument count to take closures into account.
For calls through a trait object, more work was needed.
When creating a `ReifyShim`, we need to create a shim
for the trait method (e.g. `FnOnce::call_mut`) - unlike normal
functions, closures are never invoked directly, and always go through a
trait method.
Additional handling was needed for `InstanceDef::ClosureOnceShim`. In
order to pass location information throgh a direct (monomorphized) call
to `FnOnce::call_once` on an `FnMut` closure, we need to make
`ClosureOnceShim` aware of `#[tracked_caller]`. A new field
`track_caller` is added to `ClosureOnceShim` - this is used by
`InstanceDef::requires_caller` location, allowing codegen to
pass through the extra location argument.
Since `ClosureOnceShim.track_caller` is only used by codegen,
we end up generating two identical MIR shims - one for
`track_caller == true`, and one for `track_caller == false`. However,
these two shims are used by the entire crate (i.e. it's two shims total,
not two shims per unique closure), so this shouldn't a big deal.
rustc_index: Add some map-like APIs to `IndexVec`
`IndexVec` is often used as a map, but its map APIs are lacking.
This PR adds a couple of useful methods.
"Fix" an overflow in byte position math
r? `@estebank`
help! I fixed the ICE only to brick the diagnostic.
I mean, it was wrong previously (using an already expanded macro span), but it is really bad now XD
Implement `#[must_not_suspend]`
implements #83310
Some notes on the impl:
1. The code that searches for the attribute on the ADT is basically copied from the `must_use` lint. It's not shared, as the logic did diverge
2. The RFC does specify that the attribute can be placed on fn's (and fn-like objects), like `must_use`. I think this is a direct copy from the `must_use` reference definition. This implementation does NOT support this, as I felt that ADT's (+ `impl Trait` + `dyn Trait`) cover the usecase's people actually want on the RFC, and adding an imp for the fn call case would be significantly harder. The `must_use` impl can do a single check at fn call stmt time, but `must_not_suspend` would need to answer the question: "for some value X with type T, find any fn call that COULD have produced this value". That would require significant changes to `generator_interior.rs`, and I would need mentorship on that. `@eholk` and I are discussing it.
3. `@estebank` do you know a way I can make the user-provided `reason` note pop out? right now it seems quite hidden
Also, I am not sure if we should run perf on this
r? `@nikomatsakis`
In suggest_missing_return_type, erase late bound regions after normalizing
Fixes#88360
There might be some hardening that could be done to not error or avoid erroring with LUBing `ReErased` with `ReEmpty`, but this was the most simple fix for this particular case.
r? `@nikomatsakis`
Fix debuginfo for parameters passed via the ScalarPair abi on Windows
Mark all of these as locals so the debugger does not try to interpret
them as being a pointer to the value. This extends the approach used
in #81898.
Fixes#88625
Rollup of 12 pull requests
Successful merges:
- #88795 (Print a note if a character literal contains a variation selector)
- #89015 (core::ascii::escape_default: reduce struct size)
- #89078 (Cleanup: Remove needless reference in ParentHirIterator)
- #89086 (Stabilize `Iterator::map_while`)
- #89096 ([bootstrap] Improve the error message when `ninja` is not found to link to installation instructions)
- #89113 (dont `.ensure()` the `thir_abstract_const` query call in `mir_build`)
- #89114 (Fixes a technicality regarding the size of C's `char` type)
- #89115 (⬆️ rust-analyzer)
- #89126 (Fix ICE when `indirect_structural_match` is allowed)
- #89141 (Impl `Error` for `FromSecsError` without foreign type)
- #89142 (Fix match for placeholder region)
- #89147 (add case for checking const refs in check_const_value_eq)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Fix ICE when `indirect_structural_match` is allowed
Fixes#89088. The ICE is caused by `delay_good_path_bug()`, which is called (indirectly) from a `format!()` macro invocation. I have moved the macro invocation into the `decorate` closure of `struct_span_lint_hir()`, so that the macro is only invoked if the lint is not allowed (i.e., causes at least a warning, and thus prevents `delay_good_path_bug()` from firing).
dont `.ensure()` the `thir_abstract_const` query call in `mir_build`
might fix an ICE seen in #89022 (note: this PR does not close that issue) about attempting to read stolen thir. I couldn't repro the ICE but this `.ensure` seems sus anyway.
r? `@lcnr`
Migrate in-tree crates to 2021
This replaces #89075 (cherry picking some of the commits from there), and closes#88637 and fixes#89074.
It excludes a migration of the library crates for now (see tidy diff) because we have some pending bugs around macro spans to fix there.
I instrumented bootstrap during the migration to make sure all crates moved from 2018 to 2021 had the compatibility warnings applied first.
Originally, the intent was to support cargo fix --edition within bootstrap, but this proved fairly difficult to pull off. We'd need to architect the check functionality to support running cargo check and cargo fix within the same x.py invocation, and only resetting sysroots on check. Further, it was found that cargo fix doesn't behave too well with "not quite workspaces", such as Clippy which has several crates. Bootstrap runs with --manifest-path ... for all the tools, and this makes cargo fix only attempt migration for that crate. We can't use e.g. --workspace due to needing to maintain sysroots for different phases of compilation appropriately.
It is recommended to skip the mass migration of Cargo.toml's to 2021 for review purposes; you can also use `git diff d6cd2c6c87 -I'^edition = .20...$'` to ignore the edition = 2018/21 lines in the diff.
rustc_codegen_llvm: make sse4.2 imply crc32 for LLVM 14
This fixes compiling things like the `snap` crate after
https://reviews.llvm.org/D105462. I added a test that verifies the
additional attribute gets specified, and confirmed that I can build
cargo with both LLVM 13 and 14 with this change applied.
r? `@nagisa` cc `@nikic`
This allows the format_args! macro to keep the pre-expansion code out of
the unsafe block without doing gymnastics with nested `match`
expressions. This reduces codegen.
Don't use projection cache or candidate cache in intercrate mode
Fixes#88969
It appears that *just* disabling the evaluation cache (in #88994)
leads to other issues involving intercrate mode caching. I suspect
that since we now always end up performing the full evaluation
in intercrate mode, we end up 'polluting' the candidate and projection
caches with results that depend on being in intercrate mode in some way.
Previously, we might have hit a cached evaluation (stored during
non-intercrate mode), and skipped doing this extra work in
intercrate mode.
The whole situation with intercrate mode caching is turning into
a mess. Ideally, we would remove intercrate mode entirely - however,
this might require waiting on Chalk.
Register normalization obligations instead of immediately normalizing in opaque type instantiation
For lazy TAIT we will need to instantiate opaque types from within `rustc_infer`, which cannot invoke normalization methods (they are in `rustc_trait_resolution`). So before we move the logic over to `rustc_infer`, we need make sure no normalization happens anymore. This PR resolves that by just registering normalization obligations and continuing.
This PR is best reviewed commit by commit
I also included f7ad36e which is just an independent cleanup that touches the same code and reduces diagnostics noise a bit
r? `@nikomatsakis` cc `@spastorino`
Lower only one HIR owner at a time
Based on https://github.com/rust-lang/rust/pull/83723
Additional diff is here: https://github.com/cjgillot/rust/compare/ownernode...lower-mono
Lowering is very tangled and has a tendency to intertwine the transformation of different items. This PR aims at simplifying the logic by:
- moving global analyses to the resolver (item_generics_num_lifetimes, proc_macros, trait_impls);
- removing a few special cases (non-exported macros and use statements);
- restricting the amount of available information at any one time;
- avoiding back-and-forth between different owners: an item must now be lowered all at once, and its parent cannot refer to its nodes.
I also removed the sorting of bodies by span. The diagnostic ordering changes marginally, since definitions are pretty much sorted already according to the AST. This uncovered a subtlety in thir-unsafeck.
(While these items could logically be in different PRs, the dependency between commits and the amount of conflicts force a monolithic PR.)
This also adjusts the lint docs generation to accept (and ignore) an allow
attribute, rather than expecting the documentation to be immediately followed by
the lint name.
Suggest replacing braces for brackets on array-esque invalid block expr
Newcomers may write `{1, 2, 3}` for making arrays, and the current error message is not informative enough to quickly convince them what is needed to fix the error.
This PR implements a diagnostic for this case, and its output looks like this:
```text
error: this code is interpreted as a block expression, not an array
--> src/lib.rs:1:22
|
1 | const FOO: [u8; 3] = {
| ______________________^
2 | | 1, 2, 3
3 | | };
| |_^
|
= note: to define an array, one would use square brackets instead of curly braces
help: try using [] instead of {}
|
1 | const FOO: [u8; 3] = [
2 | 1, 2, 3
3 | ];
|
```
Fix#87672
Fixes#88969
It appears that *just* disabling the evaluation cache (in #88994)
leads to other issues involving intercrate mode caching. I suspect
that since we now always end up performing the full evaluation
in intercrate mode, we end up 'polluting' the candidate and projection
caches with results that depend on being in intercrate mode in some way.
Previously, we might have hit a cached evaluation (stored during
non-intercrate mode), and skipped doing this extra work in
intercrate mode.
The whole situation with intercrate mode caching is turning into
a mess. Ideally, we would remove intercrate mode entirely - however,
this might require waiting on Chalk.
This fixes compiling things like the `snap` crate after
https://reviews.llvm.org/D105462. I added a test that verifies the
additional attribute gets specified, and confirmed that I can build
cargo with both LLVM 13 and 14 with this change applied.
This just applies the suggested fixes from the compatibility warnings,
leaving any that are in practice spurious in. This is primarily intended to
provide a starting point to identify possible fixes to the migrations (e.g., by
avoiding spurious warnings).
A secondary commit cleans these up where they are false positives (as is true in
many of the cases).
Add initial support for m68k
This patch series adds initial support for m68k making use of the new M68k
backend introduced with LLVM-13. Additional changes will be needed to be
able to actually use the backend for this target.
Add `ConstraintCategory::Usage` for handling aggregate construction
In some cases, we emit borrowcheck diagnostics pointing
at a particular field expression in a struct expression
(e.g. `MyStruct { field: my_expr }`). However, this
behavior currently relies on us choosing the
`ConstraintCategory::Boring` with the 'correct' span.
When adding additional variants to `ConstraintCategory`,
(or changing existing usages away from `ConstraintCategory::Boring`),
the current behavior can easily get broken, since a non-boring
constraint will get chosen over a boring one.
To make the diagnostic output less fragile, this commit
adds a `ConstraintCategory::Usage` variant. We use this variant
for the temporary assignments created for each field of
an aggregate we are constructing.
Using this new variant, we can emit a message mentioning
"this usage", emphasizing the fact that the error message
is related to the specific use site (in the struct expression).
This is preparation for additional work on improving NLL error messages
(see #57374)
Querify `FnAbi::of_{fn_ptr,instance}` as `fn_abi_of_{fn_ptr,instance}`.
*Note: opening this PR as draft because it's based on #88499*
This more or less replicates the `LayoutOf::layout_of` setup from #88499, to replace `FnAbi::of_{fn_ptr,instance}` with `FnAbiOf::fn_abi_of_{fn_ptr,instance}`, and also route them through queries (which `layout_of` has used for a while).
The two changes at the use sites (other than the names) are:
* return type is now wrapped in `&'tcx`
* the value *is* interned, which may affect performance
* the `extra_args` list is now an interned `&'tcx ty::List<Ty<'tcx>>`
* should be cheap (it's empty for anything other than C variadics)
Theoretically, a `FnAbiOfHelpers` implementer could choose to keep the `Result<...>` instead of eagerly erroring, but the only existing users of these APIs are codegen backends, so they don't (want to) take advantage of this.
At least miri could make use of this, since it prefers propagating errors (it "just" doesn't use `FnAbi` yet - cc `@RalfJung).`
The way this is done is probably less efficient than what is possible, because the queries handle the correctness-oriented API (i.e. the split into `fn` pointers vs instances), whereas a lower-level query could end up with more reuse between different instances with identical signatures.
r? `@nagisa` cc `@oli-obk` `@bjorn3`
Convert `debug_assert` to `assert` in `CachingSourceMapView`
I suspect that there's a bug somewhere in this code, which is
leading to the `predicates_of` ICE being seen in #89035
Gather module items after lowering.
This avoids having a non-local analysis inside lowering.
By implementing `hir_module_items` using a visitor, we make sure that iterations and visitors are consistent.
Newcomers may write `{1, 2, 3}` for making arrays, and the current error
message is not informative enough to quickly convince them what is
needed to fix the error.
This PR implements a diagnostic for this case, and its output looks like
this:
```text
error: this code is interpreted as a block expression, not an array
--> src/lib.rs:1:22
|
1 | const FOO: [u8; 3] = {
| ______________________^
2 | | 1, 2, 3
3 | | };
| |_^
|
= note: to define an array, one would use square brackets instead of curly braces
help: try using [] instead of {}
|
1 | const FOO: [u8; 3] = [
2 | 1, 2, 3
3 | ];
|
```
Fix#87672
Suggest better place to add call parentheses for method expressions wrapped in parentheses
I wanted to improve the suggestion a bit to both remove the wrapping parentheses **and** add call parentheses by both calling `suggest_method_call` and using `multipart_suggestion`. But I very quickly ran into a problem where multiple overlapping machine applicable suggestions cannot be properly applied together. So I applied the suggestion from the issue and only added the call parentheses directly after the expression.
Fixes: https://github.com/rust-lang/rust/issues/89044
Add a separate error for `dyn Trait` in `const fn`
Previously "trait bounds other than `Sized` on const fn parameters are unstable" error was used for both trait bounds (`<T: Trait>`) and trait objects (`dyn Trait`). This was pretty confusing.
This PR adds a separate error for trait objects: "trait objects in const fn are unstable". The error for trait bounds is otherwise intact.
This is follow up to #88907
r? ``@estebank``
``@rustbot`` label: +A-diagnostics
Fix linting when trailing macro expands to a trailing semi
When a macro is used in the trailing expression position of a block
(e.g. `fn foo() { my_macro!() }`), we currently parse it as an
expression, rather than a statement. As a result, we ended up
using the `NodeId` of the containing statement as our `lint_node_id`,
even though we don't normally do this for macro calls.
If such a macro expands to an expression with a `#[cfg]` attribute,
then the trailing statement can get removed entirely. This lead to
an ICE, since we were usng the `NodeId` of the expression to emit
a lint.
Ths commit makes us skip updating `lint_node_id` when handling
a macro in trailing expression position. This will cause us to
lint at the closest parent of the macro call.
Suggest replacing an inexisting field for an unmentioned field
Fix#87938
This PR adds a suggestion to replace an inexisting field for an
unmentioned field. Given the following code:
```rust
enum Foo {
Bar { alpha: u8, bravo: u8, charlie: u8 },
}
fn foo(foo: Foo) {
match foo {
Foo::Bar {
alpha,
beta, // `bravo` miswritten as `beta` here.
charlie,
} => todo!(),
}
}
```
the compiler now emits the error messages below.
```text
error[E0026]: variant `Foo::Bar` does not have a field named `beta`
--> src/lib.rs:9:13
|
9 | beta, // `bravo` miswritten as `beta` here.
| ^^^^
| |
| variant `Foo::Bar` does not have this field
| help: `Foo::Bar` has a field named `bravo`: `bravo`
```
Note that this suggestion is available iff the number of inexisting
fields and unmentioned fields are both 1.
Propagate coercion cause into `try_coerce`
Currently, `coerce_inner` discards its `ObligationCause`
when calling `try_coerce`. This interfers with other
diagnostc improvements I'm working on, since we will lose
the original span by the time the actual coercion occurs.
Additionally, we now use the span of the trailing expression
(rather than the span of the entire function) when performing
a coercion in `check_return_expr`. This currently has no visible
effect on any of the unit tests, but will unblock future
diagnostic improvements.
Start block is not allowed to have basic block predecessors
* The MIR validator is extended to detect potential violations.
* The start block has no predecessors after building MIR, so no changes are required there.
* The SimplifyCfg could previously violate this requirement when collapsing goto chains, so transformation is disabled for the start block, which also substantially simplifies the implementation.
* The LLVM function entry block also must not have basic block predecessors. Previously, to ensure that code generation had to perform necessary adjustments. This now became unnecessary.
The motivation behind the change is to align with analogous requirement in LLVM, and to avoid potential latent bugs like the one reported in #88043.
Disable the evaluation cache when in intercrate mode
It's possible to use the same `InferCtxt` with both
an intercrate and non-intercrate `SelectionContext`. However,
the local (inferctxt) evaluation cache is not aware of this
distinction, so this kind of `InferCtxt` re-use will pollute
the cache wth bad results.
This commit avoids the issue by disabling the evaluation cache
entirely during intercrate mode.
Simplify lazy DefPathHash decoding by using an on-disk hash table.
This PR simplifies the logic around mapping `DefPathHash` values encountered during incremental compilation to valid `DefId`s in the current session. It is able to do so by using an on-disk hash table encoding that allows for looking up values directly, i.e. without deserializing the entire table.
The main simplification comes from not having to keep track of `DefPathHashes` being used during the compilation session.
Skip single use lifetime lint for generated opaque types
Fix: #77175
The opaque type generated by the desugaring process of an async function uses the lifetimes defined by the originating function. The DefId for the lifetimes in the opaque type are different from the ones in the originating async function - as they should be, as far as I understand, and could therefore be considered a single use lifetimes, this causes the single_use_lifetimes lint to fail compilation if explicitly denied. This fix skips the lint for lifetimes used only once in generated opaque types for an async function that are declared in the parent async function definition.
More info in the comments on the original issue: 1 and 2
Use explicit log level in tracing instrument macro
Specify a log level in tracing instrument macro explicitly.
Additionally reduce the used log level from a default info level to a
debug level (all of those appear to be developer oriented logs, so there
should be no need to include them in release builds).
Move the Lock into symbol::Interner
This makes it easier to make the symbol interner (near) lock free in case of concurrent accesses in the future.
With https://github.com/rust-lang/rust/pull/87867 landed this shouldn't affect performance anymore.
Fast reject for NeedsNonConstDrop
Hopefully fixes the regression in #88558.
I've always wanted to help with the performance of rustc, but it doesn't feel the same when you are fixing a regression caused by your own PR...
r? `@oli-obk`
If any block on a goto chain has more than one predecessor, then the new
start block would have basic block predecessors.
Skip the transformation for the start block altogether, to avoid
violating the new invariant that the start block does not have any basic
block predecessors.
inline(always) on check_recursion_limit
r? `@oli-obk`
#88558 caused a regression, this PR adds `#[inline(always)]` to `check_recursion_limit`, a possible suspect of that regression.
Extend the `DepthFirstSearch` iterator so that it can be re-used and
extended with add'l start nodes. Then replace the FxHashSets of nodes
we were using in the fallback analysis with a single iterator. This
way we won't re-walk portions of the graph that are reached more than
once, and we also do less allocation etc.
Instead, we now record those type variables that are the target of a
`NeverToAny` adjustment and consider those to be the "diverging" type
variables. This allows us to remove the special case logic that
creates a type variable for `!` in coercion.