return the correct type for closures in `type_of`
A bit unhappy about the way `typeck::check_crate` works rn. Would have preferred to not change `CollectItemTypesVisitor` in this way.
r? ``@nikomatsakis``
Rollup of 7 pull requests
Successful merges:
- #92058 (Make Run button visible on hover)
- #92288 (Fix a pair of mistyped test cases in `std::net::ip`)
- #92349 (Fix rustdoc::private_doc_tests lint for public re-exported items)
- #92360 (Some cleanups around check_argument_types)
- #92389 (Regression test for borrowck ICE #92015)
- #92404 (Fix font size for [src] links in headers)
- #92443 (Rustdoc: resolve associated traits for non-generic primitive types)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Some cleanups around check_argument_types
Split out in ways from my rebase/continuation of #71827
Commits are mostly self-explanatory and these changes should be fairly straightforward
`thorin` is a Rust implementation of a DWARF packaging utility that
supports reading DWARF objects from archive files (i.e. rlibs) and
therefore is better suited for integration into rustc.
Signed-off-by: David Wood <david.wood@huawei.com>
In #79570, `-Z split-dwarf-kind={none,single,split}` was replaced by `-C
split-debuginfo={off,packed,unpacked}`. `-C split-debuginfo`'s packed
and unpacked aren't exact parallels to single and split, respectively.
On Unix, `-C split-debuginfo=packed` will put debuginfo into object
files and package debuginfo into a DWARF package file (`.dwp`) and
`-C split-debuginfo=unpacked` will put debuginfo into dwarf object files
and won't package it.
In the initial implementation of Split DWARF, split mode wrote sections
which did not require relocation into a DWARF object (`.dwo`) file which
was ignored by the linker and then packaged those DWARF objects into
DWARF packages (`.dwp`). In single mode, sections which did not require
relocation were written into object files but ignored by the linker and
were not packaged. However, both split and single modes could be
packaged or not, the primary difference in behaviour was where the
debuginfo sections that did not require link-time relocation were
written (in a DWARF object or the object file).
This commit re-introduces a `-Z split-dwarf-kind` flag, which can be
used to pick between split and single modes when `-C split-debuginfo` is
used to enable Split DWARF (either packed or unpacked).
Signed-off-by: David Wood <david.wood@huawei.com>
By avoiding formatting and allocations in the no-ident case, and by making the span mandatory if the ident exists.
Use the optimized `opt_item_ident` to cleanup `fn each_child_of_item`
Rollup of 7 pull requests
Successful merges:
- #92092 (Drop guards in slice sorting derive src pointers from &mut T, which is invalidated by interior mutation in comparison)
- #92388 (Fix a minor mistake in `String::try_reserve_exact` examples)
- #92442 (Add negative `impl` for `Ord`, `PartialOrd` on `LocalDefId`)
- #92483 (Stabilize `result_cloned` and `result_copied`)
- #92574 (Add RISC-V detection macro and more architecture instructions)
- #92575 (ast: Always keep a `NodeId` in `ast::Crate`)
- #92583 (⬆️ rust-analyzer)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Fixes#92266
In some `HashStable` impls, we use a cache to avoid re-computing
the same `Fingerprint` from the same structure (e.g. an `AdtDef`).
However, the `StableHashingContext` used can be configured to
perform hashing in different ways (e.g. skipping `Span`s). This
configuration information is not included in the cache key,
which will cause an incorrect `Fingerprint` to be used if
we hash the same structure with different `StableHashingContext`
settings.
To fix this, the configuration settings of `StableHashingContext`
are split out into a separate `HashingControls` struct. This
struct is used as part of the cache key, ensuring that our caches
always produce the correct result for the given settings.
With this in place, we now turn off `Span` hashing during the
entire process of computing the hash included in legacy symbols.
This current has no effect, but will matter when a future PR
starts hashing more `Span`s that we currently skip.
Extract init_env_logger to crate
I've been doing some work on rustc_ast_pretty using an out-of-tree main.rs and Cargo.toml with the following:
```toml
[dependencies]
rustc_ast = { path = "../rust/compiler/rustc_ast" }
rustc_ast_pretty = { path = "../rust/compiler/rustc_ast_pretty" }
rustc_span = { path = "../rust/compiler/rustc_span" }
```
Rustc_ast_pretty helpfully uses `tracing::debug!` but I found that in order to enable the debug output, my test crate must depend on rustc_driver which is an enormously bigger dependency than what I have been using so far, and slows down iteration time because an enormous dependency tree between rustc_ast and rustc_driver must now be rebuilt after every ast change.
I pulled out the tracing initialization to a new minimal rustc_log crate so that projects depending on the other rustc crates, like rustc_ast_pretty, can access the `debug!` messages in them without building all the rest of rustc.
Do not hash leading zero bytes of i64 numbers in Sip128 hasher
I was poking into the stable hasher, trying to improve its performance by compressing the number of hashed bytes. First I was experimenting with LEB128, but it was painful to implement because of the many assumptions that the SipHasher makes, so I tried something simpler - just ignoring leading zero bytes. For example, if an 8-byte integer can fit into a 4-byte integer, I will just hash the four bytes.
I wonder if this could produce any hashing ambiguity. Originally I thought so, but then I struggled to find any counter-example where this could cause different values to have the same hash. I'd be glad for any examples that could be broken by this (there are some ways of mitigating it if that would be the case). It could happen if you had e.g. 2x `u8` vs 1x `u16` hashed after one another in two different runs, but that can also happen now, without this "trick". And with collections, it should be fine, because the length is included in their hash.
I gathered some statistics for common values used in the `clap` benchmark. I observed that especially `i64` often had very low values, so I started with that type, let's see what perf does on CI.
There are some tradeoffs that we can try:
1) What types to use this optimization for? `u64`, `u32`, `u16`? Locally it was a slight loss for `u64`, I noticed that its values are often quite large.
2) What byte sizes to check? E.g. we can only distinguish between `u64`/`u32` or `u64`/`u8` instead of `u64`/`u32`/`u16`/`u8` to reduce branching (with `i64` it seemed to be better to go all the way down to `u8` locally though).
(The macro was introduced because I expect that I will be trying out this "trick" for different types).
Can you please schedule a perf. run? Thanks.
r? `@the8472`
Rollup of 7 pull requests
Successful merges:
- #91587 (core::ops::unsize: improve docs for DispatchFromDyn)
- #91907 (Allow `_` as the length of array types and repeat expressions)
- #92515 (RustWrapper: adapt for an LLVM API change)
- #92516 (Do not use deprecated -Zsymbol-mangling-version in bootstrap)
- #92530 (Move `contains` method of Option and Result lower in docs)
- #92546 (Update books)
- #92551 (rename StackPopClean::None to Root)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
rename StackPopClean::None to Root
With https://github.com/rust-lang/rust/pull/90102, `StackPopClean::None` is now only used for the "root" frame of the stack, so adjust its name accordingly and add an assertion.
r? `@oli-obk`
RustWrapper: adapt for an LLVM API change
No functional changes intended.
The LLVM commit ec501f15a8 removed the signed version of `createExpression`.
This adapts the Rust LLVM wrappers accordingly.
Suggest single quotes when char expected, str provided
If a type mismatch occurs where a char is expected and a string literal is provided, suggest changing the double quotes to single quotes.
We already provide this suggestion in the other direction ( ' -> " ).
Especially useful for new rust devs used to a language in which single/double quotes are interchangeable.
Fixes#92479.
Actually set IMAGE_SCN_LNK_REMOVE for .rmeta
The code intended to set the IMAGE_SCN_LNK_REMOVE flag for the
.rmeta section, however the value of this flag was set to zero.
Instead use the actual value provided by the object crate.
This dates back to the original introduction of this code in
PR #84449, so we were never setting this flag. As I'm not on
Windows, I'm not sure whether that means we were embedding .rmeta
into executables, or whether the section ended up getting stripped
for some other reason.
Remove special-cased stable hashing for HIR module
All other 'containers' (e.g. `impl` blocks) hashed their contents
in the normal, order-dependent way. However, `Mod` was hashing
its contents in a (sort-of) order-independent way. However, the
exact order is exposed to consumers through `Mod.item_ids`,
and through query results like `hir_module_items`. Therefore,
stable hashing needs to take the order of items into account,
to avoid fingerprint ICEs.
Unforuntately, I was unable to directly build a reproducer
for the ICE, due to the behavior of `Fingerprint::combine_commutative`.
This operation swaps the upper and lower `u64` when constructing the
result, which makes the function non-associative. Since we start
the hashing of module items by combining `Fingerprint::ZERO` with
the first item, it's difficult to actually build an example where
changing the order of module items leaves the final hash unchanged.
However, this appears to have been hit in practice in #92218
While we're not able to reproduce it, the fact that proc-macros
are involved (which can give an entire module the same span, preventing
any span-related invalidations) makes me confident that the root
cause of that issue is our method of hashing module items.
This PR removes all of the special handling for `Mod`, instead deriving
a `HashStable` implementation. This makes `Mod` consistent with other
'contains' like `Impl`, which hash their contents through the typical
derive of `HashStable`.
This PR removes all of the `#[stable_hasher(project(name))]`
attributes used in HIR structs. While these attributes are not known
to be causing any issues in practice, we need to hash these in
order for the incremental system to work correctly -
a query could be otherwise be incorrectly marked green
when a change occures in one of the `Span`s that it uses.
Rollup of 6 pull requests
Successful merges:
- #90102 (Remove `NullOp::Box`)
- #92011 (Use field span in `rustc_macros` when emitting decode call)
- #92402 (Suggest while let x = y when encountering while x = y)
- #92409 (Couple of libtest cleanups)
- #92418 (Fix spacing in pretty printed PatKind::Struct with no fields)
- #92444 (Consolidate Result's and Option's methods into fewer impl blocks)
Failed merges:
- #92483 (Stabilize `result_cloned` and `result_copied`)
r? `@ghost`
`@rustbot` modify labels: rollup
Use field span in `rustc_macros` when emitting decode call
This will cause backtraces to point to the location of
the field in the struct/enum, rather than the derive macro.
This makes it clear which field was being decoded when the
backtrace was captured (which is especially useful if
there are multiple fields with the same type).
Remove `NullOp::Box`
Follow up of #89030 and MCP rust-lang/compiler-team#460.
~1 month later nothing seems to be broken, apart from a small regression that #89332 (1aac85bb716c09304b313d69d30d74fe7e8e1a8e) shows could be regained by remvoing the diverging path, so it shall be safe to continue and remove `NullOp::Box` completely.
r? `@jonas-schievink`
`@rustbot` label T-compiler
Add `#[rustc_clean(loaded_from_disk)]` to assert loading of query result
Currently, you can use `#[rustc_clean]` to assert to that a particular
query (technically, a `DepNode`) is green or red. However, a green
`DepNode` does not mean that the query result was actually deserialized
from disk - we might have never re-run a query that needed the result.
Some incremental tests are written as regression tests for ICEs that
occured during query result decoding. Using
`#[rustc_clean(loaded_from_disk="typeck")]`, you can now assert
that the result of a particular query (e.g. `typeck`) was actually
loaded from disk, in addition to being green.
No functional changes intended.
The LLVM commit
ec501f15a8
removed the signed version of `createExpression`. This adapts the Rust
LLVM wrappers accordingly.
Move `PatKind::Lit` checking from ast_validation to ast lowering
Fixes#92074
This allows us to insert an `ExprKind::Err` when an invalid expression
is used in a literal pattern, preventing later stages of compilation
from seeing an unexpected literal pattern.
Rustdoc: use ThinVec for GenericArgs bindings
The bindings are almost always empty. This reduces the size of `PathSegment` and `GenericArgs` by about one fourth.
Stabilize -Z symbol-mangling-version=v0 as -C symbol-mangling-version=v0
This allows selecting `v0` symbol-mangling without an unstable option. Selecting `legacy` still requires -Z unstable-options.
This does not change the default symbol-mangling-version. See https://github.com/rust-lang/rust/pull/89917 for a pull request changing the default. Rationale, from #89917:
Rust's current mangling scheme depends on compiler internals; loses information about generic parameters (and other things) which makes for a worse experience when using external tools that need to interact with Rust symbol names; is inconsistent; and can contain . characters which aren't universally supported. Therefore, Rust has defined its own symbol mangling scheme which is defined in terms of the Rust language, not the compiler implementation; encodes information about generic parameters in a reversible way; has a consistent definition; and generates symbols that only use the characters A-Z, a-z, 0-9, and _.
Support for the new Rust symbol mangling scheme has been added to upstream tools that will need to interact with Rust symbols (e.g. debuggers).
This pull request allows enabling the new v0 symbol-mangling-version.
See #89917 for references to the implementation of v0, and for references to the tool changes to decode Rust symbols.
Support [x; n] expressions in concat_bytes!
Currently trying to use `concat_bytes!` with a repeating array value like `[42; 5]` results in an error:
```
error: expected a byte literal
--> src/main.rs:3:27
|
3 | let x = concat_bytes!([3; 4]);
| ^^^^^^
|
= note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
```
This makes it so repeating array syntax can be used the same way normal arrays can be. The RFC doesn't explicitly mention repeat expressions, but it seems reasonable to allow them as well, since normal arrays are allowed.
It is possible to make the compiler get stuck compiling forever with `concat_bytes!([3; 999999999])`, but I don't think that's much of an issue since you can do that already with `const X: [u8; 999999999] = [3; 999999999];`.
Contributes to #87555.
Remove effect of `#[no_link]` attribute on name resolution
Previously it hid all non-macro names from other crates.
This has no relation to linking and can change name resolution behavior in some cases (e.g. glob conflicts), in addition to just producing the "unresolved name" errors.
I can kind of understand the possible reasoning behind the current behavior - if you can use names from a `no_link` crates then you can use, for example, functions too, but whether it will actually work or produce link-time errors will depend on random factors like inliner behavior.
(^^^ This is not the actual reason why the current behavior exist, I've looked through git history and it's mostly accidental.)
I think this risk is ok for such an obscure attribute, and we don't need to specifically prevent use of non-macro items from such crates.
(I'm not actually sure why would anyone use `#[no_link]` on a crate, even if it's macro only, if you aware of any use cases, please share. IIRC, at some point it was used for crates implementing custom derives - the now removed legacy ones, not the current proc macros.)
Extracted from https://github.com/rust-lang/rust/pull/91795.
This allows selecting `v0` symbol-mangling without an unstable option.
Selecting `legacy` still requires -Z unstable-options.
Continue supporting -Z symbol-mangling-version for compatibility for
now, but show a deprecation warning for it.
Emit an error for `--cfg=)`
Fixes#73026
See also: #64467, #89468
The issue stems from a `FatalError` being silently raised in
`panictry_buffer`. Normally this is not a problem, because
`panictry_buffer` emits the causes of the error, but they are not
themselves fatal, so they get filtered out by the silent emitter.
To fix this, we use a parser entrypoint which doesn't use
`panictry_buffer`, and we handle the error ourselves.
Fixes#92074
This allows us to insert an `ExprKind::Err` when an invalid expression
is used in a literal pattern, preventing later stages of compilation
from seeing an unexpected literal pattern.
Mark drop calls in landing pads `cold` instead of `noinline`
Now that deferred inlining has been disabled in LLVM (#92110), this shouldn't cause catastrophic size blowup.
I confirmed that the test cases from https://github.com/rust-lang/rust/issues/41696#issuecomment-298696944 still compile quickly (<1s) after this change. ~Although note that I wasn't able to reproduce the original issue using a recent rustc/llvm with deferred inlining enabled, so those tests may no longer be representative. I was also unable to create a modified test case that reproduced the original issue.~ (edit: I reproduced it on CI by accident--the first commit timed out on the LLVM 12 builder, because I forgot to make it conditional on LLVM version)
r? `@nagisa`
cc `@arielb1` (this effectively reverts #42771 "mark calls in the unwind path as !noinline")
cc `@RalfJung` (fixes#46515)
edit: also fixes#87055
[rustc_builtin_macros] add indices to format_foreign::printf::Substitution::Escape
Fixes#92267.
The problem was that the escape string "%%" does not need to appear at the very beginning of the format string, but
the iterator implementation assumed that it did.
The solution follows the pattern used by `format_foregin:🐚:Subtitution::Escape`: 8ed935e92d/compiler/rustc_builtin_macros/src/format_foreign.rs (L629)
Fix whitespace in pretty printed PatKind::Range
Follow-up to #92238 fixing one of the FIXMEs.
```rust
macro_rules! repro {
($pat:pat) => {
stringify!($pat)
};
}
fn main() {
println!("{}", repro!(0..=1));
}
```
Before: `0 ..=1`
After: `0..=1`
The canonical spacing applied by rustfmt has no space after the lower expr. Rustc's parser diagnostics also do not put a space there:
df96fb166f/compiler/rustc_parse/src/parser/pat.rs (L754)
Fixes#73026
See also: #64467, #89468
The issue stems from a `FatalError` being silently raised in
`panictry_buffer`. Normally this is not a problem, because
`panictry_buffer` emits the causes of the error, but they are not
themselves fatal, so they get filtered out by the silent emitter.
To fix this, we use a parser entrypoint which doesn't use
`panictry_buffer`, and we handle the error ourselves.
Add Attribute::meta_kind
The `AttrItem::meta` function is being called on a lot of places, however almost always the caller is only interested in the `kind` of the result `MetaItem`. Before, the `path` had to be cloned in order to get the kind, now it does not have to be.
There is a larger related "problem". In a lot of places, something wants to know contents of attributes. This is accessed through `Attribute::meta_item_list`, which calls `AttrItem::meta` (now `AttrItem::meta_kind`), among other methods. When this function is called, the meta item list has to be recreated from scratch. Everytime something asks a simple question (like is this item/list of attributes `#[doc(hidden)]`?), the tokens of the attribute(s) are cloned, parsed and the results are allocated on the heap. That seems really unnecessary. What would be the best way to cache this? Turn `meta_item_list` into a query perhaps? Related PR: https://github.com/rust-lang/rust/pull/92227
r? rust-lang/rustdoc
Rollup of 7 pull requests
Successful merges:
- #90383 (Extend check for UnsafeCell in consts to cover unions)
- #91375 (config.rs: Add support for a per-target default_linker option.)
- #91480 (rustdoc: use smaller number of colors to distinguish items)
- #92338 (Add try_reserve and try_reserve_exact for OsString)
- #92405 (Add a couple needs-asm-support headers to tests)
- #92435 (Sync rustc_codegen_cranelift)
- #92440 (Fix mobile toggles position)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Sync rustc_codegen_cranelift
The main highlight this sync is enforcing rustfmt and lack of warnings on cg_clif's CI. I will open a separate PR to remove the cg_clif exceptions for them from this repo.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
Store liveness in interval sets for region inference
On the 100,000 line test case from https://github.com/rust-lang/rust/issues/90445, this reduces memory usage from 35 GB to 444 MB at peak (based on DHAT results, though with regular malloc), and yields a 9.4x speedup, with wall time going from 14.5 seconds to 1.5s. Performance results show that for the majority of real-world code this has little to no impact, but it's expected to generally scale better for auto-generated functions and other cases which stress this area of the compiler, as results on #90445 illustrate.
There may also be further room for improvement in future PRs making use of this data structures benefits over raw bitsets (which, at some level, are a less perfect fit for representing liveness, which is almost always composed of contiguous ranges, not point locations).
Fixes#90445.
Import `SourceFile`s from crate before decoding foreign `Span`
Fixes#92163Fixes#92014
When writing to the incremental cache, we encode all `Span`s
we encounter, regardless of whether or not their `SourceFile`
comes from the local crate, or from a foreign crate.
When we decode a `Span`, we use the `StableSourceFileId` we encoded
to locate the matching `SourceFile` in the current session. If this
id corresponds to a `SourceFile` from another crate, then we need to
have already imported that `SourceFile` into our current session.
This usually happens automatically during resolution / macro expansion,
when we try to resolve definitions from other crates. In certain cases,
however, we may try to load a `Span` from a transitive dependency
without having ever imported the `SourceFile`s from that crate, leading
to an ICE.
This PR fixes the issue by enconding the `SourceFile`'s `CrateNum`
when we encode a `Span`. During decoding, we call `imported_source_files()`
when we encounter a foreign `CrateNum`, which ensure that all
`SourceFile`s from that crate are imported into the current session.
Region inference contains several bitsets which are filled with large intervals
representing liveness. These can cause excessive memory usage, and are
relatively slow when growing to large sizes compared to the IntervalSet.
This is a compact, fast storage for variable-sized sets, typically consisting of
larger ranges. It is less efficient than a bitset if ranges are both small and
the domain size is small, but will still perform acceptably. With enormous
domain sizes and large ranges, the interval set performs much better, as it can
be much more densely packed in memory than the uncompressed bit set alternative.
ast: Avoid aborts on fatal errors thrown from mutable AST visitor
Set the node to some dummy value and rethrow the error instead.
When using the old aborting `visit_clobber` in `InvocationCollector::visit_crate` the next tests abort due to fatal errors:
```
ui\modules\path-invalid-form.rs
ui\modules\path-macro.rs
ui\modules\path-no-file-name.rs
ui\parser\issues\issue-5806.rs
ui\parser\mod_file_with_path_attr.rs
```
Follow up to https://github.com/rust-lang/rust/pull/91313.
Refactor variance diagnostics to work with more types
Instead of special-casing mutable pointers/references, we
now support general generic types (currently, we handle
`ty::Ref`, `ty::RawPtr`, and `ty::Adt`)
When a `ty::Adt` is involved, we show an additional note
explaining which of the type's generic parameters is
invariant (e.g. the `T` in `Cell<T>`). Currently, we don't
explain *why* a particular generic parameter ends up becoming
invariant. In the general case, this could require printing
a long 'backtrace' of types, so doing this would be
more suitable for a follow-up PR.
We still only handle the case where our variance switches
to `ty::Invariant`.
Allow loading LLVM plugins with both legacy and new pass manager
Opening a draft PR to get feedback and start discussion on this feature. There is already a codegen option `passes` which allow giving a list of LLVM pass names, however we currently can't use a LLVM pass plugin (as described here : https://llvm.org/docs/WritingAnLLVMPass.html), the only available passes are the LLVM built-in ones.
The proposed modification would be to add another codegen option `pass-plugins`, which can be set with a list of paths to shared library files. These libraries are loaded using the LLVM function `PassPlugin::Load`, which calls the expected symbol `lvmGetPassPluginInfo`, and register the pipeline parsing and optimization callbacks.
An example usage with a single plugin and 3 passes would look like this in the `.cargo/config`:
```toml
rustflags = [
"-C", "pass-plugins=/tmp/libLLVMPassPlugin",
"-C", "passes=pass1 pass2 pass3",
]
```
This would give the same functionality as the opt LLVM tool directly integrated in rust build system.
Additionally, we can also not specify the `passes` option, and use a plugin which inserts passes in the optimization pipeline, as one could do using clang.
Instead of special-casing mutable pointers/references, we
now support general generic types (currently, we handle
`ty::Ref`, `ty::RawPtr`, and `ty::Adt`)
When a `ty::Adt` is involved, we show an additional note
explaining which of the type's generic parameters is
invariant (e.g. the `T` in `Cell<T>`). Currently, we don't
explain *why* a particular generic parameter ends up becoming
invariant. In the general case, this could require printing
a long 'backtrace' of types, so doing this would be
more suitable for a follow-up PR.
We still only handle the case where our variance switches
to `ty::Invariant`.
Add codegen option for branch protection and pointer authentication on AArch64
The branch-protection codegen option enables the use of hint-space pointer
authentication code for AArch64 targets.
rustc_metadata: Encode list of all crate's traits into metadata
While working on https://github.com/rust-lang/rust/pull/88679 I noticed that rustdoc is casually doing something quite expensive, something that is used only for error reporting in rustc - collecting all traits from all crates in the dependency tree.
This PR trades some minor extra time spent by metadata encoder in rustc for major gains for rustdoc (and for rustc runs with errors, which execute the `all_traits` query for better diagnostics).