Implement `--extern-location`
This PR implements `--extern-location` as a followup to #72342 as part of the implementation of #57274. The goal of this PR is to allow rustc, in coordination with the build system, to present a useful diagnostic about how to remove an unnecessary dependency from a dependency specification file (eg Cargo.toml).
EDIT: Updated to current PR state.
The location is specified for each named crate - that is, for a given `--extern foo[=path]` there can also be `--extern-location foo=<location>`. It supports ~~three~~ two styles of location:
~~1. `--extern-location foo=file:<path>:<line>` - a file path and line specification
1. `--extern-location foo=span:<path>:<start>:<end>` - a span specified as a file and start and end byte offsets~~
1. `--extern-location foo=raw:<anything>` - a raw string which is included in the output
1. `--extern-location foo=json:<anything>` - an arbitrary Json structure which is emitted via Json diagnostics in a `tool_metadata` field.
~~1 & 2 are turned into an internal `Span`, so long as the path exists and is readable, and the location is meaningful (within the file, etc). This is used as the `Span` for a fix suggestion which is reported like other fix suggestions.~~
`raw` and `json` are for the case where the location isn't best expressed as a file and location within that file. For example, it could be a rule name and the name of a dependency within that rule. `rustc` makes no attempt to parse the raw string, and simply includes it in the output diagnostic text. `json` is only included in json diagnostics. `raw` is emitted as text and also as a json string in `tool_metadata`.
If no `--extern-location` option is specified then it will emit a default json structure consisting of `{"name": name, "path": path}` corresponding to the name and path in `--extern name=path`.
This is a prototype/RFC to make some of the earlier conversations more concrete. It doesn't stand on its own - it's only useful if implemented by Cargo and other build systems. There's also a ton of implementation details which I'd appreciate a second eye on as well.
~~**NOTE** The first commit in this PR is #72342 and should be ignored for the purposes of review. The first commit is a very simplistic implementation which is basically raw-only, presented as a MVP. The second implements the full thing, and subsequent commits are incremental fixes.~~
cc `@ehuss` `@est31` `@petrochenkov` `@estebank`
...so we can skip serializing `tool_metadata` if it hasn't been set.
This makes the output a bit cleaner, and avoiding having to update a
bunch of unrelated tests.
This allows a build system to indicate a location in its own dependency
specification files (eg Cargo's `Cargo.toml`) which can be reported
along side any unused crate dependency.
This supports several types of location:
- 'json' - provide some json-structured data, which is included in the json diagnostics
in a `tool_metadata` field
- 'raw' - emit the provided string into the output. This also appears as a json string in
`tool_metadata`.
If no `--extern-location` is explicitly provided then a default json entry of the form
`"tool_metadata":{"name":<cratename>,"path":<cratepath>}` is emitted.
Improve SIMD type element count validation
Resolvesrust-lang/stdsimd#53.
These changes are motivated by `stdsimd` moving in the direction of const generic vectors, e.g.:
```rust
#[repr(simd)]
struct SimdF32<const N: usize>([f32; N]);
```
This makes a few changes:
* Establishes a maximum SIMD lane count of 2^16 (65536). This value is arbitrary, but attempts to validate lane count before hitting potential errors in the backend. It's not clear what LLVM's maximum lane count is, but cranelift's appears to be much less than `usize::MAX`, at least.
* Expands some SIMD intrinsics to support arbitrary lane counts. This resolves the ICE in the linked issue.
* Attempts to catch invalid-sized vectors during typeck when possible.
Unresolved questions:
* Generic-length vectors can't be validated in typeck and are only validated after monomorphization while computing layout. This "works", but the errors simply bail out with no context beyond the name of the type. Should these errors instead return `LayoutError` or otherwise provide context in some way? As it stands, users of `stdsimd` could trivially produce monomorphization errors by making zero-length vectors.
cc `@bjorn3`
expand/resolve: Turn `#[derive]` into a regular macro attribute
This PR turns `#[derive]` into a regular attribute macro declared in libcore and defined in `rustc_builtin_macros`, like it was previously done with other "active" attributes in https://github.com/rust-lang/rust/pull/62086, https://github.com/rust-lang/rust/pull/62735 and other PRs.
This PR is also a continuation of #65252, #69870 and other PRs linked from them, which layed the ground for converting `#[derive]` specifically.
`#[derive]` still asks `rustc_resolve` to resolve paths inside `derive(...)`, and `rustc_expand` gets those resolution results through some backdoor (which I'll try to address later), but otherwise `#[derive]` is treated as any other macro attributes, which simplifies the resolution-expansion infra pretty significantly.
The change has several observable effects on language and library.
Some of the language changes are **feature-gated** by [`feature(macro_attributes_in_derive_output)`](https://github.com/rust-lang/rust/issues/81119).
#### Library
- `derive` is now available through standard library as `{core,std}::prelude::v1::derive`.
#### Language
- `derive` now goes through name resolution, so it can now be renamed - `use derive as my_derive; #[my_derive(Debug)] struct S;`.
- `derive` now goes through name resolution, so this resolution can fail in corner cases. Crater found one such regression, where import `use foo as derive` goes into a cycle with `#[derive(Something)]`.
- **[feature-gated]** `#[derive]` is now expanded as any other attributes in left-to-right order. This allows to remove the restriction on other macro attributes following `#[derive]` (https://github.com/rust-lang/reference/issues/566). The following macro attributes become a part of the derive's input (this is not a change, non-macro attributes following `#[derive]` were treated in the same way previously).
- `#[derive]` is now expanded as any other attributes in left-to-right order. This means two derive attributes `#[derive(Foo)] #[derive(Bar)]` are now expanded separately rather than together. It doesn't generally make difference, except for esoteric cases. For example `#[derive(Foo)]` can now produce an import bringing `Bar` into scope, but previously both `Foo` and `Bar` were required to be resolved before expanding any of them.
- **[feature-gated]** `#[derive()]` (with empty list in parentheses) actually becomes useful. For historical reasons `#[derive]` *fully configures* its input, eagerly evaluating `cfg` everywhere in its target, for example on fields.
Expansion infra doesn't do that for other attributes, but now when macro attributes attributes are allowed to be written after `#[derive]`, it means that derive can *fully configure* items for them.
```rust
#[derive()]
#[my_attr]
struct S {
#[cfg(FALSE)] // this field in removed by `#[derive()]` and not observed by `#[my_attr]`
field: u8
}
```
- `#[derive]` on some non-item targets is now prohibited. This was accidentally allowed as noop in the past, but was warned about since early 2018 (#50092), despite that crater found a few such cases in unmaintained crates.
- Derive helper attributes used before their introduction are now reported with a deprecation lint. This change is long overdue (since macro modularization, https://github.com/rust-lang/rust/issues/52226#issuecomment-422605033), but it was hard to do without fixing expansion order for derives. The deprecation is tracked by #79202.
```rust
#[trait_helper] // warning: derive helper attribute is used before it is introduced
#[derive(Trait)]
struct S {}
```
Crater analysis: https://github.com/rust-lang/rust/pull/79078#issuecomment-731436821
Identify unreachable subpatterns more reliably
In https://github.com/rust-lang/rust/pull/80104 I used `Span`s to identify unreachable sub-patterns in the presence of or-patterns during exhaustiveness checking. In https://github.com/rust-lang/rust/issues/80501 it was revealed that `Span`s are complicated and that this was not a good idea.
Instead, this PR identifies subpatterns logically: as a path in the tree of subpatterns of a given pattern. I made a struct that captures a set of such subpatterns. This is a bit complex, but thankfully self-contained; the rest of the code does not need to know anything about it.
Fixes https://github.com/rust-lang/rust/issues/80501. I think I managed to keep the perf neutral.
r? `@varkor`
Apply workaround from #72003 for #56935 to allow for cross-compilation of `rustc_index` crate
This patch applies the same workaround as #72003 to the `rustc_index` crate. This allows recent versions of rustfmt to compile to wasm again.
Related: #72017.
typeck: Emit structured suggestions for tuple struct syntax
And tuple variant syntax, but that didn't fit in the subject :)
Now the fact that these are suggestions is exposed both to the layout
engine and to IDEs and rustfix for automatic application.
Refactor `PrimitiveTypeTable` for Clippy
I removed `PrimitiveTypeTable` and added `PrimTy::ALL` and `PrimTy::from_name` in its place. This allows Clippy to use `PrimTy::from_name` for the `builtin_type_shadow` lint, and a `const` list of primitive types is deleted from Clippy code (the goal). All changes should be a little faster, if anything.
tidy: Run tidy style against markdown files.
This adds tidy checks for markdown files. I think it is useful to have some style enforcement (for the same reasons the style is enforced on other files). I think it is worthwhile to avoid `ignore` on rust examples since having broken code in documentation is frustrating. Avoiding trailing whitespace is good because it has semantic meaning in markdown, which I think should be avoided.
Rollup of 7 pull requests
Successful merges:
- #80011 (Stabilize `peekable_next_if`)
- #81580 (Document how `MaybeUninit<Struct>` can be initialized.)
- #81610 (BTreeMap: make Ord bound explicit, compile-test its absence)
- #81664 (Avoid a hir access inside get_static)
- #81675 (Make rustdoc respect `--error-format short` in doctests)
- #81753 (Never MIR inline functions with a different instruction set)
- #81795 (Small refactor with Iterator::reduce)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Avoid a hir access inside get_static
Together with #81056 this ensures that the codegen unit DepNode doesn't have a direct dependency on any part of the hir.
Fix rustc sysroot in systems using CAS
Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
Encode MIR metadata by iterating on DefId instead of traversing the HIR tree
Split out of https://github.com/rust-lang/rust/pull/80347.
This part only traverses `mir_keys` and encodes MIR according to the def kind.
r? `@oli-obk`
Revert 78373 ("dont leak return value after panic in drop")
Short term resolution for issue #80949.
Reopen#47949 after this lands.
(We plan to fine-tune PR #78373 to not run into this problem.)
Rollup of 15 pull requests
Successful merges:
- #79554 (Generic associated types in trait paths)
- #80726 (relax adt unsizing requirements)
- #81307 (Handle `Span`s for byte and raw strings and add more detail )
- #81318 (rustdoc-json: Fix has_body)
- #81456 (Make remote-test-server easier to use with new targets)
- #81497 (rustdoc: Move `display_fn` struct inside `display_fn`)
- #81500 (Remove struct_type from union output)
- #81542 (Expose correct symlink API on WASI)
- #81676 (Add more information to the error code for 'crate not found')
- #81682 (Add additional bitset benchmarks)
- #81730 (Make `Allocator` object-safe)
- #81763 (Cleanup rustdoc pass descriptions a bit)
- #81767 (Update LayoutError/LayoutErr stability attributes)
- #81771 (Indicate change in RSS from start to end of pass in time-passes output)
- #81781 (Fix `install-awscli.sh` error in CI)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Indicate change in RSS from start to end of pass in time-passes output
Previously, this was omitted because it could be misleading, but the
functionality seems too useful not to include.
r? ``@oli-obk``
Add additional bitset benchmarks
Add additional benchmarks for operations in bitset, I realize that it was a bit lacking when I intended to optimize it earlier, so I was hoping to put some in so I can verify my work later.
relax adt unsizing requirements
Changes unsizing of structs in case the last struct field shares generic params with other adt fields which do not change.
This change is currently insta stable and changes the language, so it at least requires a lang fcp. I feel like the current state is fairly unintuitive.
An example for what's now allowed would be https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6dd331d23f5c9ffc8c978175aae2e967
```rust
struct A<T, U: ?Sized>(T, B<T, U>); // previously ERR
// struct A<T, U: ?Sized>(T, B<[u32; 1], U>); // ok
struct B<T, U: ?Sized>(T, U);
fn main() {
let x = A([0; 1], B([0; 1], [0; 1]));
let y: &A<[u32; 1], [u32]> = &x;
assert_eq!(y.1.1.len(), 1);
}
```
rustc_codegen_ssa: tune codegen scheduling to reduce memory usage
For better throughput during parallel processing by LLVM, we used to sort
CGUs largest to smallest. This would lead to better thread utilization
by, for example, preventing a large CGU from being processed last and
having only one LLVM thread working while the rest remained idle.
However, this strategy would lead to high memory usage, as it meant the
LLVM-IR for all of the largest CGUs would be resident in memory at once.
Instead, we can compromise by ordering CGUs such that the largest and
smallest are first, second largest and smallest are next, etc. If there
are large size variations, this can reduce memory usage significantly.