This PR has several interconnected pieces:
1. In some of the NLL region error code, we now pass
around an `ObligationCause`, instead of just a plain `Span`.
This gets forwarded into `fulfill_cx.register_predicate_obligation`
during error reporting.
2. The general InferCtxt error reporting code is extended to
handle `ObligationCauseCode::BindingObligation`
3. A new enum variant `ConstraintCategory::Predicate` is added.
We try to avoid using this as the 'best blame constraint' - instead,
we use it to enhance the `ObligationCause` of the `BlameConstraint`
that we do end up choosing.
As a result, several NLL error messages now contain the same
"the lifetime requirement is introduced here" message as non-NLL
errors.
Having an `ObligationCause` available will likely prove useful
for future improvements to NLL error messages.
Don't normalize opaque types with escaping late-bound regions
Fixes#88862
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.
Needs a perf run once https://github.com/rust-lang/rustc-perf/pull/1033 is merged
r? `@nikomatsakis`
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.
The comment seems incorrect. Testing revealed that the examples in
question still work (as well as some variants) even without the
special casing here.
We now fallback type variables using the following rules:
* Construct a coercion graph `A -> B` where `A` and `B` are unresolved
type variables or the `!` type.
* Let D be those variables that are reachable from `!`.
* Let N be those variables that are reachable from a variable not in
D.
* All variables in (D \ N) fallback to `!`.
* All variables in (D & N) fallback to `()`.
Suggest removing `#![feature]` for library features that have been stabilized
Issue: https://github.com/rust-lang/rust/issues/88802
Delayed the check if #![feature] has been used to enable lib features in a non-nightly build to occur after TyCtxt has been constructed.
Allow `panic!("{}", computed_str)` in const fn.
Special-case `panic!("{}", arg)` and translate it to `panic_display(&arg)`. `panic_display` will behave like `panic_any` in cosnt eval and behave like `panic!(format_args!("{}", arg))` in runtime.
This should bring Rust 2015 and 2021 to feature parity in terms of `const_panic`; and hopefully would unblock the stabilisation of #51999.
`@rustbot` modify labels: +T-compiler +T-libs +A-const-eval +A-const-fn
r? `@oli-obk`
Fix handling of `hir::GenericArg::Infer` in `wrong_number_of_generic_args.rs`
Fixes#87563. More precisely, I have fixed the "index out of bounds" error, which is what #87563 is about. The example given there still ICEs due to running into this `todo!()`, but I'd say that this is a separate issue:
c3c0f80d60/compiler/rustc_typeck/src/astconv/mod.rs (L460-L463)
Do not issue E0071 if a type error has already been reported
Fixes#88844. A suggested fix is already included in the error message for E0412, so with my changes, E0071 is simply not emitted anymore if the type in question is a "type error". This makes sense, I think, because we cannot confidently state that something is "not a struct" if we couldn't resolve it properly; and it's unnecessary to pollute the output with this additional error message, as it is a direct consequence of the former error.
I have also addressed the issue mentioned in https://github.com/rust-lang/rust/issues/88844#issuecomment-917324856 by changing the fixed example in the documentation to more closely match the erroneous code example.
Point to closure when emitting 'cannot move out' for captured variable
Attempts to fix#87456. The error message now points to the capturing closure, but I was not able to explain _why_ the closure implements `Fn` or `FnMut` (`TypeckResults::closure_kind_origins` did not contain anything for the closure in question).
cc `@Aaron1011`
Remove concept of 'completion' from the projection cache
Fixes#88910
When we initially store a `NormalizedTy` in the projection cache,
we discard all obligations that we can (while ensuring that we
don't cause any issues with incremental compilation).
Marking a projection cache entry as 'completed' discards all
obligations associated with it. This can only cause problems,
since any obligations stored in the cache are there for a reason
(e.g. they evaluate to `EvaluatedToOkModuloRegions`).
This commit removes `complete` and `complete_normalized` entirely.
PassWrapper: handle separate Module*SanitizerPass
Change ab41eef9aca3 in LLVM split MemorySanitizerPass into
MemorySanitizerPass for functions and ModuleMemorySanitizerPass for
modules. There's a related change for ThreadSanitizerPass, and in here
since we're using a ModulePassManager I only add the module flavor of
the pass on LLVM 14.
r? `@nikic` cc `@nagisa`
Improve error message for type mismatch in generator arguments
Fixes#88653. The code example given there is invalid because the `Generator` trait (unlike the `Fn` traits) does not take the generator arguments in tupled-up form (because there can only be one argument, from my understanding). Hence, the type error in the example in #88653 is correct, because the given generator takes a `bool` argument, whereas the function's return type talks about a generator with a `(bool,)` argument.
The error message is both confusing and wrong, though: It is wrong because it displays the wrong "expected signature", and it is confusing because both the "expected" and "found" notes point at the same span. With my changes, I get the following, more helpful output:
```
error[E0631]: type mismatch in generator arguments
--> test.rs:5:22
|
5 | fn foo(bar: bool) -> impl Generator<(bool,)> {
| ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
6 | |bar| {
| ----- found signature of `fn(bool) -> _`
```
Couple of changes to FileSearch and SearchPath
* Turn a couple of regular comments into doc comments
* Move `get_tools_search_paths` from `FileSearch` to `Session`
* Use Lrc instead of Option to avoid duplication of a `SearchPath`
Fix ICE in `improper_ctypes_definitions` lint with all-ZST transparent types
Fixes#87496. There is also another function in the same file that looks fishy, but I haven't been able to produce an ICE there, and in any case, it's not related to #87496:
fd853c00e2/compiler/rustc_lint/src/types.rs (L720-L734)
r? ```@JohnTitor```
Introduce a fast path that avoids the `debug_tuple` abstraction when deriving Debug for unit-like enum variants.
The intent here is to allow LLVM to remove the switch entirely in favor of an
indexed load from a table of constant strings, which is likely what the
programmer would write in C. Unfortunately, LLVM currently doesn't perform this
optimization due to a bug, but there is [a
patch](https://reviews.llvm.org/D109565) that fixes this issue. I've verified
that, with that patch applied on top of this commit, Debug for unit-like tuple
variants becomes a load, reducing the O(n) code bloat to O(1).
Note that inlining `DebugTuple::finish()` wasn't enough to allow LLVM to
optimize the code properly; I had to avoid the abstraction entirely. Not using
the abstraction is likely better for compile time anyway.
Part of #88793.
r? `@oli-obk`
Point at argument instead of call for their obligations
When an obligation is introduced by a specific `fn` argument, point at
the argument instead of the `fn` call if the obligation fails to be
fulfilled.
Move the information about pointing at the call argument expression in
an unmet obligation span from the `FulfillmentError` to a new
`ObligationCauseCode`.
When giving an error about an obligation introduced by a function call
that an argument doesn't fulfill, and that argument is a block, add a
span_label pointing at the innermost tail expression.
Current output:
```
error[E0425]: cannot find value `x` in this scope
--> f10.rs:4:14
|
4 | Some(x * 2)
| ^ not found in this scope
error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
--> f10.rs:2:31
|
2 | let p = Some(45).and_then({
| ______________________--------_^
| | |
| | required by a bound introduced by this call
3 | | |x| println!("doubling {}", x);
4 | | Some(x * 2)
| | -----------
5 | | });
| |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
|
= help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
```
Previous output:
```
error[E0425]: cannot find value `x` in this scope
--> f10.rs:4:14
|
4 | Some(x * 2)
| ^ not found in this scope
error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
--> f10.rs:2:22
|
2 | let p = Some(45).and_then({
| ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
|
= help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
```
Partially address #27300. Will require rebasing on top of #88546.
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.
Rollup of 10 pull requests
Successful merges:
- #88292 (Enable --generate-link-to-definition for rustc's docs)
- #88729 (Recover from `Foo(a: 1, b: 2)`)
- #88875 (cleanup(rustc_trait_selection): remove vestigial code from rustc_on_unimplemented)
- #88892 (Move object safety suggestions to the end of the error)
- #88928 (Document the closure arguments for `reduce`.)
- #88976 (Clean up and add doc comments for CStr)
- #88983 (Allow calling `get_body_with_borrowck_facts` without `-Z polonius`)
- #88985 (Update clobber_abi list to include k[1-7] regs)
- #88986 (Update the backtrace crate)
- #89009 (Fix typo in `break` docs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
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 patch adds a separeta error for trait objects: "trait objects in const fn
are unstable". The error for trait bounds is otherwise intact.
If #![feature] is used outside the nightly channel for only lib
features, the check will be delayed to the stability pass after
parsing. This is done so that appropriate help messages can be shown if
the #![feature] has been used needlessly
Allow calling `get_body_with_borrowck_facts` without `-Z polonius`
For my [static analysis tool](https://github.com/willcrichton/flowistry), I need to access the set of outlives-constraints. Recently, #86977 merged a way to access these facts via Polonius. However, the merged implementation requires `-Z polonius` to be provided to use this feature. This uses Polonius for borrow checking on the entire crate, which as described [here](https://rust-lang.zulipchat.com/#narrow/stream/186049-t-compiler.2Fwg-polonius/topic/Polonius.20performance.20in.20a.20rustc.20plugin/near/251301631), is very slow.
This PR allows `get_body_with_borrowck_facts` to be called without `-Z polonius`. This is essential for my tool to run in a sensible length of time. This is a temporary patch as the Polonius-related APIs develop -- I can update my code as future changes happen.
Additionally, this PR also makes public two APIs that were previously public but then became private after `rustc_mir` got broken up: `rustc_mir_dataflow::framework::graphviz` and `rustc_mir_transform::MirPass`. I need both of these for my analysis tool. (I can break this change into a separate PR if necessary.)
cleanup(rustc_trait_selection): remove vestigial code from rustc_on_unimplemented
This isn't allowed by the validator, and seems to be unused.
When it was added in ed10a3faae,
it was used on `Sized`, and that usage is gone.
Recover from `Foo(a: 1, b: 2)`
Detect likely `struct` literal using parentheses as delimiters and emit
targeted suggestion instead of type ascription parse error.
Fix#61326.
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)
Disable RemoveZsts in generators to avoid query cycles
Querying layout of a generator requires its optimized MIR. Thus
computing layout during MIR optimization of a generator might create a
query cycle. Disable RemoveZsts in generators to avoid the issue
(similar approach is used in ConstProp transform already).
Fixes#88972.
Change ab41eef9aca3 in LLVM split MemorySanitizerPass into
MemorySanitizerPass for functions and ModuleMemorySanitizerPass for
modules. There's a related change for ThreadSanitizerPass, and in here
since we're using a ModulePassManager I only add the module flavor of
the pass on LLVM 14.
r? @nikic cc @nagisa
When evaluating an `ExprKind::Call`, we first have to `check_expr` on it's
callee. When this one is a `ExprKind::Path`, we had to evaluate the bounds
introduced for its arguments, but by the time we evaluated them we no
longer had access to the argument spans. Now we special case this so
that we can point at the right place on unsatisfied bounds. This also
allows the E0277 deduplication to kick in correctly, so we now emit
fewer errors.
When giving an error about an obligation introduced by a function call
that an argument doesn't fulfill, and that argument is a block, add a
span_label pointing at the innermost tail expression.
Move the information about pointing at the call argument expression in
an unmet obligation span from the `FulfillmentError` to a new
`ObligationCauseCode`.
Add non_exhaustive_omitted_patterns lint related to rfc-2008-non_exhaustive
Fixes: #84332
This PR adds `non_exhaustive_omitted_patterns`, an allow by default lint that is triggered when a `non_exhaustive` type is missing explicit patterns. The warning or deny attribute can be put above the wildcard `_` pattern on enums or on the expression for enums or structs. The lint is capable of warning about multiple types within the same pattern. This lint will not be triggered for `if let ..` patterns.
```rust
// crate A
#[non_exhaustive]
pub struct Foo {
a: u8,
b: usize,
}
#[non_exhaustive]
pub enum Bar {
A(Foo),
B,
}
// crate B
#[deny(non_exhaustive_omitted_patterns)] // here
match Bar::B {
Bar::B => {}
#[deny(non_exhaustive_omitted_patterns)] // or here
_ => {}
}
#[warn(non_exhaustive_omitted_patterns)] // only here
let Foo { a, .. } = Foo::default();
#[deny(non_exhaustive_omitted_patterns)]
match Bar::B {
// triggers for Bar::B, and Foo.b
Bar::A(Foo { a, .. }) => {}
// if the attribute was here only Bar::B would cause a warning
_ => {}
}
```
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.
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.
Highlight the `const fn` if error happened because of a bound on the impl block
Currently, for the following code, the compiler produces the errors like the
following:
```rust
struct Type<T>(T);
impl<T: Clone> Type<T> {
const fn f() {}
}
```
```text
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> ./test.rs:3:6
|
3 | impl<T: Clone> Type<T> {
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
```
This can be confusing (especially to newcomers) since the error mentions "const fn parameters", but highlights only the impl.
This PR adds function highlighting, changing the error to the following:
```text
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> ./test.rs:3:6
|
3 | impl<T: Clone> Type<T> {
| ^
4 | pub const fn f() {}
| ---------------- function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
```
---
I've originally wanted to point directly to `const` token, but couldn't find a way to get it's span. It seems like this span is lost during the AST -> HIR lowering.
Also, since the errors for object casts in `const fn`s (`&T` -> `&dyn Trait`) seem to trigger the same error, this PR accidentally changes these errors too. Not sure if it's desired or how to fix this.
P.S. it's my first time contributing to diagnostics, so feedback is very appreciated!
---
r? ```@estebank```
```@rustbot``` label: +A-diagnostics
Revert anon union parsing
Revert PR #84571 and #85515, which implemented anonymous union parsing in a manner that broke the context-sensitivity for the `union` keyword and thus broke stable Rust code.
Fix#88583.
Accept `m!{ .. }.method()` and `m!{ .. }?` statements.
This PR fixes something that I keep running into when using `quote!{}.into()` in a proc macro to convert the `proc_macro2::TokenStream` to a `proc_macro::TokenStream`:
Before:
```
error: expected expression, found `.`
--> src/lib.rs:6:6
|
4 | quote! {
5 | ...
6 | }.into()
| ^ expected expression
```
After:
```
```
(No output, compiles fine.)
---
Context:
For expressions like `{ 1 }` and `if true { 1 } else { 2 }`, we accept them as full statements without a trailing `;`, which means the following is not accepted:
```rust
{ 1 } - 1 // error
```
since that is parsed as two statements: `{ 1 }` and `-1`. Syntactically correct, but the type of `{ 1 }` should be `()` as there is no `;`.
However, for specifically `.` and `?` after the `}`, we do [continue parsing it as an expression](13db8440bb/compiler/rustc_parse/src/parser/expr.rs (L864-L876)):
```rust
{ "abc" }.len(); // ok
```
For braced macro invocations, we do not do this:
```rust
vec![1, 2, 3].len(); // ok
vec!{1, 2, 3}.len(); // error
```
(It parses `vec!{1, 2, 3}` as a full statement, and then complains about `.len()` not being a valid expression.)
This PR changes this to also look for a `.` and `?` after a braced macro invocation. We can be sure the macro is an expression and not a full statement in those cases, since no statement can start with a `.` or `?`.
Introduce -Z remap-cwd-prefix switch
This switch remaps any absolute paths rooted under the current
working directory to a new value. This includes remapping the
debug info in `DW_AT_comp_dir` and `DW_AT_decl_file`.
Importantly, this flag does not require passing the current working
directory to the compiler, such that the command line can be
run on any machine (with the same input files) and produce the
same results. This is critical property for debugging compiler
issues that crop up on remote machines.
This is based on adetaylor's dbc4ae7cba
Major Change Proposal: https://github.com/rust-lang/compiler-team/issues/450
Discussed on #38322. Would resolve issue #87325.
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).
Querying layout of a generator requires its optimized MIR. Thus
computing layout during MIR optimization of a generator might create a
query cycle. Disable RemoveZsts in generators to avoid the issue
(similar approach is used in ConstProp transform already).
Use a separate interner type for UniqueTypeId
Using symbol::Interner makes it very easy to mixup UniqueTypeId symbols
with the global interner. In fact the Debug implementation of
UniqueTypeId did exactly this.
Using a separate interner type also avoids prefilling the interner with
unused symbols and allow for optimizing the symbol interner for parallel
access without negatively affecting the single threaded module codegen.
Const drop
The changes are pretty primitive at this point. But at least it works. ^-^
Problems with the current change that I can think of now:
- [x] `~const Drop` shouldn't change anything in the non-const world.
- [x] types that do not have drop glues shouldn't fail to satisfy `~const Drop` in const contexts. `struct S { a: u8, b: u16 }` This might not fail for `needs_non_const_drop`, but it will fail in `rustc_trait_selection`.
- [x] The current change accepts types that have `const Drop` impls but have non-const `Drop` glue.
Fixes#88424.
Significant Changes:
- `~const Drop` is no longer treated as a normal trait bound. In non-const contexts, this bound has no effect, but in const contexts, this restricts the input type and all of its transitive fields to either a) have a `const Drop` impl or b) can be trivially dropped (i.e. no drop glue)
- `T: ~const Drop` will not be linted like `T: Drop`.
- Instead of recursing and iterating through the type in `rustc_mir::transform::check_consts`, we use the trait system to special case `~const Drop`. See [`rustc_trait_selection::...::candidate_assembly#assemble_const_drop_candidates`](https://github.com/fee1-dead/rust/blob/const-drop/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L817) and others.
Changes not related to `const Drop`ping and/or changes that are insignificant:
- `Node.constness_for_typeck` no longer returns `hir::Constness::Const` for type aliases in traits. This was previously used to hack how we determine default bound constness for items. But because we now use an explicit opt-in, it is no longer needed.
- Removed `is_const_impl_raw` query. We have `impl_constness`, and the only existing use of that query uses `HirId`, which means we can just operate it with hir.
- `ty::Destructor` now has a field `constness`, which represents the constness of the destructor.
r? `@oli-obk`
Fixes#88910
When we initially store a `NormalizedTy` in the projection cache,
we discard all obligations that we can (while ensuring that we
don't cause any issues with incremental compilation).
Marking a projection cache entry as 'completed' discards all
obligations associated with it. This can only cause problems,
since any obligations stored in the cache are there for a reason
(e.g. they evaluate to `EvaluatedToOkModuloRegions`).
This commit removes `complete` and `complete_normalized` entirely.
Add linting on non_exhaustive structs and enum variants
Add ui tests for non_exhaustive reachable lint
Rename to non_exhaustive_omitted_patterns and avoid triggering on if let
This encoding allows for random access without an expensive upfront decoding
state which in turn allows simplifying the DefPathIndex lookup logic without
regressing performance.
Enum should prefer discriminant zero for niche
Given an enum with unassigned zero-discriminant, rust should prefer it for niche selection.
Zero as discriminant for `Option<Enum>` makes it possible for LLVM to optimize resulting asm.
- Eliminate branch when expected value coincides.
- Use smaller instruction `test eax, eax` instead of `cmp eax, ?`
- Possible interaction with zeroed memory?
Example:
```rust
pub enum Size {
One = 1,
Two = 2,
Three = 3,
}
pub fn handle(x: Option<Size>) -> u8 {
match x {
None => {0}
Some(size) => {size as u8}
}
}
```
In this case discriminant zero is available as a niche.
Above example on nightly:
```asm
mov eax, edi
cmp al, 4
jne .LBB0_2
xor eax, eax
.LBB0_2:
ret
```
PR:
```asm
mov eax, edi
ret
```
I created this PR because I had a performance regression when I tried to use an enum to represent legal grapheme byte-length for utf8.
Using an enum instead of `NonZeroU8` [here](d683304f5d/src/internal/decoder_incomplete.rs (L90))
resulted in a performance regression of about 5%.
I consider this to be a somewhat realistic benchmark.
Thanks to `@ogoffart` for pointing me in the right direction!
Edit: Updated description
Improve error message for missing trait in trait impl
Fixes#88818. For the following example:
```rust
struct S { }
impl for S { }
```
the current output is:
```
error: missing trait in a trait impl
--> t1.rs:2:5
|
2 | impl for S { }
| ^
```
With my changes, I get:
```
error: missing trait in a trait impl
--> t1.rs:2:5
|
2 | impl for S { }
| ^
|
help: add a trait here
|
2 | impl Trait for S { }
| +++++
help: for an inherent impl, drop this `for`
|
2 - impl for S { }
2 + impl S { }
|
```
Fix duplicate bounds for const_trait_impl
Fixes#88383.
Compare the constness of the candidates before winnowing and removing a `~const` `BoundCandidate`.
Use smaller spans for some structured suggestions
Use more accurate suggestion spans for
* argument parse error
* fully qualified path
* missing code block type
* numeric casts
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
PR #81898.
Currently, for the following code, the compiler produces the errors like the
following error:
```rust
struct Type<T>
impl<T: Clone> Type<T> {
fn const f() {}
}
```
```text
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> ./test.rs:3:6
|
3 | impl<T: Clone> Type<T> {
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
```
This can be confusing (especially to newcomers) since the error mentions
"const fn parameters", but highlights only the impl.
This commits adds function highlighting, changing the error to the following:
```text
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
--> ./test.rs:3:6
|
3 | impl<T: Clone> Type<T> {
| ^
4 | pub const fn f() {}
| ---------------- function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
```
Using symbol::Interner makes it very easy to mixup UniqueTypeId symbols
with the global interner. In fact the Debug implementation of
UniqueTypeId did exactly this.
Using a separate interner type also avoids prefilling the interner with
unused symbols and allow for optimizing the symbol interner for parallel
access without negatively affecting the single threaded module codegen.
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.
ARMv6K Nintendo 3DS Tier 3 target added
Addition of the target specifications to build .elf files for Nintendo 3DS (ARMv6K, Horizon). Requires devkitARM 3DS toolkit for system libraries and arm-none-eabi-gcc linker.
Introduce NullOp::AlignOf
This PR introduces `Rvalue::NullaryOp(NullOp::AlignOf, ty)`, which will be lowered from `align_of`, similar to `size_of` lowering to `Rvalue::NullaryOp(NullOp::SizeOf, ty)`.
The changes are originally part of #88700 but since it's not dependent on other changes and could have performance impact on its own, it's separated into its own PR.
Add -Z panic-in-drop={unwind,abort} command-line option
This PR changes `Drop` to abort if an unwinding panic attempts to escape it, making the process abort instead. This has several benefits:
- The current behavior when unwinding out of `Drop` is very unintuitive and easy to miss: unwinding continues, but the remaining drops in scope are simply leaked.
- A lot of unsafe code doesn't expect drops to unwind, which can lead to unsoundness:
- https://github.com/servo/rust-smallvec/issues/14
- https://github.com/bluss/arrayvec/issues/3
- There is a code size and compilation time cost to this: LLVM needs to generate extra landing pads out of all calls in a drop implementation. This can compound when functions are inlined since unwinding will then continue on to process drops in the callee, which can itself unwind, etc.
- Initial measurements show a 3% size reduction and up to 10% compilation time reduction on some crates (`syn`).
One thing to note about `-Z panic-in-drop=abort` is that *all* crates must be built with this option for it to be sound since it makes the compiler assume that dropping `Box<dyn Any>` will never unwind.
cc https://github.com/rust-lang/lang-team/issues/97
Rework DepthFirstSearch API
This expands the API to be more flexible, allowing for more visitation patterns
on graphs. This will be useful to avoid extra datasets (and allocations) in
cases where the expanded DFS API is sufficient.
This also fixes a bug with the previous DFS constructor, which left the start
node not marked as visited (even though it was immediately returned).
Commit written by ```@nikomatsakis``` originally, cherry picked from several commits in work on never type stabilization, but stands alone.
generic_const_exprs: use thir for abstract consts instead of mir
Changes `AbstractConst` building to use `thir` instead of `mir` so that there's less chance of consts unifying when they shouldn't because lowering to mir dropped information (see `abstract-consts-as-cast-5.rs` test)
r? `@lcnr`
Detect stricter constraints on gats where clauses in impls vs trait
I might try to see if I can do a bit more to improve these diagnostics, but any initial feedback is appreciated. I can also do any additional work in a followup PR.
r? `@estebank`
Encode spans relative to the enclosing item
The aim of this PR is to avoid recomputing queries when code is moved without modification.
MCP at https://github.com/rust-lang/compiler-team/issues/443
This is achieved by :
1. storing the HIR owner LocalDefId information inside the span;
2. encoding and decoding spans relative to the enclosing item in the incremental on-disk cache;
3. marking a dependency to the `source_span(LocalDefId)` query when we translate a span from the short (`Span`) representation to its explicit (`SpanData`) representation.
Since all client code uses `Span`, step 3 ensures that all manipulations
of span byte positions actually create the dependency edge between
the caller and the `source_span(LocalDefId)`.
This query return the actual absolute span of the parent item.
As a consequence, any source code motion that changes the absolute byte position of a node will either:
- modify the distance to the parent's beginning, so change the relative span's hash;
- dirty `source_span`, and trigger the incremental recomputation of all code that
depends on the span's absolute byte position.
With this scheme, I believe the dependency tracking to be accurate.
For the moment, the spans are marked during lowering.
I'd rather do this during def-collection,
but the AST MutVisitor is not practical enough just yet.
The only difference is that we attach macro-expanded spans
to their expansion point instead of the macro itself.
Refactor query forcing
The control flow in those functions was very complex, with several layers of continuations.
I tried to simplify the implementation, while keeping essentially the same logic.
Now, all code paths go through `try_execute_query` for the actual query execution.
Communication with the `dep_graph` and the live caches are the only difference between query getting/ensuring/forcing.