Move capture lowering from THIR to MIR
This allows us to:
- Handle precise Places captured by a closure directly in MIR. Handling
captures in MIR is easier since we can rely on/ tweak PlaceBuilder to
generate `mir::Place`s that resemble how we store captures (`hir::Place`).
- Handle `let _ = x` case when feature `capture_disjoint_fields`
is enabled directly in MIR. This is required to be done in MIR since
patterns are desugared in MIR.
Closes: rust-lang/project-rfc-2229#25
r? ```@nikomatsakis```
add optimization fuel checks to some mir passes
Fixes#77402
Inserts a bunch of calls to `consider_optimizing`. Note that `consider_optimizing` is the method that actually decrements the fuel count, so the point at which it's called is when the optimization takes place, from a fuel perspective. This means that where we call it has some thought behind it:
1. We probably don't want to decrement the fuel count before other simple checks, otherwise we count an optimization as being performed even if nothing was mutated (ie. it returned early).
2. In cases like `InstCombine`, where we gather optimizations in a pass and then mutate values, we probably would rather skip the gathering pass for performance reasons rather than skip the mutations afterwards.
Improve the diagnostic for when an `fn` contains qualifiers inside an `extern` block.
This mitigates #78941. As suggested by ```@estebank,``` `span_suggestion` was replaced with `span_suggestion_verbose` for this specific diagnostic.
Make bad "rust-call" arguments no longer ICE
The simplest of bad rust-call definitions will no longer cause an ICE. There is a FIXME added for future work, as I wanted to get this easy fix in before trying to either add a hack or mess with the whole obligation system
fixes#22565
Fix setting inline hint based on `InstanceDef::requires_inline`
For instances where `InstanceDef::requires_inline` is true, an attempt
is made to set an inline hint though a call to the `inline` function.
The attempt is ineffective, since all attributes will be usually removed
by the second call.
Fix the issue by applying the attributes only once, with user provided
attributes having a priority when provided.
Closes#79108.
Handle empty matches cleanly in exhaustiveness checking
This removes the special-casing of empty matches that was done in `check_match`. This fixes most of https://github.com/rust-lang/rust/issues/55123.
Somewhat unrelatedly, I also made `_match.rs` more self-contained, because I think it's cleaner.
r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
type is too big -> values of the type are too big
strictly speaking, `[u8; usize::MAX]` or even `[[[u128; usize::MAX]; usize::MAX]; usize::MAX]` are absolutely fine types as long as you don't try to deal with any values of it.
This error message seems to cause some confusion imo, for example in https://github.com/rust-lang/rust/pull/79135#issuecomment-729361380 so I would prefer us to be more precise here.
See the added test case which uses one of these types without causing an error.
r? ``@oli-obk``
Updated the list of white-listed target features for x86
This PR both adds in-source documentation on what to look out for when adding a new (X86) feature set and [adds all that are detectable at run-time in Rust stable as of 1.27.0](https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/src/detect/arch/x86.rs).
This should only enable the use of the corresponding LLVM intrinsics.
Actual intrinsics need to be added separately in rust-lang/stdarch.
It also re-orders the run-time-detect test statements to be more consistent
with the actual list of intrinsics whitelisted and removes underscores not present
in the actual names (which might be mistaken as being part of the name)
The reference for LLVM's feature names used is [this file](https://github.com/llvm/llvm-project/blob/master/llvm/include/llvm/Support/X86TargetParser.def).
This PR was motivated as the compiler end's part for allowing #67329 to be adressed over on rust-lang/stdarch
ExprKind::SelfRef was used to express accessing `self` in
the desugared Closure/Generator struct when lowering captures in THIR.
Since we handle captures in MIR now, we don't need `ExprKind::Self`.
This allows us to:
- Handle precise Places captured by a closure directly in MIR. Handling
captures in MIR is easier since we can rely on/ tweak PlaceBuilder to
generate `mir::Place`s that resemble how we store captures (`hir::Place`).
- Allows us to handle `let _ = x` case when feature `capture_disjoint_fields`
is enabled directly in MIR. This is required to be done in MIR since
patterns are desugared in MIR.
[self-profiling] Include the estimated size of each cgu in the profile
This is helpful when looking for CGUs where the size estimate isn't a
good indicator of compilation time.
I verified that moving the profiling timer call doesn't affect the
results.
Results:
<img width="297" alt="Screen Shot 2020-11-03 at 7 25 04 AM" src="https://user-images.githubusercontent.com/831192/97985503-5901d100-1da6-11eb-9f10-f3e399702952.png">
`measureme` doesn't have support for custom arg names yet so `arg0` is the CGU name and `arg1` is the estimated size.
Rustdoc test compiler output color
Fixes#72915
We just need to be sure it doesn't break rustdoc doctests' compilation checks. Maybe some other unforeseen consequences too?
r? `@ehuss`
cc `@rust-lang/rustdoc`
Introduce `TypeVisitor::BreakTy`
Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`
~~Blocked on FCP in rust-lang/compiler-team#383.~~
RFC-2229: Implement Precise Capture Analysis
### This PR introduces
- Feature gate for RFC-2229 (incomplete) `capture_disjoint_field`
- Rustc Attribute to print out the capture analysis `rustc_capture_analysis`
- Precise capture analysis
### Description of the analysis
1. If the feature gate is not set then all variables that are not local to the closure will be added to the list of captures. (This is for backcompat)
2. The rest of the analysis is based entirely on how the captured `Place`s are used within the closure. Precise information (i.e. projections) about the `Place` is maintained throughout.
3. To reduce the amount of information we need to keep track of, we do a minimization step. In this step, we determine a list such that no Place within this list represents an ancestor path to another entry in the list. Check rust-lang/project-rfc-2229#9 for more detailed examples.
4. To keep the compiler functional as before we implement a Bridge between the results of this new analysis to existing data structures used for closure captures. Note the new capture analysis results are only part of MaybeTypeckTables that is the information is only available during typeck-ing.
### Known issues
- Statements like `let _ = x` will make the compiler ICE when used within a closure with the feature enabled. More generally speaking the issue is caused by `let` statements that create no bindings and are init'ed using a Place expression.
### Testing
We removed the code that would handle the case where the feature gate is not set, to enable the feature as default and did a bors try and perf run. More information here: #78762
### Thanks
This has been slowly in the works for a while now.
I want to call out `@Azhng` `@ChrisPardy` `@null-sleep` `@jenniferwills` `@logmosier` `@roxelo` for working on this and the previous PRs that led up to this, `@nikomatsakis` for guiding us.
Closesrust-lang/project-rfc-2229#7Closesrust-lang/project-rfc-2229#9Closesrust-lang/project-rfc-2229#6Closesrust-lang/project-rfc-2229#19
r? `@nikomatsakis`
For instances where `InstanceDef::requires_inline` is true, an attempt
is made to set an inline hint though a call to the `inline` function.
The attempt is ineffective, since all attributes will be usually removed
by the second call.
Fix the issue by applying the attributes only once, with user provided
attributes having a priority when provided.
Update E0744 about control flow in `const` contexts to accurately describe when the error is triggered and why
This PR fixes#79083. `const fn` currently supports `if`, `match`, `loop`, and `while` in terms of control flow. The error relating to control flow in `const` contexts currently states that those control flow constructs are not allowed in `const` contexts. That is no longer true, as RFC 2342 and 2344 were [stabilized](https://github.com/rust-lang/rust/pull/72437). `for` loops, however, as well as `?` and `.await` are still not allowed, so I changed the error message to be more descriptive of the error as it is not just control flow that could trigger this error. I also added links to tracking issues that mark things that are blocking the usage of these expressions.
improve type const mismatch errors
Doesn't completely remove `check_generic_arg_count` as that would have required some more complex changes but
instead checks type and const params in only one step. Also moved the help added by `@JulianKnodt` in #75611 to `generic_arg_mismatch_err`.
r? `@varkor` cc `@petrochenkov`
Simplify output capturing
This is a sequence of incremental improvements to the unstable/internal `set_panic` and `set_print` mechanism used by the `test` crate:
1. Remove the `LocalOutput` trait and use `Arc<Mutex<dyn Write>>` instead of `Box<dyn LocalOutput>`. In practice, all implementations of `LocalOutput` were just `Arc<Mutex<..>>`. This simplifies some logic and removes all custom `Sink` implementations such as `library/test/src/helpers/sink.rs`. Also removes a layer of indirection, as the outermost `Box` is now gone. It also means that locking now happens per `write_fmt`, not per individual `write` within. (So `"{} {}\n"` now results in one `lock()`, not four or more.)
2. Since in all cases the `dyn Write`s were just `Vec<u8>`s, replace the type with `Arc<Mutex<Vec<u8>>>`. This simplifies things more, as error handling and flushing can be removed now. This also removes the hack needed in the default panic handler to make this work with `::realstd`, as (unlike `Write`) `Vec<u8>` is from `alloc`, not `std`.
3. Replace the `RefCell`s by regular `Cell`s. The `RefCell`s were mostly used as `mem::replace(&mut *cell.borrow_mut(), something)`, which is just `Cell::replace`. This removes an unecessary bookkeeping and makes the code a bit easier to read.
4. Merge `set_panic` and `set_print` into a single `set_output_capture`. Neither the test crate nor rustc (the only users of this feature) have a use for using these separately. Merging them simplifies things even more. This uses a new function name and feature name, to make it clearer this is internal and not supposed to be used by other crates.
Might be easier to review per commit.
This is a squash of these commits:
- Update E0744 about control flow in `const` contexts to reflect current status of `const fn`.
- E0744 isn't just about `for` loops or control flow
- Fix formatting on E0744 cause my editor decided to not copy it well
- Improve wording
- Fix a markdown formatting error
- Fix E0744's description as I interpreted some code wrong
- Fix a minor wording issue again
- Add a few more links to blocking issues
- Improve links to tracking issues
Clippy uses `ExprUseVisitor` and atleast in some cases it runs
after writeback.
We currently don't writeback the min_capture results of closure
capture analysis since no place within the compiler itself uses it.
In the short term to fix clippy we add a fallback when walking captures
of a closure to check if closure_capture analysis has any entries in it.
Writeback for closure_min_captures will be implemented in
rust-lang/project-rfc-2229#18
Move likely/unlikely argument outside of invisible unsafe block
The previous `likely!`/`unlikely!` macros were unsound because it permits the caller's expr to contain arbitrary unsafe code.
```rust
pub fn huh() -> bool {
likely!(std::ptr::read(&() as *const () as *const bool))
}
```
**Before:** compiles cleanly.
**After:**
```console
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
70 | likely!(std::ptr::read(&() as *const () as *const bool))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
```
astconv: extract closures into a separate trait
Am currently looking into completely removing `check_generic_arg_count` and `create_substs_for_generic_args` was somewhat difficult to understand for me so I moved these closures into a trait.
This should not have changed the behavior of any of these methods
Make `_` an expression, to discard values in destructuring assignments
This is the third and final step towards implementing destructuring assignment (RFC: rust-lang/rfcs#2909, tracking issue: #71126). This PR is the third and final part of #71156, which was split up to allow for easier review.
With this PR, an underscore `_` is parsed as an expression but is allowed *only* on the left-hand side of a destructuring assignment. There it simply discards a value, similarly to the wildcard `_` in patterns. For instance,
```rust
(a, _) = (1, 2)
```
will simply assign 1 to `a` and discard the 2. Note that for consistency,
```
_ = foo
```
is also allowed and equivalent to just `foo`.
Thanks to ````@varkor```` who helped with the implementation, particularly around pre-expansion gating.
r? ````@petrochenkov````
cleanup: Remove `ParseSess::injected_crate_name`
Its only remaining use is in pretty-printing where the necessary information can be easily re-computed.
Allow making `RUSTC_BOOTSTRAP` conditional on the crate name
Motivation: This came up in the [Zulip stream](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Require.20users.20to.20confirm.20they.20know.20RUSTC_.E2.80.A6.20compiler-team.23350/near/208403962) for https://github.com/rust-lang/compiler-team/issues/350.
See also https://github.com/rust-lang/cargo/pull/6608#issuecomment-458546258; this implements https://github.com/rust-lang/cargo/issues/6627.
The goal is for this to eventually allow prohibiting setting `RUSTC_BOOTSTRAP` in build.rs (https://github.com/rust-lang/cargo/issues/7088).
## User-facing changes
- `RUSTC_BOOTSTRAP=1` still works; there is no current plan to remove this.
- Things like `RUSTC_BOOTSTRAP=0` no longer activate nightly features. In practice this shouldn't be a big deal, since `RUSTC_BOOTSTRAP` is the opposite of stable and everyone uses `RUSTC_BOOTSTRAP=1` anyway.
- `RUSTC_BOOTSTRAP=x` will enable nightly features only for crate `x`.
- `RUSTC_BOOTSTRAP=x,y` will enable nightly features only for crates `x` and `y`.
## Implementation changes
The main change is that `UnstableOptions::from_environment` now requires
an (optional) crate name. If the crate name is unknown (`None`), then the new feature is not available and you still have to use `RUSTC_BOOTSTRAP=1`. In practice this means the feature is only available for `--crate-name`, not for `#![crate_name]`; I'm interested in supporting the second but I'm not sure how.
Other major changes:
- Added `Session::is_nightly_build()`, which uses the `crate_name` of
the session
- Added `nightly_options::match_is_nightly_build`, a convenience method
for looking up `--crate-name` from CLI arguments.
`Session::is_nightly_build()`should be preferred where possible, since
it will take into account `#![crate_name]` (I think).
- Added `unstable_features` to `rustdoc::RenderOptions`
I'm not sure whether this counts as T-compiler or T-lang; _technically_ RUSTC_BOOTSTRAP is an implementation detail, but it's been used so much it seems like this counts as a language change too.
r? `@joshtriplett`
cc `@Mark-Simulacrum` `@hsivonen`
Clean up outdated `use_once_payload` pretty printer comment
While reading some parts of the pretty printer code, I noticed this old comment
which seemed out of place. The `use_once_payload` this outdated comment mentions
was removed in 2017 in 40f03a1e0d, so this
completes the work by removing the comment.
Fix rustc_ast_pretty print_qpath resulting in invalid macro input
related https://github.com/rust-lang/rust/issues/76874 (third case)
### Issue:
The input for a procedural macro is incorrect, for the rust code:
```rust
mod m {
pub trait Tr {
type Ts: super::Tu;
}
}
trait Tu {
fn dummy() { }
}
#[may_proc_macro]
fn foo() {
<T as m::Tr>::Ts::dummy();
}
```
the macro will get the input:
```rust
fn foo() {
<T as m::Tr>::dummy();
}
```
Thus `Ts` has disappeared.
### Fix:
This is due to invalid pretty print of qpath. This PR fix it.
Normalize function type during validation
During inlining, the callee body is normalized and has types revealed,
but some of locals corresponding to the arguments might come from the
caller body which is not. As a result the caller body does not pass
validation without additional normalization.
Closes#78442.
Do not call `unwrap` with `signatures` option enabled
Fixes#75229
Didn't add a test since I couldn't set `RUST_SAVE_ANALYSIS_CONFIG` even with `rustc-env`.
Lower intrinsics calls: forget, size_of, unreachable, wrapping_*
This allows constant propagation to evaluate `size_of` and `wrapping_*`,
and unreachable propagation to propagate a call to `unreachable`.
The lowering is performed as a MIR optimization, rather than during MIR
building to preserve the special status of intrinsics with respect to
unsafety checks and promotion.
Currently enabled by default to determine the performance impact (no
significant impact expected). In practice only useful when combined with
inlining since intrinsics are rarely used directly (with exception of
`unreachable` and `discriminant_value` used by built-in derive macros).
Closes#32716.
The previous `likely!`/`unlikely!` macros were unsound because it
permits the caller's expr to contain arbitrary unsafe code.
pub fn huh() -> bool {
likely!(std::ptr::read(&() as *const () as *const bool))
}
Before: compiles cleanly.
After:
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
70 | likely!(std::ptr::read(&() as *const () as *const bool))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
Previously, cap-lints was ignored when checking the previous forbid level, which
meant that it was a hard error to do so. This is different from the normal
behavior of lints, which are silenced by cap-lints; if the forbid would not take
effect regardless, there is not much point in complaining about the fact that we
are reducing its level.
It might be considered a bug that even `--cap-lints deny` would suffice to
silence the error on overriding forbid, depending on if one cares about failing
the build or precisely forbid being set. But setting cap-lints to deny is quite
odd and not really done in practice, so we don't try to handle it specially.
This also unifies the code paths for nested and same-level scopes. However, the
special case for CLI lint flags is left in place (introduced by #70918) to fix
the regression noted in #70819. That means that CLI flags do not lint on forbid
being overridden by a non-forbid level. It is unclear whether this is a bug or a
desirable feature, but it is certainly inconsistent. CLI flags are a
sufficiently different "type" of place though that this is deemed out of scope
for this commit.
add error_occured field to ConstQualifs,
fix#76064
I wasn't sure what `in_return_place` actually did and not sure why it returns `ConstQualifs` while it's sibling functions return `bool`. So I tried to make as minimal changes to the structure as possible. Please point out whether I have to refactor it or not.
r? `@oli-obk`
cc `@RalfJung`
rustc_target: Mark UEFI targets as `is_like_windows`/`is_like_msvc`
And document what `is_like_windows` and `is_like_msvc` actually mean in more detail.
Addresses FIXMEs left from https://github.com/rust-lang/rust/pull/71030.
r? `@nagisa`
rustc_parse: Remove optimization for 0-length streams in `collect_tokens`
The optimization conflates empty token streams with unknown token stream, which is at least suspicious, and doesn't affect performance because 0-length token streams are very rare.
r? `@Aaron1011`
This allows constant propagation to evaluate `size_of` and `wrapping_*`,
and unreachable propagation to propagate a call to `unreachable`.
The lowering is performed as a MIR optimization, rather than during MIR
building to preserve the special status of intrinsics with respect to
unsafety checks and promotion.
Add type to `ConstKind::Placeholder`
I simply threaded `<'tcx>` through everything that required it. I'm not sure whether this is the correct thing to do, but it seems to work.
r? `@nikomatsakis`
While reading some parts of the pretty printer code, I noticed this old comment
which seemed out of place. The `use_once_payload` this outdated comment mentions
was removed in 2017 in 40f03a1e0d, so this
completes the work by removing the comment.
During inlining, the callee body is normalized and has types revealed,
but some of locals corresponding to the arguments might come from the
caller body which is not. As a result the caller body does not pass
validation without additional normalization.
The optimization conflates empty token streams with unknown token stream, which is at least suspicious, and doesn't affect performance because 0-length token streams are very rare.
The inliner looks if a sanitizer is enabled before considering
`no_sanitize` attribute as possible source of incompatibility.
The MIR inlining could happen in a crate with sanitizer disabled, but
code generation in a crate with sanitizer enabled, thus the attribute
would be incorrectly ignored.
To avoid the issue never inline functions with different `no_sanitize`
attributes.
Add asm register information for SPIR-V
As discussed in [zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Defining.20asm!.20for.20new.20architecture), we at [rust-gpu](https://github.com/EmbarkStudios/rust-gpu) would like to support `asm!` for our SPIR-V backend. However, we cannot do so purely without frontend support: [this match](d4ea0b3e46/compiler/rustc_target/src/asm/mod.rs (L185)) fails and so `asm!` is not supported ([error reported here](d4ea0b3e46/compiler/rustc_ast_lowering/src/expr.rs (L1095))). To resolve this, we need to stub out register information for SPIR-V to support getting the `asm!` content all the way to [`AsmBuilderMethods::codegen_inline_asm`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/traits/trait.AsmBuilderMethods.html#tymethod.codegen_inline_asm), at which point the rust-gpu backend can do all the parsing and codegen that is needed.
This is a pretty weird PR - adding support for a backend that isn't in-tree feels pretty gross to me, but I don't see an easy way around this. ``@Amanieu`` said I should submit it anyway, so, here we are! Let me know if this needs to go through a more formal process (MCP?) and what I should do to help this along.
I based this off the [wasm asm PR](https://github.com/rust-lang/rust/pull/78684), which unfortunately this PR conflicts with that one quite a bit, sorry for any merge conflict pain :(
---
Some open questions:
- What do we call the register class? Some context, SPIR-V is an SSA-based IR, there are "instructions" that create IDs (referred to as `<id>` in the spec), which can be referenced by other instructions. So, `reg` isn't exactly accurate, they're SSA IDs, not re-assignable registers.
- What happens when a SPIR-V register gets to the LLVM backend? Right now it's a `bug!`, but should that be a `sess.fatal()`? I'm not sure if it's even possible to reach that point, maybe there's a check that prevents the `spirv` target from even reaching that codepath.
Implement destructuring assignment for structs and slices
This is the second step towards implementing destructuring assignment (RFC: rust-lang/rfcs#2909, tracking issue: #71126). This PR is the second part of #71156, which was split up to allow for easier review.
Note that the first PR (#78748) is not merged yet, so it is included as the first commit in this one. I thought this would allow the review to start earlier because I have some time this weekend to respond to reviews. If ``@petrochenkov`` prefers to wait until the first PR is merged, I totally understand, of course.
This PR implements destructuring assignment for (tuple) structs and slices. In order to do this, the following *parser change* was necessary: struct expressions are not required to have a base expression, i.e. `Struct { a: 1, .. }` becomes legal (in order to act like a struct pattern).
Unfortunately, this PR slightly regresses the diagnostics implemented in #77283. However, it is only a missing help message in `src/test/ui/issues/issue-77218.rs`. Other instances of this diagnostic are not affected. Since I don't exactly understand how this help message works and how to fix it yet, I was hoping it's OK to regress this temporarily and fix it in a follow-up PR.
Thanks to ``@varkor`` who helped with the implementation, particularly around the struct rest changes.
r? ``@petrochenkov``
Reusing bindings causes errors later in lowering:
```
error[E0596]: cannot borrow `vec` as mutable, as it is not declared as mutable
--> /checkout/src/test/ui/async-await/argument-patterns.rs:12:20
|
LL | async fn b(n: u32, ref mut vec: A) {
| ^^^^^^^^^^^
| |
| cannot borrow as mutable
| help: consider changing this to be mutable: `mut vec`
```
incr-comp: hash and serialize span end line/column
Hash both the length and the end location (line/column) of a span. If we
hash only the length, for example, then two otherwise equal spans with
different end locations will have the same hash. This can cause a
problem during incremental compilation wherein a previous result for a
query that depends on the end location of a span will be incorrectly
reused when the end location of the span it depends on has changed. A
similar analysis applies if some query depends specifically on the
length of the span, but we only hash the end location. So hash both.
Fix#46744, fix#59954, fix#63161, fix#73640, fix#73967, fix#74890, fix#75900
---
See #74890 for a more in-depth analysis.
I haven't thought about what other problems this root cause could be responsible for. Please let me know if anything springs to mind. I believe the issue has existed since the inception of incremental compilation.
This commit grepped for LLVM_VERSION_GE, LLVM_VERSION_LT, get_major_version and
min-llvm-version and statically evaluated every expression possible
(and sensible) assuming that the LLVM version is >=9 now
Do not collect tokens for doc comments
Doc comment is a single token and AST has all the information to re-create it precisely.
Doc comments are also responsible for majority of calls to `collect_tokens` (with `num_calls == 1` and `num_calls == 0`, cc https://github.com/rust-lang/rust/pull/78736).
(I also moved token collection into `fn parse_attribute` to deduplicate code a bit.)
r? `@Aaron1011`
rustc_target: Move target env "gnu" from `linux_base` to `linux_gnu_base`
Follow up to https://github.com/rust-lang/rust/pull/77729.
Changes the target spec hierarchy for Linux from
```
linux_base
├── linux_musl_base
└── linux_uclibc_base
```
where `linux_base` is really `linux_gnu_base` and the inheriting targets replace target env "gnu" with "musl"/"uclibc" to
```
linux_base
├── linux_gnu_base
├── linux_musl_base
└── linux_uclibc_base
```
which is slightly less confusing (I think).
Support inlining diverging function calls
The existing heuristic does penalize diverging calls to some degree, but since
it never inlined them previously it might need some further modifications.
Additionally introduce storage markers for all temporaries created by
the inliner. The temporary introduced for destination rebrorrow, didn't
use them previously.
Add flags customizing behaviour of MIR inlining
* `-Zinline-mir-threshold` to change the default threshold.
* `-Zinline-mir-hint-threshold` to change the threshold used by
functions with inline hint.
Having those as configurable flags makes it possible to experiment with with
different inlining thresholds and substantially increase test coverage of MIR
inlining when used with increased thresholds (for example, necessary to test
#78844).
look at assoc ct, check the type of nodes
an example where types matter are function objects, see the added test which previously passed.
Now does a shallow comparison of unevaluated constants.
r? ```@oli-obk```
Majority of targets use "unknown" vendor and changing it from "unknown" to omitted doesn't make sense.
From the LLVM docs (https://clang.llvm.org/docs/CrossCompilation.html#target-triple):
>Most of the time it can be omitted (and Unknown) will be assumed, which sets the defaults for the specified architecture.
>When a parameter is not important, it can be omitted, or you can choose unknown and the defaults will be used. If you choose a parameter that Clang doesn’t know, like blerg, it’ll ignore and assume unknown
The discussion seems to have resolved that this lint is a bit "noisy" in
that applying it in all places would result in a reduction in
readability.
A few of the trivial functions (like `Path::new`) are fine to leave
outside of closures.
The general rule seems to be that anything that is obviously an
allocation (`Box`, `Vec`, `vec![]`) should be in a closure, even if it
is a 0-sized allocation.
It was only ever used with Vec<u8> anyway. This simplifies some things.
- It no longer needs to be flushed, because that's a no-op anyway for
a Vec<u8>.
- Writing to a Vec<u8> never fails.
- No #[cfg(test)] code is needed anymore to use `realstd` instead of
`std`, because Vec comes from alloc, not std (like Write).
Add comments to explain memory usage optimization
Add explanatory comments so that people understand that it's just an optimization and doesn't affect behavior.
rustc_target: Further cleanup use of target options
Follow up to https://github.com/rust-lang/rust/pull/77729.
Implements items 2 and 4 from the list in https://github.com/rust-lang/rust/pull/77729#issue-500228243.
The first commit collapses uses of `target.options.foo` into `target.foo`.
The second commit renames some target options to avoid tautology:
`target.target_endian` -> `target.endian`
`target.target_c_int_width` -> `target.c_int_width`
`target.target_os` -> `target.os`
`target.target_env` -> `target.env`
`target.target_vendor` -> `target.vendor`
`target.target_family` -> `target.os_family`
`target.target_mcount` -> `target.mcount`
r? `@Mark-Simulacrum`
Assert that a return place is not used for indexing during integration
The inliner integrates call destination place with callee return place
by remapping the local and adding extra projections as necessary.
If a call destination place contains any projections (which is already
possible) and a return place is used in an indexing projection (most
likely doesn't happen yet) the end result would be incorrect.
Add an assertion to ensure that potential issue won't go unnoticed in
the presence of more sophisticated copy propagation scheme.
Make it more clear what an about async fn's returns when referring to what it returns
see #76547
This is *likely* not the ONLY place that this happens to be unclear, but we can move this fn to rustc_middle or something like that and reuse it if need be, to apply it to more diagnostics
One outstanding question I have is, if the fn returns (), should I make the message more clear (what about `fn f()` vs `fn f() -> ()`, can you tell those apart in the hir?)
R? `@tmandry`
`@rustbot` modify labels +A-diagnostics +T-compiler
* `-Zinline-mir-threshold` to change the default threshold.
* `-Zinline-mir-hint-threshold` to change the threshold used by
functions with inline hint.
Monomorphize a type argument of size-of operation during codegen
This wasn't necessary until MIR inliner started to consider drop glue as
a candidate for inlining; introducing for the first time a generic use
of size-of operation.
No test at this point since this only happens with a custom inlining
threshold.
rustc_ast: Do not panic by default when visiting macro calls
Panicking by default made sense when we didn't have HIR or MIR and everything worked on AST, but now all AST visitors run early and majority of them have to deal with macro calls, often by ignoring them.
The second commit renames `visit_mac` to `visit_mac_call`, the corresponding structures were renamed earlier in https://github.com/rust-lang/rust/pull/69589.
inliner: Break inlining cycles
Keep track of all instances inlined so far. When examining a new call
sites from an inlined body, skip those where callee had been inlined
already to avoid potential inlining cycles.
Fixes#78573.
Improve lifetime name annotations for closures & async functions
* Don't refer to async functions as "generators" in error output
* Where possible, emit annotations pointing exactly at the `&` in the return type of closures (when they have explicit return types) and async functions, like we do for arguments.
Addresses #74072, but I wouldn't call that *closed* until annotations are identical for async and non-async functions.
* Emit a better annotation when the lifetime doesn't appear in the full name type, which currently happens for opaque types like `impl Future`. Addresses #74497, but further improves could probably be made (why *doesn't* it appear in the type as `impl Future + '1`?)
This is included in the same PR because the changes to `give_name_if_anonymous_region_appears_in_output` would introduce ICE otherwise (it would return `None` in cases where it didn't previously, which then gets `unwrap`ped)
gsgdt [https://crates.io/crates/gsgdt] is a crate which provides an
interface for stringly typed graphs. It also provides generation of
graphviz dot format from said graph.
Implement destructuring assignment for tuples
This is the first step towards implementing destructuring assignment (RFC: https://github.com/rust-lang/rfcs/pull/2909, tracking issue: #71126). This PR is the first part of #71156, which was split up to allow for easier review.
Quick summary: This change allows destructuring the LHS of an assignment if it's a (possibly nested) tuple.
It is implemented via a desugaring (AST -> HIR lowering) as follows:
```rust
(a,b) = (1,2)
```
... becomes ...
```rust
{
let (lhs0,lhs1) = (1,2);
a = lhs0;
b = lhs1;
}
```
Thanks to `@varkor` who helped with the implementation, particularly around default binding modes.
r? `@petrochenkov`
inliner: Use substs_for_mir_body
Changes from 68965 extended the kind of instances that are being
inlined. For some of those, the `instance_mir` returns a MIR body that
is already expressed in terms of the types found in substitution array,
and doesn't need further substitution.
Use `substs_for_mir_body` to take that into account.
Resolves#78529.
Resolves#78560.
Fix handling of item names for HIR
- Handle variants, fields, macros in `Node::ident()`
- Handle the crate root in `opt_item_name`
- Rewrite `item_name` in terms of `opt_item_name`
I need this for both https://github.com/rust-lang/rust/pull/77820 and https://github.com/rust-lang/rust/pull/78082, so splitting it out into a separate PR so it can land early.
Recognize `private_intra_doc_links` as a lint
Previously, trying to allow this would give another error!
```
warning: unknown lint: `private_intra_doc_links`
--> private.rs:1:10
|
1 | #![allow(private_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `broken_intra_doc_links`
|
= note: `#[warn(unknown_lints)]` on by default
warning: public documentation for `DocMe` links to private item `DontDocMe`
--> private.rs:2:11
|
2 | /// docs [DontDocMe]
| ^^^^^^^^^ this item is private
|
= note: `#[warn(private_intra_doc_links)]` on by default
= note: this link will resolve properly if you pass `--document-private-items`
```
Fixes the issue found in https://github.com/rust-lang/rust/pull/77249#issuecomment-712339227.
r? ````````@Manishearth````````
Does anyone know why this additional step is necessary? It seems weird this has to be declared in 3 different places.
Refactor IntErrorKind to avoid "underflow" terminology
This PR is a continuation of #76455
# Changes
- `Overflow` renamed to `PosOverflow` and `Underflow` renamed to `NegOverflow` after discussion in #76455
- Changed some of the parsing code to return `InvalidDigit` rather than `Empty` for strings "+" and "-". https://users.rust-lang.org/t/misleading-error-in-str-parse-for-int-types/49178
- Carry the problem `char` with the `InvalidDigit` variant.
- Necessary changes were made to the compiler as it depends on `int_error_matching`.
- Redid tests to match on specific errors.
r? ```@KodrAus```
Additionally introduce storage markers for all temporaries created by
the inliner. The temporary introduced for destination rebrorrow, didn't
use them previously.
When examining candidates for inlining, reject those that are determined
to be recursive either because of self-recursive calls or calls to any
instances already inlined.
rustc_ast: Visit tokens stored in AST nodes in mutable visitor
After #77271 token visiting is enabled only for one visitor in `rustc_expand\src\mbe\transcribe.rs` which applies hygiene marks to tokens produced by declarative macros (`macro_rules` or `macro`), so this change doesn't affect anything else.
When a macro has some interpolated token from an outer macro in its output
```rust
macro inner() {
$interpolated
}
```
we can use the usual interpretation of interpolated tokens in token-based model - a None-delimited group - to write this macro in an equivalent form
```rust
macro inner() {
⟪ a b c d ⟫
}
```
When we are expanding the macro `inner` we need to apply hygiene marks to all tokens produced by it, including the tokens inside the group.
Before this PR we did this by visiting the AST piece inside the interpolated token and applying marks to all spans in it.
I'm not sure this is 100% correct (ideally we should apply the marks to tokens and then re-parse the AST from tokens), but it's a very good approximation at least.
We didn't however apply the marks to actual tokens stored in the nonterminal, so if we used the nonterminal as a token rather than as an AST piece (e.g. passed it to a proc macro), then we got hygiene bugs.
This PR applies the marks to tokens in addition to the AST pieces thus fixing the issue.
r? `@Aaron1011`
This allows constructing the sccc for large that visit many nodes before
finding a single cycle of sccc, for example lists. When used to find
dependencies in borrow checking the list case is what occurs in very
long functions.
with an eye on merging `TargetOptions` into `Target`.
`TargetOptions` as a separate structure is mostly an implementation detail of `Target` construction, all its fields logically belong to `Target` and available from `Target` through `Deref` impls.
Rollup of 19 pull requests
Successful merges:
- #76097 (Stabilize hint::spin_loop)
- #76227 (Stabilize `Poll::is_ready` and `is_pending` as const)
- #78065 (make concurrency helper more pleasant to read)
- #78570 (Remove FIXME comment in print_type_sizes ui test suite)
- #78572 (Use SOCK_CLOEXEC and accept4() on more platforms.)
- #78658 (Add a tool to run `x.py` from any subdirectory)
- #78706 (Fix run-make tests running when LLVM is disabled)
- #78728 (Constantify `UnsafeCell::into_inner` and related)
- #78775 (Bump Rustfmt and RLS)
- #78788 (Correct unsigned equivalent of isize to be usize)
- #78811 (Make some std::io functions `const`)
- #78828 (use single char patterns for split() (clippy::single_char_pattern))
- #78841 (Small cleanup in `TypeFoldable` derive macro)
- #78842 (Honor the rustfmt setting in config.toml)
- #78843 (Less verbose debug logging from inlining integrator)
- #78852 (Convert a bunch of intra-doc links)
- #78860 (rustc_resolve: Use `#![feature(format_args_capture)]`)
- #78861 (typo and formatting)
- #78865 (Don't fire `CONST_ITEM_MUTATION` lint when borrowing a deref)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Don't fire `CONST_ITEM_MUTATION` lint when borrowing a deref
Fixes#78819
This extends the check for dereferences added in PR #77324
to cover mutable borrows, as well as direct writes. If we're operating
on a dereference of a `const` item, we shouldn't be firing the lint.
rustc_resolve: Use `#![feature(format_args_capture)]`
This is the best new sugar for quite some time.
(I only changed places that already used named arguments.)
Less verbose debug logging from inlining integrator
The inlining integrator produces relatively verbose and uninteresting
logs. Move them from a debug log level to a trace level, so that they
can be easily isolated from others.
revert #75443, update mir validator
This PR reverts rust-lang#75443 to fix rust-lang#75992 and instead uses rust-lang#75419 to fix rust-lang#75313.
Adapts rust-lang#75419 to correctly deal with unevaluated constants as otherwise some `feature(const_evaluatable_checked)` tests would ICE.
Note that rust-lang#72793 was also fixed by rust-lang#75443, but as that issue only concerns `feature(type_alias_impl_trait)` I deleted that test case for now and would reopen that issue.
rust-lang#75443 may have also allowed some other code to now successfully compile which would make this revert a breaking change after 2 stable versions, but I hope that this is a purely theoretical concern.
See https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/generator.20upvars/near/214617274 for more reasoning about this.
r? `@nikomatsakis` `@eddyb` `@RalfJung`
rustc_target: Move some target options from `Target` to `TargetOptions`
The only reason for `Target` to `TargetOptions` to be separate structures is that options in `TargetOptions` have reasonable defaults and options in `Target` don't.
(Otherwise all the options logically belong to a single `Target` struct.)
This PR moves a number of options with reasonable defaults from `Target` to `TargetOptions`, so they no longer needs to be specified explicitly for majority of the targets.
The move also allows to inherit the options from `rustc_target/src/spec/*_base.rs` files in a nicer way.
I didn't change any specific option values here.
The moved options are `target_c_int_width` (defaults to `"32"`), `target_endian` (defaults to `"little"`), `target_os` (defaults to `"none"`), `target_env` (defaults to `""`), `target_vendor` (defaults to `"unknown"`) and `linker_flavor` (defaults to `LinkerFlavor::Gcc`).
Next steps (in later PRs):
- Find a way to merge `TargetOptions` into `Target`
- If not, always access `TargetOptions` fields through `Deref` making it a part of `Target` at least logically (`session.target.target.options.foo` -> `session.target.target.foo`)
- ~Eliminate `session::config::Config` and use `Target` instead (`session.target.target.foo` -> `session.target.foo`)~ Done in https://github.com/rust-lang/rust/pull/77943.
- Avoid tautologies in option names (`target.target_os` -> `target.os`)
- Resolve _ https://github.com/rust-lang/rust/issues/77730 (rustc_target: The differences between `target_os = "none"` and `target_os = "unknown"`, and `target_vendor = "unknown"` and `target_vendor = ""` are unclear) noticed during implementation of this PR.
This PR allows using `#[repr(simd)]` on ADTs containing a
single array field:
```rust
#[repr(simd)] struct S0([f32; 4]);
#[repr(simd)] struct S1<const N: usize>([f32; N]);
#[repr(simd)] struct S2<T, const N: usize>([T; N]);
```
This should allow experimenting with portable packed SIMD
abstractions on nightly that make use of const generics.
Fixes#78819
This extends the check for dereferences added in PR #77324
to cover mutable borrows, as well as direct writes. If we're operating
on a dereference of a `const` item, we shouldn't be firing the lint.
Revert "Revert "resolve: Avoid "self-confirming" import resolutions in one more case""
Specifically, this reverts commit b20bce8ce5 from #77421 to fix#77586.
The lang team has decided that for the time being we want to avoid the breakage here (perhaps for a future edition; though almost certainly not the upcoming one), though a future PR may want to add a lint around this case (and perhaps others) which are unlikely to be readable code.
r? `@petrochenkov` to confirm this is the right way to fix#77586.
The inlining integrator produces relatively verbose and uninteresting
logs. Move them from a debug log level to a trace level, so that they
can be easily isolated from others.
The main change is that `UnstableOptions::from_environment` now requires
an (optional) crate name. If the crate name is unknown (`None`), then the new feature is not available and you still have to use `RUSTC_BOOTSTRAP=1`. In practice this means the feature is only available for `--crate-name`, not for `#![crate_name]`; I'm interested in supporting the second but I'm not sure how.
Other major changes:
- Added `Session::is_nightly_build()`, which uses the `crate_name` of
the session
- Added `nightly_options::match_is_nightly_build`, a convenience method
for looking up `--crate-name` from CLI arguments.
`Session::is_nightly_build()`should be preferred where possible, since
it will take into account `#![crate_name]` (I think).
- Added `unstable_features` to `rustdoc::RenderOptions`
There is a user-facing change here: things like `RUSTC_BOOTSTRAP=0` no
longer active nightly features. In practice this shouldn't be a big
deal, since `RUSTC_BOOTSTRAP` is the opposite of stable and everyone
uses `RUSTC_BOOTSTRAP=1` anyway.
- Add tests
Check against `Cheat`, not whether nightly features are allowed.
Nightly features are always allowed on the nightly channel.
- Only call `is_nightly_build()` once within a function
- Use booleans consistently for rustc_incremental
Sessions can't be passed through threads, so `read_file` couldn't take a
session. To be consistent, also take a boolean in `write_file_header`.
- Handle variants, fields, macros in `Node::ident()`
- Handle the crate root in `opt_item_name`
- Factor out `item_name_from_def_id` to reduce duplication
- Look at HIR before the DefId for `opt_item_name`
This gives accurate spans, which are not available from serialized
metadata.
- Don't panic on the crate root in `opt_item_name`
- Add comments
The inliner integrates call destination place with callee return place
by remapping the local and adding extra projections as necessary.
If a call destination place contains any projections (which is already
possible) and a return place is used in an indexing projection (most
likely doesn't happen yet) the end result would be incorrect.
Add an assertion to ensure that potential issue won't go unnoticed in
the presence of more sophisticated copy propagation scheme.
This wasn't necessary until MIR inliner started to consider drop glue as
a candidate for inlining; introducing for the first time a generic use
of size-of operation.
No test at this point since this only happens with a custom inlining
threshold.
The renumber pass is long gone
Originally, there has been a dedicated pass for renumbering
AST NodeIds to have actual values. This pass had been added by
commit a5ad4c3794.
Then, later, this step was moved to where it resides now,
macro expansion. See commit c86c8d41a2
or PR #36438.
The comment snippet, added by the original commit, has
survived the times without any change, becoming outdated
at removal of the dedicated pass.
Nowadays, grepping for the next_node_id function will show up
multiple places in the compiler that call it, but the main
rewriting that the comment talks about is still done in the
expansion step, inside an innocious looking visit_id function
that's called during macro invocation collection.
inliner: Copy unevaluated constants only after successful inlining
Inliner copies the unevaluated constants from the callee body to the
caller at the point where decision to inline is yet to be made. The
constants will be unnecessary if inlining were to fail.
Organize the code moving items from callee to the caller together in one
place to avoid the issue.
Fix unreachable sub-branch detection in or-patterns
The previous implementation was too eager to avoid unnecessary "unreachable pattern" warnings. I feel more confident about this implementation than I felt about the previous one.
Fixes https://github.com/rust-lang/rust/issues/76836.
``@rustbot`` modify labels: +A-exhaustiveness-checking
Working expression optimization, and some improvements to branch-level source coverage
This replaces PR #78040 after reorganizing the original commits (by request) into a more logical sequence of major changes.
Most of the work is in the MIR `transform/coverage/` directory (originally, `transform/instrument_coverage.rs`).
Note this PR includes some significant additional debugging capabilities, to help myself and any future developer working on coverage improvements or issues.
In particular, there's a new Graphviz (.dot file) output for the coverage graph (the `BasicCoverageBlock` control flow graph) that provides ways to get some very good insight into the relationships between the MIR, the coverage graph BCBs, coverage spans, and counters. (There are also some cool debugging options, available via environment variable, to alter how some data in the graph appears.)
And the code for this Graphviz view is actually generic... it can be used by any implementation of the Rust `Graph` traits.
Finally (for now), I also now output information from `llvm-cov` that shows the actual counters and spans it found in the coverage map, and their counts (from the `--debug` flag). I found this to be enormously helpful in debugging some coverage issues, so I kept it in the test results as well for additional context.
`@tmandry` `@wesleywiser`
r? `@tmandry`
Here's an example of the new coverage graph:
* Within each `BasicCoverageBlock` (BCB), you can see each `CoverageSpan` and its contributing statements (MIR `Statement`s and/or `Terminator`s)
* Each `CoverageSpan` has a `Counter` or and `Expression`, and `Expression`s show their Add/Subtract operation with nested operations. (This can be changed to show the Counter and Expression IDs instead, or in addition to, the BCB.)
* The terminators of all MIR `BasicBlock`s in the BCB, including one final `Terminator`
* If an "edge counter" is required (because we need to count an edge between blocks, in some cases) the edge's Counter or Expression is shown next to its label. (Not shown in the example below.) (FYI, Edge Counters are converted into a new MIR `BasicBlock` with `Goto`)
<img width="1116" alt="Screen Shot 2020-10-17 at 12 23 29 AM" src="https://user-images.githubusercontent.com/3827298/96331095-616cb480-100f-11eb-8212-60f2d433e2d8.png">
r? `@tmandry`
FYI: `@wesleywiser`
Implementing the Graph traits for the BasicCoverageBlock
graph.
optimized replacement of counters with expressions plus new BCB graphviz
* Avoid adding coverage to unreachable blocks.
* Special case for Goto at the end of the body. Make it non-reportable.
Improved debugging and formatting options (from env)
Don't automatically add counters to BCBs without CoverageSpans. They may
still get counters but only if there are dependencies from
other BCBs that have spans, I think.
Make CodeRegions optional for Counters too. It is
possible to inject counters (`llvm.instrprof.increment` intrinsic calls
without corresponding code regions in the coverage map. An expression
can still uses these counter values.
Refactored instrument_coverage.rs -> instrument_coverage/mod.rs, and
then broke up the mod into multiple files.
Compiling with coverage, with the expression optimization, works on
the json5format crate and its dependencies.
Refactored debug features from mod.rs to debug.rs
Originally, there has been a dedicated pass for renumbering
AST NodeIds to have actual values. This pass had been added by
commit a5ad4c3794.
Then, later, this step was moved to where it resides now,
macro expansion. See commit c86c8d41a2
or PR #36438.
The comment snippet, added by the original commit, has
survived the times without any change, becoming outdated
at removal of the dedicated pass.
Nowadays, grepping for the next_node_id function will show up
multiple places in the compiler that call it, but the main
rewriting that the comment talks about is still done in the
expansion step, inside an innocious looking visit_id function
that's called during macro invocation collection.
Changes from 68965 extended the kind of instances that are being
inlined. For some of those, the `instance_mir` returns a MIR body that
is already expressed in terms of the types found in substitution array,
and doesn't need further substitution.
Use `substs_for_mir_body` to take that into account.
The basic conversion is a straightforward conversion of the linear
recursion to a loop forwards and backwards propagation of the result.
But this uses an optimization to avoid the need for extra space that
would otherwise be necessary to store the stack of unfinished states as
the function is not tail recursive.
Observe that only non-root-nodes in cycles have a recursive call and
that every such call overwrites their own node state. Thus we reuse the
node state itself as temporary storage for the stack of unfinished
states by inverting the links to a chain back to the previous state
update. When we hit the root or end of the full explored chain we
propagate the node state update backwards by following the chain until
a node with a link to itself.
Previously, trying to allow this would give another error!
```
warning: unknown lint: `private_intra_doc_links`
--> private.rs:1:10
|
1 | #![allow(private_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `broken_intra_doc_links`
|
= note: `#[warn(unknown_lints)]` on by default
warning: public documentation for `DocMe` links to private item `DontDocMe`
--> private.rs:2:11
|
2 | /// docs [DontDocMe]
| ^^^^^^^^^ this item is private
|
= note: `#[warn(private_intra_doc_links)]` on by default
= note: this link will resolve properly if you pass `--document-private-items`
```
reverse binding order in matches to allow the subbinding of copyable fields in bindings after @
Fixes#69971
### TODO
- [x] Regression tests
r? `@oli-obk`
Inliner copies the unevaluated constants from the callee body to the
caller at the point where decision to inline is yet to be made. The
constants will be unnecessary if inlining were to fail.
Organize the code moving items from callee to the caller together in one
place to avoid the issue.
Provide diagnostic suggestion in ExprUseVisitor Delegate
The [Delegate trait](981346fc07/compiler/rustc_typeck/src/expr_use_visitor.rs (L28-L38)) currently use `PlaceWithHirId` which is composed of Hir `Place` and the
corresponding expression id.
Even though this is an accurate way of expressing how a Place is used,
it can cause confusion during diagnostics.
Eg:
```
let arr : [String; 5];
let [a, ...] = arr;
^^^ E1 ^^^ = ^^E2^^
```
Here `arr` is moved because of the binding created E1. However, when we
point to E1 in diagnostics with the message `arr` was moved, it can be
confusing. Rather we would like to report E2 to the user.
Closes: https://github.com/rust-lang/project-rfc-2229/issues/20
r? `@ghost`
Refactorings in preparation for const value trees
cc #72396
This PR changes the `Scalar::Bits { data: u128, size: u8 }` variant to `Scalar::Bits(ScalarInt)` where `ScalarInt` contains the same information, but is `repr(packed)`. The reason for using a packed struct is to allow enum variant packing to keep the original size of `Scalar` instead of adding another word to its size due to padding.
Other than that the PR just gets rid of all the inspection of the internal fields of `Scalar::Bits` which were frankly scary. These fields have invariants that we need to uphold and we can't do that without making the fields private.
r? `@ghost`
Use reparsed `TokenStream` if we captured any inner attributes
Fixes#78675
We now bail out of `prepend_attrs` if we ended up capturing any inner
attributes (which can happen in several places, due to token capturing
for `macro_rules!` arguments.
Hash both the length and the end location (line/column) of a span. If we
hash only the length, for example, then two otherwise equal spans with
different end locations will have the same hash. This can cause a
problem during incremental compilation wherein a previous result for a
query that depends on the end location of a span will be incorrectly
reused when the end location of the span it depends on has changed. A
similar analysis applies if some query depends specifically on the
length of the span, but we only hash the end location. So hash both.
Fix#46744, fix#59954, fix#63161, fix#73640, fix#73967, fix#74890, fix#75900
Corrected suggestion for generic parameters in `function_item_references` lint
This commit handles functions with generic type parameters like you pointed out as well as const generics. Also this is probably a minor thing, but the type alias you used in the example doesn't show up so the suggestion right now would be `size_of::<[u8; 16]> as fn() ->`. This is because the lint checker works with MIR instead of HIR. I don't think we can get the alias at that point, but let me know if I'm wrong and there's a way to fix this. Also I put you as the reviewer, but I'm not sure if you want to review it or if it makes more sense to ask one of the original reviewers of this lint.
closes#78571
Improve errors about #[deprecated] attribute
This change:
1. Turns `#[deprecated]` on a trait impl block into an error, which fixes#78625;
2. Changes these and other errors about `#[deprecated]` to use the span of the attribute instead of the item; and
3. Turns this error into a lint, to make sure it can be capped with `--cap-lints` and doesn't break any existing dependencies.
Can be reviewed per commit.
---
Example:
```rust
struct X;
#[deprecated = "a"]
impl Default for X {
#[deprecated = "b"]
fn default() -> Self {
X
}
}
```
Before:
```
error: This deprecation annotation is useless
--> src/main.rs:6:5
|
6 | / fn default() -> Self {
7 | | X
8 | | }
| |_____^
```
After:
```
error: this `#[deprecated]' annotation has no effect
--> src/main.rs:3:1
|
3 | #[deprecated = "a"]
| ^^^^^^^^^^^^^^^^^^^ help: try removing the deprecation attribute
|
= note: `#[deny(useless_deprecated)]` on by default
error: this `#[deprecated]' annotation has no effect
--> src/main.rs:5:5
|
5 | #[deprecated = "b"]
| ^^^^^^^^^^^^^^^^^^^ help: try removing the deprecation attribute
```
Add support for SHA256 source file hashing
Adds support for `-Z src-hash-algorithm sha256`, which became available in LLVM 11.
Using an older version of LLVM will cause an error `invalid checksum kind` if the hash algorithm is set to sha256.
r? `@eddyb`
cc #70401 `@est31`
Properly handle lint spans after MIR inlining
The first commit shows what happens when we apply mir inlining and then cause lints on the inlined MIR.
The second commit fixes that.
r? `@wesleywiser`
Retagging: do not retag 'raw reborrows'
When doing `&raw const (*raw_ptr).field`, we do not want any retagging; the original provenance should be fully preserved.
Fixes https://github.com/rust-lang/miri/issues/1608
Test added by https://github.com/rust-lang/miri/pull/1614
Not sure whom to ask for review on this... `@oli-obk` can you have a look? Or maybe highfive makes a good choice.^^
This is helpful when looking for CGUs where the size estimate isn't a
good indicator of compilation time.
I verified that moving the profiling timer call doesn't affect the
results.
add mipsel-unknown-none target
This adds a target for bare MIPS32r2, little endian, softfloat. This target can be used for PIC32 microcontrollers (or possibly for other devices that have a MIPS MCU core such as the M4K core).
Tried to find a name for the target that is in line with the naming scheme apparently used for the other MIPS targets.
r? `@jonas-schievink`
Fix ICE when a future-incompat-report has its command-line level capped
Fixes#78660
With PR https://github.com/rust-lang/rust/pull/75534 merged, we now run
more lint-related code for future-incompat-report, even when their final
level is Allow. Some lint-related code was not expecting `Level::Allow`,
and had an explicit panic.
This PR explicitly tracks the lint level set on the command line before
`--cap-lints` is applied. This is used to emit a more precise error
note (e.g. we don't say that `-W lint-name` was specified on the
command line just because a lint was capped to Warn). As a result, we
can now correctly emit a note that `-A` was used if we got
`Level::Allow` from the command line (before the cap is applied).
Treat trailing semicolon as a statement in macro call
See #61733 (comment)
We now preserve the trailing semicolon in a macro invocation, even if
the macro expands to nothing. As a result, the following code no longer
compiles:
```rust
macro_rules! empty {
() => { }
}
fn foo() -> bool { //~ ERROR mismatched
{ true } //~ ERROR mismatched
empty!();
}
```
Previously, `{ true }` would be considered the trailing expression, even
though there's a semicolon in `empty!();`
This makes macro expansion more token-based.
foreign_modules query hash table lookups
When compiling a large monolithic crate we're seeing huge times in the `foreign_modules` query due to repeated iteration over foreign modules (in order to find a module by its id). This implements hash table lookups so that which massively reduces time spent in that query in this particular case. We'll need to see if the overhead of creating the hash table has a negative impact on performance in more normal compilation scenarios.
I'm working with `@wesleywiser` on this.
Fixes#78675
We now bail out of `prepend_attrs` if we ended up capturing any inner
attributes (which can happen in several places, due to token capturing
for `macro_rules!` arguments.
See https://github.com/rust-lang/rust/issues/61733#issuecomment-716188981
We now preserve the trailing semicolon in a macro invocation, even if
the macro expands to nothing. As a result, the following code no longer
compiles:
```rust
macro_rules! empty {
() => { }
}
fn foo() -> bool { //~ ERROR mismatched
{ true } //~ ERROR mismatched
empty!();
}
```
Previously, `{ true }` would be considered the trailing expression, even
though there's a semicolon in `empty!();`
This makes macro expansion more token-based.
Transform post order walk to an iterative approach
The previous recursive approach might overflow the stack when walking a
particularly deep, list-like, graph. In particular, dominator
calculation for borrow checking does such a traversal and very long
functions might lead to a region dependency graph with in this
problematic structure.
This addresses what appears to be the cause of #78567 (`@SunHao-0` thanks for the stack trace).
Rollup of 5 pull requests
Successful merges:
- #78606 (Clarify handling of final line ending in str::lines())
- #78610 (Do not remove tokens before AST json serialization)
- #78620 (Trivial fixes to bitwise operator documentation)
- #78627 (Point out that total_cmp is no strict superset of partial comparison)
- #78637 (Add fetch_update methods to AtomicBool and AtomicPtr)
Failed merges:
r? `@ghost`
Fixes#78660
With PR https://github.com/rust-lang/rust/pull/75534 merged, we now run
more lint-related code for future-incompat-report, even when their final
level is Allow. Some lint-related code was not expecting `Level::Allow`,
and had an explicit panic.
This PR explicitly tracks the lint level set on the command line before
`--cap-lints` is applied. This is used to emit a more precise error
note (e.g. we don't say that `-W lint-name` was specified on the
command line just because a lint was capped to Warn). As a result, we
can now correctly emit a note that `-A` was used if we got
`Level::Allow` from the command line (before the cap is applied).
The [Delegate
trait](981346fc07/compiler/rustc_typeck/src/expr_use_visitor.rs (L28-L38))
currently use `PlaceWithHirId` which is composed of Hir `Place` and the
corresponding expression id.
Even though this is an accurate way of expressing how a Place is used,
it can cause confusion during diagnostics.
Eg:
```
let arr : [String; 5];
let [a, ...] = arr;
^^^ E1 ^^^ = ^^E2^^
```
Here `arr` is moved because of the binding created E1. However, when we
point to E1 in diagnostics with the message `arr` was moved, it can be
confusing. Rather we would like to report E2 to the user.
Closes: https://github.com/rust-lang/project-rfc-2229/issues/20
Do not remove tokens before AST json serialization
`TokenStripper` is error-prone and introduces one more use of `MutVisitor`.
It's much simpler to treat serialization as just one more place that wants lazy token stream to turn into a real token stream.
Also, no code is better than more code, in general.
r? @Aaron1011
(I also merged tests for `TokenStripper` ICEs into one.)
Add option to customize the nll-facts' folder location
This PR adds a `nll-facts-dir` option to specify the location of the directory in which NLL facts are dumped into. It works the same way `dump-mir-dir` controls the location used by the `dump-mir` option.
This lint was incorrectly suggesting casting a function to a pointer without
specifying generic type parameters or const generics. This would cause a
compiler error since the missing parameters couldn't be inferred. This commit
fixed the suggestion and added a few tests with generics.
Implement -Z relax-elf-relocations=yes|no
This lets rustc users tweak whether the linker should relax ELF relocations without recompiling a whole new target with its own libcore etc.
Implement rustc side of report-future-incompat
cc https://github.com/rust-lang/rust/issues/71249
This is an alternative to `@pnkfelix's` initial implementation in https://github.com/pnkfelix/rust/commits/prototype-rustc-side-of-report-future-incompat (mainly because I started working before seeing that branch 😄 ).
My approach outputs the entire original `Diagnostic`, in a way that is compatible with incremental compilation. This is not yet integrated with compiletest, but can be used manually by passing `-Z emit-future-incompat-report` to `rustc`.
Several changes are made to support this feature:
* The `librustc_session/lint` module is moved to a new crate `librustc_lint_defs` (name bikesheddable). This allows accessing lint definitions from `librustc_errors`.
* The `Lint` struct is extended with an `Option<FutureBreakage>`. When present, it indicates that we should display a lint in the future-compat report. `FutureBreakage` contains additional information that we may want to display in the report (currently, a `date` field indicating when the crate will stop compiling).
* A new variant `rustc_error::Level::Allow` is added. This is used when constructing a diagnostic for a future-breakage lint that is marked as allowed (via `#[allow]` or `--cap-lints`). This allows us to capture any future-breakage diagnostics in one place, while still discarding them before they are passed to the `Emitter`.
* `DiagnosticId::Lint` is extended with a `has_future_breakage` field, indicating whether or not the `Lint` has future breakage information (and should therefore show up in the report).
* `Session` is given access to the `LintStore` via a new `SessionLintStore` trait (since `librustc_session` cannot directly reference `LintStore` without a cyclic dependency). We use this to turn a string `DiagnosticId::Lint` back into a `Lint`, to retrieve the `FutureBreakage` data.
Currently, `FutureBreakage.date` is always set to `None`. However, this could potentially be interpreted by Cargo in the future.
I've enabled the future-breakage report for the `ARRAY_INTO_ITER` lint, which can be used to test out this PR. The intent is to use the field to allow Cargo to determine the date of future breakage (as described in [RFC 2834](https://github.com/rust-lang/rfcs/blob/master/text/2834-cargo-report-future-incompat.md)) without needing to parse the diagnostic itself.
cc `@pnkfelix`
Fix#78549
Before #78430, this worked because `specialize_constructor` didn't actually care too much which constructor was passed to it unless needed. That PR however handles `&str` as a special case, and I did not anticipate patterns for the `&str` type other than string literals.
I am not very confident there are not other similar oversights left, but hopefully only `&str` was different enough to break my assumptions.
Fixes https://github.com/rust-lang/rust/issues/78549
Rollup of 6 pull requests
Successful merges:
- #78073 (Add #[inline] to some functions in core::str.)
- #78596 (Fix doc links to std::fmt)
- #78599 (Add note to process::arg[s] that args shouldn't be escaped or quoted)
- #78602 (fix various aliasing issues in the standard library)
- #78603 (expand: Tweak a comment in implementation of `macro_rules`)
- #78621 (Inline Default::default() for atomics)
Failed merges:
r? `@ghost`
expand: Tweak a comment in implementation of `macro_rules`
The answer to the removed FIXME is that we don't apply mark to the span `sp` just because that span is no longer used. We could apply it, but that would just be unnecessary extra work.
The comments in code tell why the span is unused, it's a span of `$var` literally, which is lost for `tt` variables because their tokens are outputted directly, but kept for other variables which are outputted as [groups](https://doc.rust-lang.org/nightly/proc_macro/struct.Group.html) and `sp` is kept as the group's span.
Closes https://github.com/rust-lang/rust/issues/2887
rustc_llvm: unwrap LLVMMetadataRef before casting
Directly casting the opaque pointer was [reported] to cause an
"incomplete type" error with GCC 9.3:
```
llvm-wrapper/RustWrapper.cpp:939:31: required from here
/usr/include/c++/9.3/type_traits:1301:12: error: invalid use of incomplete type 'struct LLVMOpaqueMetadata'
1301 | struct is_base_of
| ^~~~~~~~~~
In file included from [...]/rust/src/llvm-project/llvm/include/llvm-c/BitReader.h:23,
from llvm-wrapper/LLVMWrapper.h:1,
from llvm-wrapper/RustWrapper.cpp:1:
[...]/rust/src/llvm-project/llvm/include/llvm-c/Types.h:89:16: note: forward declaration of 'struct LLVMOpaqueMetadata'
89 | typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
| ^~~~~~~~~~~~~~~~~~
```
[reported]: https://zulip-archive.rust-lang.org/182449tcompilerhelp/12215halprustcllvmbuildfail.html#214915124
A simple `unwrap` fixes the issue.
r? `@eddyb`
Suggest calling associated `fn` inside `trait`s
When calling a function that doesn't exist inside of a trait's
associated `fn`, and another associated `fn` in that trait has that
name, suggest calling it with the appropriate fully-qualified path.
Expand the label to be more descriptive.
Prompted by the following user experience:
https://users.rust-lang.org/t/cannot-find-function/50663
Before #78430, string literals worked because `specialize_constructor`
didn't actually care too much which constructor was passed to it unless
needed. Since then, string literals are special cased and a bit hacky. I
did not anticipate patterns for the `&str` type other than string
literals, hence this bug. This makes string literals less hacky.
The validator in visit_local asserts that local has a stroage when used,
but visit_local is never called so validation is ineffective.
Use super_statement and super_terminator to ensure that locals are visited.
The previous recursive approach might overflow the stack when walking a
particularly deep, list-like, graph. In particular, dominator
calculation for borrow checking does such a traversal and very long
functions might lead to a region dependency graph with in this
problematic structure.
This lets rustc users tweak whether the linker should relax ELF relocations,
namely whether it should emit R_X86_64_GOTPCRELX relocations instead of
R_X86_64_GOTPCREL, as the former is allowed by the ABI to be further
optimised. The default value is whatever the target defines.
The log color variable is whatever the log variable is (`RUSTC_LOG`,
`RUSTDOC_LOG`, `MIRI_LOG`, etc.) + `_COLOR`. So `RUSTC_LOG_COLOR`,
`RUSTDOC_LOG_COLOR`, `MIRI_LOG_COLOR`, etc.
Thanks to @RalfJung for suggesting this! It was much easier to implement
than adding a new unstable argument, which is what I tried before.
- Add more well-known traits
- Use the correct binders when lowering trait objects
- Use correct substs when lowering trait objects
- Use the correct binders for opaque_ty_data
- Lower negative impls with the correct polarity
- Supply associated type values
- Use `predicates_defined_on` for where clauses
Avoid BorrowMutError with RUSTC_LOG=debug
```console
$ touch empty.rs
$ env RUSTC_LOG=debug rustc +stage1 --crate-type=lib empty.rs
```
Fails with a `BorrowMutError` because source map files are already
borrowed while `features_query` attempts to format a log message
containing a span.
Release the borrow before the query to avoid the issue.
Simplify a nested bool match
Logically this first eliminates the innermost match by merging the patterns.
Then, in a second step, turns the newly innermost match into a `matches!` call.
Always record reference to binding in match if guards
When encountering a binding from a `match` pattern in its `if` guard when computing a generator's interior types, we must always record the type of a reference to the binding because of how `if` guards are lowered to MIR. This was missed in #75213 because the binding in that test case was autorefed and we recorded that adjusted type anyway.
Fixes#78366
[resolve] Use `unwrap_or_else` instead of `unwrap_or` in a hot path
This improves the performance of the `resolve_crate` function by 30% for
a very large single file crate with auto-generated C bindings.
cc `@rylev`
Directly casting the opaque pointer was [reported] to cause an
"incomplete type" error with GCC 9.3:
```
llvm-wrapper/RustWrapper.cpp:939:31: required from here
/usr/include/c++/9.3/type_traits:1301:12: error: invalid use of incomplete type 'struct LLVMOpaqueMetadata'
1301 | struct is_base_of
| ^~~~~~~~~~
In file included from [...]/rust/src/llvm-project/llvm/include/llvm-c/BitReader.h:23,
from llvm-wrapper/LLVMWrapper.h:1,
from llvm-wrapper/RustWrapper.cpp:1:
[...]/rust/src/llvm-project/llvm/include/llvm-c/Types.h:89:16: note: forward declaration of 'struct LLVMOpaqueMetadata'
89 | typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
| ^~~~~~~~~~~~~~~~~~
```
[reported]: https://zulip-archive.rust-lang.org/182449tcompilerhelp/12215halprustcllvmbuildfail.html#214915124
A simple `unwrap` fixes the issue.
Use unwrapDIPtr because the Scope may be null.
I ran into an assertion when using debug information on Windows with LLVM assertions enabled.
It seems like we are using unwrap here (which in turn calls isa and requires the pointer to be non-null) but we expect the value to be null because that is what we are passing from rustc.
This change uses unwrapDIPtr which explicitly allows nullptr.
The FFI prototype for this method on the rust side has the `LLVMMetadataRef` parameter as `Scope: Option<&'a DIScope>`, and we always pass `None` when `msvc_like_names` is true.
rustc_span: improve bounds checks in byte_pos_to_line_and_col
The effect of this change is to consider edge-case spans that start or
end at the position one past the end of a file to be valid during span
hashing and encoding. This change means that these spans will be
preserved across incremental compilation sessions when they are part of
a serialized query result, instead of causing the dummy span to be used.
Dogfood {exclusive,half-open} ranges in compiler (nfc)
In particular, this allows us to write more explicit matches that
avoid the pitfalls of using a fully general fall-through case, yet
remain fairly ergonomic. Less logic is in guard cases, more is in
the actual exhaustive case analysis.
No functional changes.
In particular, this allows us to write more explicit matches that
avoid the pitfalls of using a fully general fall-through case, yet
remain fairly ergonomic. Less logic is in guard cases, more is in
the actual exhaustive case analysis.
No functional changes.
Adjust turbofish help message for const generics
Types are no longer special. (This message arguably only makes sense with `min_const_generics` or more, but we'll be there soon.)
r? @lcnr
min_const_generics: allow ty param in repeat expr
implements https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/repeat.20expressions
Even with `min_const_generics` active, now keeps resulting in future compat warnings instead of hard errors.
Const parameters, for example `[0; N + 1]`, still result in hard errors during resolve.
```rust
#![allow(dead_code)]
fn foo<T>() {
[0; std::mem::size_of::<*mut T>()];
}
struct Foo<T>(T);
impl<T> Foo<T> {
const ASSOC: usize = 4;
fn test() {
[0; Self::ASSOC];
}
}
```
r? @varkor cc @petrochenkov
Clarify main code paths in exhaustiveness checking
This PR massively clarifies the main code paths of exhaustiveness checking, by using the `Constructor` enum to a fuller extent. I've been itching to write it for more than a year, but the complexity of matching consts had prevented me. Behold a massive simplification :D.
This in particular removes a fair amount of duplication between various parts, localizes code into methods of relevant types when applicable, makes some implicit assumptions explicit, and overall improves legibility a lot (or so I hope). Additionally, after my changes undoing #76918 turned out to be a noticeable perf gain.
As usual I tried my best to make the commits self-contained and easy to follow. I've also tried to keep the code well-commented, but I tend to forget how complex this file is; I'm happy to clarify things as needed.
My measurements show good perf improvements on the two match-heavy benchmarks (-18.0% on `unicode_normalization-check`! :D); I'd like a perf run to check the overall impact.
r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
$ touch empty.rs
$ env RUSTC_LOG=debug rustc +stage1 --crate-type=lib empty.rs
Fails with a `BorrowMutError` because source map files are already
borrowed while `features_query` attempts to format a log message
containing a span.
Release the borrow before the query to avoid the issue.
Implement -Z function-sections=yes|no
This lets rustc users tweak whether all functions should be put in their own TEXT section, using whatever default value the target defines if the flag is missing.
I'm having fun experimenting with musl libc and trying to implement the start symbol in Rust, that means avoiding code that requires relocations, and AFAIK putting everything in its own section makes the toolchain generate `GOTPCREL` relocations for symbols that could use plain old PC-relative addressing (at least on `x86_64`) if they were all in the same section.
Iterate over the smaller list
If there are two lists of different sizes,
iterating over the smaller list and then
looking up in the larger list is cheaper
than vice versa, because lookups scale
sublinearly.
resolve: private fields in tuple struct ctor diag
Fixes#75906.
This PR improves the diagnostic emitted when a tuple struct is being constructed which has private fields so that private fields are labelled and the message is improved.
r? @estebank
Tweak invalid `fn` header and body parsing
* Rely on regular "expected"/"found" parser error for `fn`, fix#77115
* Recover empty `fn` bodies when encountering `}`
* Recover trailing `>` in return types
* Recover from non-type in array type `[<BAD TOKEN>; LEN]`
check object safety of generic constants
As `Self` can only be effectively used in constants with `const_evaluatable_checked` this should not matter outside of it.
Implements the first item of #72219
> Object safety interactions with constants
r? @oli-obk for now cc @nikomatsakis
Move "mutable thing in const" check from interning to validity
This moves the check for mutable things (such as `UnsafeCell` or `&mut`) in a`const` from interning to validity. That means we can give more targeted error messages (pointing out *where* the problem lies), and we can simplify interning a bit.
Also fix the interning mode used for promoteds in statics.
r? @oli-obk
Suggest calling await on method call and field access
When encountering a failing method or field resolution on a `Future`,
look at the `Output` and try the same operation on it. If successful,
suggest calling `.await` on the `Future`.
This had already been introduced in #72784, but at some point they
stopped working.
Built on top of #78214, only last commit is relevant.
r? @oli-obk
Separate unsized locals
Closes#71694
Takes over again #72029 and #74971
cc @RalfJung @oli-obk @pnkfelix @eddyb as they've participated in previous reviews of this PR.
Uplift `temporary-cstring-as-ptr` lint from `clippy` into rustc
The general consensus seems to be that this lint covers a common enough mistake to warrant inclusion in rustc.
The diagnostic message might need some tweaking, as I'm not sure the use of second-person perspective matches the rest of rustc, but I'd like to hear others' thoughts on that.
(cc #53224).
r? `@oli-obk`
When a function argument bound by `Pointer` is an associated type, we only
perform substitutions using the parameters from the callsite but don't attempt
to normalize since it may not succeed. A simplified version of the scenario that
triggered this error was added as a test case. Also fixed `Pointer::fmt` which
was being double-counted when called outside of macros and added a test case for
this.
Removed test for the unhandled case of calls to `fn f<T>(x: &T)` where `x` is a
function reference and is formatted as a pointer in `f`. This compiles since
`&T` implements `Pointer`, but is unlikely to occur in practice. Also tweaked
the lint's wording and modified tests accordingly.
The lint checks arguments in calls to `transmute` or functions that have
`Pointer` as a trait bound and displays a warning if the argument is a function
reference. Also checks for `std::fmt::Pointer::fmt` to handle formatting macros
although it doesn't depend on the exact expansion of the macro or formatting
internals. `std::fmt::Pointer` and `std::fmt::Pointer::fmt` were also added as
diagnostic items and symbols.
Working with MIR let's us exclude expressions like `&fn_name as &dyn Something`
and `(&fn_name)()`. Also added ABI, unsafety and whether a function is variadic
in the lint suggestion, included the `&` in the span of the lint and updated the
test.
Capture output from threads spawned in tests
This is revival of #75172.
Original text:
> Fixes#42474.
>
> r? `@dtolnay` since you expressed interest in this, but feel free to redirect if you aren't the right person anymore.
---
Closes#75172.
Suggest that expressions that look like const generic arguments should be enclosed in brackets
I pulled out the changes for const expressions from https://github.com/rust-lang/rust/pull/71592 (without the trait object diagnostic changes) and made some small changes; the implementation is `@estebank's.`
We're also going to want to make some changes separately to account for trait objects (they result in poor diagnostics, as is evident from one of the test cases here), such as an adaption of https://github.com/rust-lang/rust/pull/72273.
Fixes https://github.com/rust-lang/rust/issues/70753.
r? `@petrochenkov`
The test change is because we used to treat `&str` like other `&T`s, ie
as having a single constructor. That's not quite true though since we
consider `&str` constants as atomic instead of refs to `str` constants.
Also removes the ugly caching that was introduced in #76918. It was
bolted on without deeper knowledge of the workings of the algorithm.
This commit manages to be more performant without any of the complexity.
It should be better on representative workloads too.
Add compiler support for LLVM's x86_64 ERMSB feature
This change is needed for compiler-builtins to check for this feature
when implementing memcpy/memset. See:
https://github.com/rust-lang/compiler-builtins/pull/365
Without this change, the following code compiles, but does nothing:
```rust
#[cfg(target_feature = "ermsb")]
pub unsafe fn ermsb_memcpy() { ... }
```
The change just does compile-time detection. I think that runtime
detection will have to come in a follow-up CL to std-detect.
Like all the CPU feature flags, this just references #44839
Signed-off-by: Joe Richey <joerichey@google.com>
The effect of this change is to consider edge-case spans that start or
end at the position one past the end of a file to be valid during span
hashing and encoding. This change means that these spans will be
preserved across incremental compilation sessions when they are part of
a serialized query result, instead of causing the dummy span to be used.
When calling a function that doesn't exist inside of a trait's
associated `fn`, and another associated `fn` in that trait has that
name, suggest calling it with the appropriate fully-qualified path.
Expand the label to be more descriptive.
Prompted by the following user experience:
https://users.rust-lang.org/t/cannot-find-function/50663
Remove unused set-discriminant statements and assignments regardless of rvalue
* Represent use counts with u32
* Unify use count visitors
* Change RemoveStatements visitor into a function
* Remove unused set-discriminant statements
* Use exhaustive match to clarify what is being optimized
* Remove unused assignments regardless of rvalue kind
This lets rustc users tweak whether all functions should be put in their own
TEXT section, using whatever default value the target defines if the flag
is missing.
rustc_mir: track inlined callees in SourceScopeData.
We now record which MIR scopes are the roots of *other* (inlined) functions's scope trees, which allows us to generate the correct debuginfo in codegen, similar to what LLVM inlining generates.
This PR makes the `ui` test `backtrace-debuginfo` pass, if the MIR inliner is turned on by default.
Also, `#[track_caller]` is now correct in the face of MIR inlining (cc `@anp).`
Fixes#76997.
r? `@rust-lang/wg-mir-opt`
Add cg_clif as optional codegen backend
Rustc_codegen_cranelift is an alternative codegen backend for rustc based on Cranelift. It has the potential to improve compilation times in debug mode. In my experience the compile time improvements over debug mode LLVM for a clean build are about 20-30% in most cases.
This PR adds cg_clif as optional codegen backend. By default it is only enabled for `./x.py check`. It can be enabled for `./x.py build` too by adding `cranelift` to the `rust.codegen-backends` array in `config.toml`.
MCP: https://github.com/rust-lang/compiler-team/issues/270
r? `@Mark-Simulacrum`
When encountering a failing method or field resolution on a `Future`,
look at the `Output` and try the same operation on it. If successful,
suggest calling `.await` on the `Future`.
This had already been introduced in #72784, but at some point they
stopped working.
This commit improves the diagnostic emitted when a tuple struct is being
constructed which has private fields so that private fields are
labelled and the message is improved.
Signed-off-by: David Wood <david@davidtw.co>
This change is needed for compiler-builtins to check for this feature
when implementing memcpy/memset. See:
https://github.com/rust-lang/compiler-builtins/pull/365
The change just does compile-time detection. I think that runtime
detection will have to come in a follow-up CL to std-detect.
Like all the CPU feature flags, this just references #44839
Signed-off-by: Joe Richey <joerichey@google.com>
Update affected ui & incremental tests to use a user declared variable
bindings instead of temporaries. The former are preserved because of
debuginfo, the latter are not.
The simplify locals implementation uses two different visitors to update
the locals use counts. The DeclMarker calculates the initial use counts.
The StatementDeclMarker updates the use counts as statements are being
removed from the block.
Replace them with a single visitor that can operate in either mode,
ensuring consistency of behaviour.
Additionally use exhaustive match to clarify what is being optimized.
No functional changes intended.
Updated the added documentation in llvm_util.rs to note which copies of LLVM need to be inspected.
Removed avx512bf16 and avx512vp2intersect because they are unsupported before LLVM 9 with the build with external LLVM 8 being supported
Re-introduced detection testing previously removed for un-requestable features tsc and mmx
Rollup of 10 pull requests
Successful merges:
- #74477 (`#[deny(unsafe_op_in_unsafe_fn)]` in sys/wasm)
- #77836 (transmute_copy: explain that alignment is handled correctly)
- #78126 (Properly define va_arg and va_list for aarch64-apple-darwin)
- #78137 (Initialize tracing subscriber in compiletest tool)
- #78161 (Add issue template link to IRLO)
- #78214 (Tweak match arm semicolon removal suggestion to account for futures)
- #78247 (Fix#78192)
- #78252 (Add codegen test for #45964)
- #78268 (Do not try to report on closures to avoid ICE)
- #78295 (Add some regression tests)
Failed merges:
r? `@ghost`
Tweak match arm semicolon removal suggestion to account for futures
* Tweak and extend "use `.await`" suggestions
* Suggest removal of semicolon on prior match arm
* Account for `impl Future` when suggesting semicolon removal
* Silence some errors when encountering `await foo()?` as can't be certain what the intent was
*Thanks to https://twitter.com/a_hoverbear/status/1318960787105353728 for pointing this out!*
Properly define va_arg and va_list for aarch64-apple-darwin
From [Apple][]:
> Because of these changes, the type `va_list` is an alias for `char*`,
> and not for the struct type in the generic procedure call standard.
With this change `/x.py test --stage 1 src/test/ui/abi/variadic-ffi`
passes.
Fixes#78092
[Apple]: https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms
The associated_items(def_id) call
allocates internally.
Previously, we'd have called it for
each pair, so we'd have had O(n^2)
many calls. By precomputing the
associated items, we avoid
repeating so many allocations.
The only instance where this precomputation
would be a regression is if there's only
one inherent impl block for the type,
as the inner loop then doesn't run.
In that instance, we just early return.
Also, use SmallVec to avoid doing an
allocation at all if the number is small
(the case for most impl blocks out there).
This PR both adds in-source documentation on what to look out for
when adding a new (X86) feature set and adds all that are detectable at run-time in Rust stable
as of 1.27.0.
This should only enable the use of the corresponding LLVM intrinsics.
Actual intrinsics need to be added separately in rust-lang/stdarch.
It also re-orders the run-time-detect test statements to be more consistent
with the actual list of intrinsics whitelisted and removes underscores not present
in the actual names (which might be mistaken as being part of the name)
Rollup of 8 pull requests
Successful merges:
- #77984 (Compute proper module parent during resolution)
- #78085 (MIR validation should check `SwitchInt` values are valid for the type)
- #78208 (replace `#[allow_internal_unstable]` with `#[rustc_allow_const_fn_unstable]` for `const fn`s)
- #78209 (Update `compiler_builtins` to 0.1.36)
- #78276 (Bump backtrace-rs to enable Mach-O support on iOS.)
- #78320 (Link to cargo's `build-std` feature instead of `xargo` in custom target docs)
- #78322 (BTreeMap: stop mistaking node::MIN_LEN for a node level constraint)
- #78326 (Split out statement attributes changes from #78306)
Failed merges:
r? `@ghost`
Split out statement attributes changes from #78306
This is the same as PR https://github.com/rust-lang/rust/pull/78306, but `unused_doc_comments` is modified to explicitly ignore statement items (which preserves the current behavior).
This shouldn't have any user-visible effects, so it can be landed without lang team discussion.
---------
When the 'early' and 'late' visitors visit an attribute target, they
activate any lint attributes (e.g. `#[allow]`) that apply to it.
This can affect warnings emitted on sibiling attributes. For example,
the following code does not produce an `unused_attributes` for
`#[inline]`, since the sibiling `#[allow(unused_attributes)]` suppressed
the warning.
```rust
trait Foo {
#[allow(unused_attributes)] #[inline] fn first();
#[inline] #[allow(unused_attributes)] fn second();
}
```
However, we do not do this for statements - instead, the lint attributes
only become active when we visit the struct nested inside `StmtKind`
(e.g. `Item`).
Currently, this is difficult to observe due to another issue - the
`HasAttrs` impl for `StmtKind` ignores attributes for `StmtKind::Item`.
As a result, the `unused_doc_comments` lint will never see attributes on
item statements.
This commit makes two interrelated fixes to the handling of inert
(non-proc-macro) attributes on statements:
* The `HasAttr` impl for `StmtKind` now returns attributes for
`StmtKind::Item`, treating it just like every other `StmtKind`
variant. The only place relying on the old behavior was macro
which has been updated to explicitly ignore attributes on item
statements. This allows the `unused_doc_comments` lint to fire for
item statements.
* The `early` and `late` lint visitors now activate lint attributes when
invoking the callback for `Stmt`. This ensures that a lint
attribute (e.g. `#[allow(unused_doc_comments)]`) can be applied to
sibiling attributes on an item statement.
For now, the `unused_doc_comments` lint is explicitly disabled on item
statements, which preserves the current behavior. The exact locatiosn
where this lint should fire are being discussed in PR #78306
replace `#[allow_internal_unstable]` with `#[rustc_allow_const_fn_unstable]` for `const fn`s
`#[allow_internal_unstable]` is currently used to side-step feature gate and stability checks.
While it was originally only meant to be used only on macros, its use was expanded to `const fn`s.
This pr adds stricter checks for the usage of `#[allow_internal_unstable]` (only on macros) and introduces the `#[rustc_allow_const_fn_unstable]` attribute for usage on `const fn`s.
This pr does not change any of the functionality associated with the use of `#[allow_internal_unstable]` on macros or the usage of `#[rustc_allow_const_fn_unstable]` (instead of `#[allow_internal_unstable]`) on `const fn`s (see https://github.com/rust-lang/rust/issues/69399#issuecomment-712911540).
Note: The check for `#[rustc_allow_const_fn_unstable]` currently only validates that the attribute is used on a function, because I don't know how I would check if the function is a `const fn` at the place of the check. I therefore openend this as a 'draft pull request'.
Closesrust-lang/rust#69399
r? @oli-obk
Compute proper module parent during resolution
Fixes#75982
The direct parent of a module may not be a module
(e.g. `const _: () = { #[path = "foo.rs"] mod foo; };`).
To find the parent of a module for purposes of resolution, we need to
walk up the tree until we hit a module or a crate root.
perf: buffer SipHasher128
This is an attempt to improve Siphasher128 performance by buffering input. Although it reduces instruction count, I'm not confident the effect on wall times, or lack-thereof, is worth the change.
---
Additional notes not reflected in source comments:
* Implementation choices were guided by a combination of results from rustc-perf and micro-benchmarks, mostly the former.
* ~~I tried a couple of different struct layouts that might be more cache friendly with no obvious effect.~~ Update: a particular struct layout was chosen, but it's not critical to performance. See comments in source and discussion below.
* I suspect that buffering would be important to a SIMD-accelerated algorithm, but from what I've read and my own tests, SipHash does not seem very amenable to SIMD acceleration, at least by SSE.
fix def collector for impl trait
fixes#77329
We now consistently make `impl Trait` a hir owner, requiring some special casing for synthetic generic params.
r? `@eddyb`
Upgrade to measureme 9.0.0
I believe I did this correctly but there's still a reference to `measureme@0.7.1` coming from `rustc-ap-rustc_data_structures` and I'm not sure how to resolve that.
r? `@Mark-Simulacrum`
We'll also need to deploy the new version of the tools on perf.rlo.
stop promoting union field accesses in 'const'
Turns out that promotion of union field accesses is the only difference between "promotion in `const`/`static` bodies" and "explicit promotion". So if we can remove this, we have finally achieved what I thought to already be the case -- that the bodies of `const`/`static` initializers behave the same as explicit promotion contexts.
The reason we do not want to promote union field accesses is that they can introduce UB, i.e., they can go wrong. We want to [minimize the ways promoteds can fail to evaluate](https://github.com/rust-lang/const-eval/issues/53). Also this change makes things more consistent overall, removing a special case that was added without much consideration (as far as I can tell).
Cc `@rust-lang/wg-const-eval`
Rollup of 12 pull requests
Successful merges:
- #75115 (`#[deny(unsafe_op_in_unsafe_fn)]` in sys/cloudabi)
- #76614 (change the order of type arguments on ControlFlow)
- #77610 (revise Hermit's mutex interface to support the behaviour of StaticMutex)
- #77830 (Simplify query proc-macros)
- #77930 (Do not ICE with TraitPredicates containing [type error])
- #78069 (Fix const core::panic!(non_literal_str).)
- #78072 (Cleanup constant matching in exhaustiveness checking)
- #78119 (Throw core::panic!("message") as &str instead of String.)
- #78191 (Introduce a temporary for discriminant value in MatchBranchSimplification)
- #78272 (const_evaluatable_checked: deal with unused nodes + div)
- #78318 (TyCtxt: generate single impl block with `slice_interners` macro)
- #78327 (resolve: Relax macro resolution consistency check to account for any errors)
Failed merges:
r? `@ghost`
resolve: Relax macro resolution consistency check to account for any errors
The check was previously omitted only when ambiguity errors or `Res::Err` were encountered, but the "macro-expanded `extern crate` items cannot shadow..." error (at least) can cause same inconsistencies as well.
Fixes https://github.com/rust-lang/rust/issues/78325
Introduce a temporary for discriminant value in MatchBranchSimplification
The optimization introduces additional uses of the discriminant operand, but
does not ensure that it is still valid to evaluate it or that it still
evaluates to the same value.
Evaluate it once at original position, and store the result in a new temporary.
Follow up on #78151. The optimization remains disabled by default.
Closes#78239.
Cleanup constant matching in exhaustiveness checking
This supercedes https://github.com/rust-lang/rust/pull/77390. I made the `Opaque` constructor work.
I have opened two issues https://github.com/rust-lang/rust/issues/78071 and https://github.com/rust-lang/rust/issues/78057 from the discussion we had on the previous PR. They are not regressions nor directly related to the current PR so I thought we'd deal with them separately.
I left a FIXME somewhere because I didn't know how to compare string constants for equality. There might even be some unicode things that need to happen there. In the meantime I preserved previous behavior.
EDIT: I accidentally fixed#78071
Fix const core::panic!(non_literal_str).
Invocations of `core::panic!(x)` where `x` is not a string literal expand to `panic!("{}", x)`, which is not understood by the const panic logic right now. This adds `panic_str` as a lang item, and modifies the const eval implementation to hook into this item as well.
This fixes the issue mentioned here: https://github.com/rust-lang/rust/issues/51999#issuecomment-687604248
r? `@RalfJung`
`@rustbot` modify labels: +A-const-eval
Simplify query proc-macros
The query code generation is split between proc-macros and regular macros in `rustc_middle::ty::query`.
This PR removes unused capabilities of the proc-macros, and tend to use regular macros for the logic.
change the order of type arguments on ControlFlow
This allows ControlFlow<BreakType> which is much more ergonomic for common iterator combinator use cases.
Addresses one component of #75744
Unconditionally capture tokens for attributes.
This allows us to avoid synthesizing tokens in `prepend_attr`, since we
have the original tokens available.
We still need to synthesize tokens when expanding `cfg_attr`,
but this is an unavoidable consequence of the syntax of `cfg_attr` -
the user does not supply the `#` and `[]` tokens that a `cfg_attr`
expands to.
This is based on PR https://github.com/rust-lang/rust/pull/77250 - this PR exposes a bug in the current `collect_tokens` implementation, which is fixed by the rewrite.
Fixes#75982
The direct parent of a module may not be a module
(e.g. `const _: () = { #[path = "foo.rs"] mod foo; };`).
To find the parent of a module for purposes of resolution, we need to
walk up the tree until we hit a module or a crate root.
When the 'early' and 'late' visitors visit an attribute target, they
activate any lint attributes (e.g. `#[allow]`) that apply to it.
This can affect warnings emitted on sibiling attributes. For example,
the following code does not produce an `unused_attributes` for
`#[inline]`, since the sibiling `#[allow(unused_attributes)]` suppressed
the warning.
```rust
trait Foo {
#[allow(unused_attributes)] #[inline] fn first();
#[inline] #[allow(unused_attributes)] fn second();
}
```
However, we do not do this for statements - instead, the lint attributes
only become active when we visit the struct nested inside `StmtKind`
(e.g. `Item`).
Currently, this is difficult to observe due to another issue - the
`HasAttrs` impl for `StmtKind` ignores attributes for `StmtKind::Item`.
As a result, the `unused_doc_comments` lint will never see attributes on
item statements.
This commit makes two interrelated fixes to the handling of inert
(non-proc-macro) attributes on statements:
* The `HasAttr` impl for `StmtKind` now returns attributes for
`StmtKind::Item`, treating it just like every other `StmtKind`
variant. The only place relying on the old behavior was macro
which has been updated to explicitly ignore attributes on item
statements. This allows the `unused_doc_comments` lint to fire for
item statements.
* The `early` and `late` lint visitors now activate lint attributes when
invoking the callback for `Stmt`. This ensures that a lint
attribute (e.g. `#[allow(unused_doc_comments)]`) can be applied to
sibiling attributes on an item statement.
For now, the `unused_doc_comments` lint is explicitly disabled on item
statements, which preserves the current behavior. The exact locatiosn
where this lint should fire are being discussed in PR #78306
If there are two lists of different sizes,
iterating over the smaller list and then
looking up in the larger list is cheaper
than vice versa, because lookups scale
sublinearly.
Make codegen coverage_context optional, and check
Addresses Issue #78286
Libraries compiled with coverage and linked with out enabling coverage
would fail when attempting to add the library's coverage statements to
the codegen coverage context (None).
Now, if coverage statements are encountered while compiling / linking
with `-Z instrument-coverage` disabled, codegen will *not* attempt to
add code regions to a coverage map, and it will not inject the LLVM
instrprof_increment intrinsic calls.
move `visit_predicate` into `TypeVisitor`
Seems easier than dealing with `PredicateVisitor` for me which I needed for object safety checks for `PredicateAtom::ConstEvaluatable`. Is there a reason I am missing for this split?
r? @matthewjasper
improve const infer error
For type inference we probably have to be careful about subtyping and stuff but considering that subtyping shouldn't be relevant for constants I don't really see a reason why we may not want to reuse the const origin here.
r? `@varkor`
Revert "Allow dynamic linking for iOS/tvOS targets."
This reverts PR #73516.
On macOS I compile static libs for iOS, automated using [cargo-mobile](https://github.com/BrainiumLLC/cargo-mobile), which has worked smoothly for the past 2 years. However, upon updating to Rust 1.46.0, I was no longer able to use Rust on iOS. I've bisected this to the PR referenced above.
For most projects tested, apps now immediately crash with a message like this:
```
dyld: Library not loaded: /Users/francesca/Projects/example/target/aarch64-apple-ios/debug/deps/libexample.dylib
Referenced from: /private/var/containers/Bundle/Application/745912AF-A928-465C-B340-872BD1C9F368/example.app/example
Reason: image not found
dyld: launch, loading dependent libraries
DYLD_LIBRARY_PATH=/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/Developer/Library/PrivateFrameworks/GPUTools.framework/libglInterpose.dylib:/usr/lib/libMTLCapture.dylib
```
This can be reproduced by using cargo-mobile to generate a winit example project, and then attempting to run it on an iOS device (`cargo mobile init && cargo apple open`).
In our projects that depend on DisplayLink, the build instead fails with a linker error:
```
= note: Undefined symbols for architecture arm64:
"_CACurrentMediaTime", referenced from:
display_link::ios::run_callback_ios10::hda81197ff46aedbd in libapp-4f0abc1d7684103f.rlib(app-4f0abc1d7684103f.40d4iro0yz1iy487.rcgu.o)
display_link::ios::run_callback_pre_ios10::h91f085da19374320 in libapp-4f0abc1d7684103f.rlib(app-4f0abc1d7684103f.40d4iro0yz1iy487.rcgu.o)
ld: symbol(s) not found for architecture arm64
```
After reverting the change to enable dynamic linking on iOS, everything works the same as it did on Rust 1.45.2 for me.
In the future, would it be possible for me to be pinged when iOS-related PRs are made? I work for a company that intends on using Rust on iOS in production, so I'd gladly provide testing.
cc @aspenluxxxy
Addresses Issue #78286
Libraries compiled with coverage and linked with out enabling coverage
would fail when attempting to add the library's coverage statements to
the codegen coverage context (None).
Now, if coverage statements are encountered while compiling / linking
with `-Z instrument-coverage` disabled, codegen will *not* attempt to
add code regions to a coverage map, and it will not inject the LLVM
instrprof_increment intrinsic calls.
passes: `check_attr` on more targets
This PR modifies `check_attr` so that:
- Enum variants are now checked (some attributes would not have been prohibited on variants previously).
- `check_expr_attributes` and `check_stmt_attributes` are removed as `check_attributes` can perform the same checks. This means that codegen attribute errors aren't shown if there are other errors first (e.g. from other attributes, as shown in `src/test/ui/macros/issue-68060.rs` changes below).
The validation was introduced in 3a63bf0299
without strict validation of functions, e. g. all function types were
allowed.
Now the validation only allows `const fn`s.
Clean up and improve some docs
* compiler docs
* Don't format list as part of a code block
* Clean up some other formatting
* rustdoc book
* Update CommonMark spec version to latest (0.28 -> 0.29)
* Clean up some various wording and formatting
Fix trait solving ICEs
- Selection candidates that are known to be applicable are preferred
over candidates that are not.
- Don't ICE if a projection/object candidate is no longer applicable
(this can happen due to cycles in normalization)
- Normalize supertraits when finding trait object candidates
Closes#77653Closes#77656
r? `@nikomatsakis`
Make fewer types generic over QueryContext
While trying to refactor `rustc_query_system::query::QueryContext` to make it dyn-safe, I noticed some smaller things:
* QueryConfig doesn't need to be generic over QueryContext
* ~~The `kind` field on QueryJobId is unused~~
* Some unnecessary where clauses
* Many types in `job.rs` where generic over `QueryContext` but only needed `QueryContext::Query`.
If handle_cycle_error() could be refactored to not take `error: CycleError<CTX::Query>`, all those bounds could be removed as well.
Changing `find_cycle_in_stack()` in job.rs to not take a `tcx` argument is the only functional change here. Everything else is just updating type signatures. (aka compile-error driven development ^^)
~~Currently there is a weird bug where memory usage suddenly skyrockets when running UI tests. I'll investigate that tomorrow.
A perf run probably won't make sense before that is fixed.~~
EDIT: `kind` actually is used by `Eq`, and re-adding it fixed the memory issue.
Use `DroplessArena` where we know the type doesn't need drop
This PR uses a single `DroplessArena` in resolve instead of three separate `TypedArena`s.
`DroplessArena` checks that the type indeed doesn't need drop, so in case the types change, this will result in visible failures.
Rollup of 10 pull requests
Successful merges:
- #77420 (Unify const-checking structured errors for `&mut` and `&raw mut`)
- #77554 (Support signed integers and `char` in v0 mangling)
- #77976 (Mark inout asm! operands as used in liveness pass)
- #78009 (Haiku: explicitly set CMAKE_SYSTEM_NAME when cross-compiling)
- #78084 (Greatly improve display for small mobile devices screens)
- #78155 (Fix two small issues in compiler/rustc_lint/src/types.rs)
- #78156 (Fixed build failure of `rustfmt`)
- #78172 (Add test case for #77062)
- #78188 (Add tracking issue number for pin_static_ref)
- #78200 (Add `ControlFlow::is_{break,continue}` methods)
Failed merges:
r? `@ghost`
* compiler docs
* Don't format list as part of a code block
* Clean up some other formatting
* rustdoc book
* Update CommonMark spec version to latest (0.28 -> 0.29)
* Clean up some various wording and formatting
Mark inout asm! operands as used in liveness pass
Variables used in `inout` operands in inline assembly (that is, they're used as both input and output to some arbitrary assembly instruction) are being marked as read and written, but are not marked as being used in the RWU table during the liveness pass. This can result in such expressions triggering an unused variable lint warning. This is incorrect behavior- reads without uses are currently only used for compound assignments. We conservatively assume that an `inout` operand is being read and used in the context of the assembly instruction.
Closes#77915
Support signed integers and `char` in v0 mangling
Likely we want more tests, to check the output is correct too: however, I wasn't sure what kind of test we needed, so I just added one similar to that added in https://github.com/rust-lang/rust/pull/77452 for now.
r? @eddyb
This allows us to avoid synthesizing tokens in `prepend_attr`, since we
have the original tokens available.
We still need to synthesize tokens when expanding `cfg_attr`,
but this is an unavoidable consequence of the syntax of `cfg_attr` -
the user does not supply the `#` and `[]` tokens that a `cfg_attr`
expands to.
Calculate visibilities once in resolve
Then use them through a query based on resolver outputs.
Item visibilities were previously calculated in three places - initially in `rustc_resolve`, then in `rustc_privacy` during type privacy checkin, and then in `rustc_metadata` during metadata encoding.
The visibility logic is not entirely trivial, especially for things like constructors or enum variants, and all of it was duplicated.
This PR deduplicates all the visibility calculations, visibilities are determined once during early name resolution and then stored in `ResolverOutputs` and are later available through `tcx` as a query `tcx.visibility(def_id)`.
(This query existed previously, but only worked for other crates.)
Some special cases (e.g. visibilities for closure types, which are needed for type privacy checking) are not processed in resolve, but deferred and performed directly in the query instead.
Cycles in normalization can cause evaluations to change from Unknown to
Err. This means that some selection that were applicable no longer are.
To avoid this:
* Selection candidates that are known to be applicable are prefered
over candidates that are not.
* We don't ICE if a candidate is no longer applicable.
allow_internal_unstable is currently used
to side-step feature gate and stability checks.
While it was originally only meant to be used
only on macros, its use was expanded to
const functions.
This commit prepares stricter checks for the usage of allow_internal_unstable (only on macros)
and introduces the rustc_allow_const_fn_unstable attribute for usage on functions.
See rust-lang/rust#69399
Rewrite `collect_tokens` implementations to use a flattened buffer
Instead of trying to collect tokens at each depth, we 'flatten' the
stream as we go allong, pushing open/close delimiters to our buffer
just like regular tokens. One capturing is complete, we reconstruct a
nested `TokenTree::Delimited` structure, producing a normal
`TokenStream`.
The reconstructed `TokenStream` is not created immediately - instead, it is
produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This
closure stores a clone of the original `TokenCursor`, plus a record of the
number of calls to `next()/next_desugared()`. This is sufficient to reconstruct
the tokenstream seen by the callback without storing any additional state. If
the tokenstream is never used (e.g. when a captured `macro_rules!` argument is
never passed to a proc macro), we never actually create a `TokenStream`.
This implementation has a number of advantages over the previous one:
* It is significantly simpler, with no edge cases around capturing the
start/end of a delimited group.
* It can be easily extended to allow replacing tokens an an arbitrary
'depth' by just using `Vec::splice` at the proper position. This is
important for PR #76130, which requires us to track information about
attributes along with tokens.
* The lazy approach to `TokenStream` construction allows us to easily
parse an AST struct, and then decide after the fact whether we need a
`TokenStream`. This will be useful when we start collecting tokens for
`Attribute` - we can discard the `LazyTokenStream` if the parsed
attribute doesn't need tokens (e.g. is a builtin attribute).
The performance impact seems to be neglibile (see
https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a
small slowdown on a few benchmarks, but it only rises above 1% for incremental
builds, where it represents a larger fraction of the much smaller instruction
count. There a ~1% speedup on a few other incremental benchmarks - my guess is
that the speedups and slowdowns will usually cancel out in practice.
Improve wording of "cannot multiply" type error
For example, if you had this code:
fn foo(x: i32, y: f32) -> f32 {
x * y
}
You would get this error:
error[E0277]: cannot multiply `f32` to `i32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
However, that's not usually how people describe multiplication. People
usually describe multiplication like how the division error words it:
error[E0277]: cannot divide `i32` by `f32`
--> src/lib.rs:2:7
|
2 | x / y
| ^ no implementation for `i32 / f32`
|
= help: the trait `Div<f32>` is not implemented for `i32`
So that's what this change does. It changes this:
error[E0277]: cannot multiply `f32` to `i32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
To this:
error[E0277]: cannot multiply `i32` by `f32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
The optimization introduces additional uses of the discriminant operand, but
does not ensure that it is still valid to evaluate it or that it still
evaluates to the same value.
Evaluate it once at original position, and store the result in a new temporary.
Drop unneeded `mut`
These parameters don't get modified.
Note that `trailing_comment` is pub and gets exported from `rustc_ast_pretty`. Is that considered to be a stable API? If yes, and you want to reserve the right to modify `self` in `trailing_comment` in the future, that hunk would need to be dropped.
Don't update `entries` in `TypedArena` if T does not need drop
As far as I can tell, `entries` is only used when dropping `TypedArenaChunk`s and their contents. It is already ignored there, if T is not `mem::needs_drop`, this PR just skips updating it's value.
You can see `TypedArenaChunk` ignoring the entry count in L71. The reasoning is similar to what you can find in `DroplessArena`.
r? @oli-obk
Improve `skip_binder` usage during FlagComputation
It looks like there was previously a bug around `ExistentialPredicate::Projection` here, don't know how to best trigger that one to add a regression test though.
Trait predicate ambiguities are not always in `Self`
When reporting ambiguities in trait predicates, the compiler incorrectly assumed the ambiguity was always in the type the trait should be implemented on, and never the generic parameters of the trait. This caused silly suggestions for predicates like `<KnownType as Trait<_>>`, such as giving explicit types to completely unrelated variables that happened to be of type `KnownType`.
This also reverts #73027, which worked around this issue in some cases and does not appear to be necessary any more.
fixes#77982fixes#78055
This optimization can result in unsoundness, because it introduces
additional uses of a place holding the discriminant value without
ensuring that it is valid to do so.
Instead of trying to collect tokens at each depth, we 'flatten' the
stream as we go allong, pushing open/close delimiters to our buffer
just like regular tokens. One capturing is complete, we reconstruct a
nested `TokenTree::Delimited` structure, producing a normal
`TokenStream`.
The reconstructed `TokenStream` is not created immediately - instead, it is
produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This
closure stores a clone of the original `TokenCursor`, plus a record of the
number of calls to `next()/next_desugared()`. This is sufficient to reconstruct
the tokenstream seen by the callback without storing any additional state. If
the tokenstream is never used (e.g. when a captured `macro_rules!` argument is
never passed to a proc macro), we never actually create a `TokenStream`.
This implementation has a number of advantages over the previous one:
* It is significantly simpler, with no edge cases around capturing the
start/end of a delimited group.
* It can be easily extended to allow replacing tokens an an arbitrary
'depth' by just using `Vec::splice` at the proper position. This is
important for PR #76130, which requires us to track information about
attributes along with tokens.
* The lazy approach to `TokenStream` construction allows us to easily
parse an AST struct, and then decide after the fact whether we need a
`TokenStream`. This will be useful when we start collecting tokens for
`Attribute` - we can discard the `LazyTokenStream` if the parsed
attribute doesn't need tokens (e.g. is a builtin attribute).
The performance impact seems to be neglibile (see
https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a
small slowdown on a few benchmarks, but it only rises above 1% for incremental
builds, where it represents a larger fraction of the much smaller instruction
count. There a ~1% speedup on a few other incremental benchmarks - my guess is
that the speedups and slowdowns will usually cancel out in practice.
Rollup of 4 pull requests
Successful merges:
- #77877 (Use `try{}` in `try_fold` to decouple iterators in the library from `Try` details)
- #78089 (Fix issue with specifying generic arguments for primitive types)
- #78099 (Add missing punctuation)
- #78103 (Add link to rustdoc book in rustdoc help popup)
Failed merges:
r? `@ghost`
Try to make ObligationForest more efficient
This PR tries to decrease the number of allocations in ObligationForest, as well as moves some cold path code to an uninlined function.
normalize substs while inlining
fixes#68347 or more precisely, this fixes the same ICE in rust analyser as veloren is pinned to a specific nightly
and had an error with the current one.
I didn't look into creating an MVCE here as that seems fairly annoying, will spend a few minutes doing so rn. (failed)
r? `@eddyb` cc `@bjorn3`
Make sure arenas don't allocate bigger than HUGE_PAGE
Right now, arenas allocate based on the size of the last chunk. It is possible for a `grow` call to allocate a chunk that is not a multiple of `PAGE`, and this size is doubled for each subsequent allocation. This means, instead of `HUGE_PAGE`, the biggest page possible is actually unknown.
This change fixes this, and also removes an unnecessary checked multiplication. It is still possible to allocate bigger than `HUGE_PAGE` pages, but this will only happen as many times as absolutely necessary.
Make set_span take mut self
This was a mistake in https://github.com/rust-lang/rust/pull/77614
It's not a _huge_ deal, because backends can always implement this with interior mutability, but it's nice to avoid interior mutability when possible. For context, the `set_source_location` method, called alongside `set_span`, also takes `&mut self`.
r? `@eddyb`
For example, if you had this code:
fn foo(x: i32, y: f32) -> f32 {
x * y
}
You would get this error:
error[E0277]: cannot multiply `f32` to `i32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
However, that's not usually how people describe multiplication. People
usually describe multiplication like how the division error words it:
error[E0277]: cannot divide `i32` by `f32`
--> src/lib.rs:2:7
|
2 | x / y
| ^ no implementation for `i32 / f32`
|
= help: the trait `Div<f32>` is not implemented for `i32`
So that's what this change does. It changes this:
error[E0277]: cannot multiply `f32` to `i32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
To this:
error[E0277]: cannot multiply `i32` by `f32`
--> src/lib.rs:2:7
|
2 | x * y
| ^ no implementation for `i32 * f32`
|
= help: the trait `Mul<f32>` is not implemented for `i32`
Rollup of 7 pull requests
Successful merges:
- #75802 (resolve: Do not put nonexistent crate `meta` into prelude)
- #76607 (Modify executable checking to be more universal)
- #77851 (BTreeMap: refactor Entry out of map.rs into its own file)
- #78043 (Fix grammar in note for orphan-rule error [E0210])
- #78048 (Suggest correct place to add `self` parameter when inside closure)
- #78050 (Small CSS cleanup)
- #78059 (Set `MDBOOK_OUTPUT__HTML__INPUT_404` on linkchecker)
Failed merges:
r? `@ghost`
Suggest correct place to add `self` parameter when inside closure
It would incorrectly suggest adding it as a parameter to the closure instead of the containing function.
[For example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1936bcd1e5f981573386e0cee985c3c0):
```
help: add a `self` receiver parameter to make the associated `fn` a method
|
5 | let _ = || self&self;
| ^^^^^
```
`DiagnosticMetadata.current_function` is only used for these messages so tweaking its behavior should be ok.
Fix grammar in note for orphan-rule error [E0210]
Fixes the grammar in the error note for [E0210] from:
_"= note: implementing a foreign trait is only possible if at least one of the types for which **is it** implemented is local"_
to:
_"= note: implementing a foreign trait is only possible if at least one of the types for which **it is** implemented is local"_
The content of this commit is the result of running the following command at the repository root:
`find . \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/which is it implemented/which it is implemented/g'`
resolve: Do not put nonexistent crate `meta` into prelude
Before the 2018 edition release there was some vague suggestion about adding a crate named `meta` to the standard distribution.
On this basis the name `meta` was "partially reserved" by putting `meta` into extern prelude (this means importing something named `meta` will result in an ambiguity error, for example).
This only caused confusion so far, and two years later there are no specific plans to add such crate.
If some standard crate (named `meta` or not) is added in the future, then cargo will hopefully already have ability to put it into extern prelude explicitly through `Cargo.toml`.
Otherwise, it could be added to extern prelude by the compiler at edition boundary.
Closes https://github.com/rust-lang/rust/issues/73948
Use rebind instead of Binder::bind when possible
These are really only the easy places. I just searched for `Binder::bind` and replaced where it straightforward.
r? `@lcnr`
cc. `@nikomatsakis`
Set .llvmbc and .llvmcmd sections as allocatable
This marks both sections as allocatable rather than excluded, which matches what
clang does with the equivalent `-fembed-bitcode` flag.
Permit uninhabited enums to cast into ints
This essentially reverts part of #6204; it is unclear why that [commit](c0f587de34) was introduced, and I suspect no one remembers.
The changed code was only called from casting checks and appears to not affect any callers of that code (other than permitting this one case).
Fixes#75647.
instrument-coverage: try our best to not ICE
instrument-coverage was ICEing for me on some code, in particular code
that had devirtualized paths from standard library. Instrument coverage
probably has no bussiness dictating which paths are valid and which
aren't so just feed it everything and whatever and let tooling deal with
other stuff.
For example, with this commit we can generate coverage hitpoints for
these interesting paths:
* `/rustc/.../library/core/lib.rs` – non-devirtualized path for libcore
* `/home/.../src/library/core/lib.rs` – devirtualized version of above
* `<inline asm>`, `<anon>` and many similar synthetic paths
Even if those paths somehow get to the instrumentation pass, I'd much
rather get hits for these weird paths and hope some of them work (as
would be the case for devirtualized path to libcore), rather than have
compilation fail entirely.
Deny broken intra-doc links in linkchecker
Since rustdoc isn't warning about these links, check for them manually.
This also fixes the broken links that popped up from the lint.
Suggest minimal subset features in `incomplete_features` lint
This tells users that we have a minimal subset feature of it and they can fix the lint warning without allowing it.
The wording improvement is helpful :)
Fixes#77913
resolve: further improvements to "try using the enum's variant" diagnostic
Follow-up on https://github.com/rust-lang/rust/pull/77341#issuecomment-702738281.
This PR improves the diagnostic modified in #77341 to suggest not only those variants which do not have fields, but those with fields (by suggesting with placeholders). In addition, the wording of the tuple-variant-only case is improved slightly.
I've not made further changes to the tuple-variant-only case (e.g. to only suggest variants with the correct number of fields) because I don't think I have enough information to do so reliably (e.g. in the case where there is an attempt to construct a tuple variant, I have no information on how many fields were provided; and in the case of pattern matching, I only have a slice of spans and would need to check for things like `..` in those spans, which doesn't seem worth it).
r? @estebank
stabilize union with 'ManuallyDrop' fields and 'impl Drop for Union'
As [discussed by @SimonSapin and @withoutboats](https://github.com/rust-lang/rust/issues/55149#issuecomment-634692020), this PR proposes to stabilize parts of the `untagged_union` feature gate:
* It will be possible to have a union with field type `ManuallyDrop<T>` for any `T`.
* While at it I propose we also stabilize `impl Drop for Union`; to my knowledge, there are no open concerns around this feature.
In the RFC discussion, we also talked about allowing `&mut T` as another non-`Copy` non-dropping type, but that felt to me like an overly specific exception so I figured we'd wait if there is actually any use for such a special case.
Some things remain unstable and still require the `untagged_union` feature gate:
* Union with fields that do not drop, are not `Copy`, and are not `ManuallyDrop<_>`. The reason to not stabilize this is to avoid semver concerns around libraries adding `Drop` implementations later. (This is already not fully semver compatible as, to my knowledge, the borrow checker will exploit the non-dropping nature of any type, but it seems prudent to avoid further increasing the amount of trouble adding an `impl Drop` can cause.)
Due to this, quite a few tests still need the `untagged_union` feature, but I think the ones where I could remove the feature flag provide good test coverage for the stable part.
Cc @rust-lang/lang
instrument-coverage was ICEing for me on some code, in particular code
that had devirtualized paths from standard library. Instrument coverage
probably has no bussiness dictating which paths are valid and which
aren't so just feed it everything and whatever and let tooling deal with
other stuff.
For example, with this commit we can generate coverage hitpoints for
these interesting paths:
* `/rustc/.../library/core/lib.rs` – non-devirtualized path for libcore
* `/home/.../src/library/core/lib.rs` – devirtualized version of above
* `<inline asm>`, `<anon>` and many similar synthetic paths
Even if those paths somehow get to the instrumentation pass, I'd much
rather get hits for these weird paths and hope some of them work (as
would be the case for devirtualized path to libcore), rather than have
compilation fail entirely.
Prevent miscompilation in trivial loop {}
Ideally, we would want to handle a broader set of cases to fully fix the
underlying bug here. That is currently relatively expensive at compile and
runtime, so we don't do that for now.
Performance results indicate this is not a major regression, if at all, so it should be safe to land.
cc #28728
Remove arena's dependency on `rustc_data_structures`
`rustc_arena` currently has a dependency on `rustc_data_structures` because of a trivial "don't inline me" function. This PR copies that function and removes the dependency.
Create a single source scope for promoteds
A promoted inherits all scopes from the parent body. At the same time,
almost all statements and terminators inside the promoted body so far
refer only to one of those scopes: the outermost one.
Instead of inheriting all scopes, inherit only a single scope
corresponding to the location of the promoted, making sure that there
are no references to other scopes.
rustc_parse: fix spans on cast and range exprs with attrs
Currently the span for cast and range expressions does not include the span of attributes associated to the lhs which is causing some issues for us in rustfmt.
```rust
fn foo() -> i64 {
#[attr]
1u64 as i64
}
fn bar() -> Range<i32> {
#[attr]
1..2
}
```
This corrects the span for cast and range expressions to fully include the span of child nodes
Stabilize move_ref_pattern
# Implementation
- Initially the rule was added in the run-up to 1.0. The AST-based borrow checker was having difficulty correctly enforcing match expressions that combined ref and move bindings, and so it was decided to simplify forbid the combination out right.
- The move to MIR-based borrow checking made it possible to enforce the rules in a finer-grained level, but we kept the rule in place in an effort to be conservative in our changes.
- In #68376, @Centril lifted the restriction but required a feature-gate.
- This PR removes the feature-gate.
Tracking issue: #68354.
# Description
This PR is to stabilize the feature `move_ref_pattern`, which allows patterns
containing both `by-ref` and `by-move` bindings at the same time.
For example: `Foo(ref x, y)`, where `x` is `by-ref`,
and `y` is `by-move`.
The rules of moving a variable also apply here when moving *part* of a variable,
such as it can't be referenced or moved before.
If this pattern is used, it would result in *partial move*, which means that
part of the variable is moved. The variable that was partially moved from
cannot be used as a whole in this case, only the parts that are still
not moved can be used.
## Documentation
- The reference (rust-lang/reference#881)
- Rust by example (rust-lang/rust-by-example#1377)
## Tests
There are many tests, but I think one of the comperhensive ones:
- [borrowck-move-ref-pattern-pass.rs](85fbf49ce0/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs)
- [borrowck-move-ref-pattern.rs](85fbf49ce0/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs)
# Examples
```rust
#[derive(PartialEq, Eq)]
struct Finished {}
#[derive(PartialEq, Eq)]
struct Processing {
status: ProcessStatus,
}
#[derive(PartialEq, Eq)]
enum ProcessStatus {
One,
Two,
Three,
}
#[derive(PartialEq, Eq)]
enum Status {
Finished(Finished),
Processing(Processing),
}
fn check_result(_url: &str) -> Status {
// fetch status from some server
Status::Processing(Processing {
status: ProcessStatus::One,
})
}
fn wait_for_result(url: &str) -> Finished {
let mut previous_status = None;
loop {
match check_result(url) {
Status::Finished(f) => return f,
Status::Processing(p) => {
match (&mut previous_status, p.status) {
(None, status) => previous_status = Some(status), // first status
(Some(previous), status) if *previous == status => {} // no change, ignore
(Some(previous), status) => { // Now it can be used
// new status
*previous = status;
}
}
}
}
}
}
```
Before, we would have used:
```rust
match (&previous_status, p.status) {
(Some(previous), status) if *previous == status => {} // no change, ignore
(_, status) => {
// new status
previous_status = Some(status);
}
}
```
Demonstrating *partial move*
```rust
fn main() {
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
let person = Person {
name: String::from("Alice"),
age: 20,
};
// `name` is moved out of person, but `age` is referenced
let Person { name, ref age } = person;
println!("The person's age is {}", age);
println!("The person's name is {}", name);
// Error! borrow of partially moved value: `person` partial move occurs
//println!("The person struct is {:?}", person);
// `person` cannot be used but `person.age` can be used as it is not moved
println!("The person's age from person struct is {}", person.age);
}
```
mangling: mangle impl params w/ v0 scheme
This PR modifies v0 symbol mangling to include all generic parameters from impl blocks (not just those used in the self type) - an alternative fix to #75326.
```
original:
_RNCNvXCs4fqI2P2rA04_19impl_param_manglingINtB4_3FooppENtNtNtNtCsfnEnqCNU58Z_4core4iter6traits8iterator8Iterator4next0B4_
// |------------ B4_ ----------------|
// _R (N C (N v (X (C ((s 4fqI2p2rA04_) 19impl_param_mangling)) (I (N t B4_ 3Foo) pp E) (N t (N t (N t (N t (C ((s fnEnqCNU58Z_) 4core)) 4iter) 6traits) 8iterator) 8Iterator)) 4next) 0) B4_
modified:
_RNvXINICs4fqI2P2rA04_11issue_753260pppEINtB5_3FooppENtNtNtNtCsfnEnqCNU58Z_4core4iter6traits8iterator8Iterator4nextB5_
// _R (N v (X (I (N I (C ((s 4fqI2P2rA04_) 11issue_75326)) 0) ppp E) (I (N t B5_ 3Foo) pp E) (N t (N t (N t (N t (C ((s fnEnqCNU58Z_) 4core)) 4iter) 6traits) 8iterator) 8Iterator)) 4next) B5_
// | ^ |
// | | |
// | new impl namespace |
```
~~Submitted as a draft as after some discussion w/ @eddyb, I'm going to do some investigation into (yet more alternative) changes to polymorphization that might remove the necessity for this.~~
r? @eddyb
ensure arguments are included in count mismatch span
The current diagnostic isn't very helpful if the function header spans multiple lines. Lines comprising the function signature may be elided to keep the diagnostic short, but these lines are essential to fixing the error. This is made worse when the function has a body, because the last two lines of the span are then dedicated to showing the end of the body, which is irrelevant.
This PR changes the span to be a multispan made up of the header and the the arguments, ensuring they won't be elided. It also discards the function body from the span.
[Old](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f92d9f81a8c9416f0f04e4e09923b6d4):
```
error[E0061]: this function takes 6 arguments but 1 argument was supplied
--> src/main.rs:18:5
|
1 | / fn bar(
2 | | a: i32,
3 | | b: i32,
4 | | c: i32,
... |
14 | | println!("{}", f);
15 | | }
| |_- defined here
...
18 | bar(1);
| ^^^ - supplied 1 argument
| |
| expected 6 arguments
```
New:
```
error[E0061]: this function takes 6 arguments but 1 argument was supplied
--> $DIR/not-enough-arguments.rs:28:3
|
LL | bar(1);
| ^^^ - supplied 1 argument
| |
| expected 6 arguments
|
note: function defined here
--> $DIR/not-enough-arguments.rs:9:1
|
LL | / fn bar(
LL | | a: i32,
| | ^^^^^^^
LL | | b: i32,
| | ^^^^^^^
LL | | c: i32,
| | ^^^^^^^
LL | | d: i32,
| | ^^^^^^^
LL | | e: i32,
| | ^^^^^^^
LL | | f: i32,
| | ^^^^^^^
LL | | ) {
| |_^
```
This commit improves the tuple struct case added in rust-lang/rust#77341
so that the context is mentioned in more of the message.
Signed-off-by: David Wood <david@davidtw.co>
This commit improves the diagnostic modified in rust-lang/rust#77341 to
suggest not only those variants which do not have fields, but those with
fields (by suggesting with placeholders).
Signed-off-by: David Wood <david@davidtw.co>
Ideally, we would want to handle a broader set of cases to fully fix the
underlying bug here. That is currently relatively expensive at compile and
runtime, so we don't do that for now.
This commit modifies v0 symbol mangling to include all generic
parameters from impl blocks (not just those used in the self type).
Signed-off-by: David Wood <david@davidtw.co>
This commit adjust `#[rustc_symbol_name]` so that it can be applied to
non-monomorphic functions without producing an ICE.
Signed-off-by: David Wood <david@davidtw.co>
The wrapper type led to tons of target.target
across the compiler. Its ptr_width field isn't
required any more, as target_pointer_width
is already present in parsed form.
Preparation for a subsequent change that replaces
rustc_target::config::Config with its wrapped Target.
On its own, this commit breaks the build. I don't like making
build-breaking commits, but in this instance I believe that it
makes review easier, as the "real" changes of this PR can be
seen much more easily.
Result of running:
find compiler/ -type f -exec sed -i -e 's/target\.target\([)\.,; ]\)/target\1/g' {} \;
find compiler/ -type f -exec sed -i -e 's/target\.target$/target/g' {} \;
find compiler/ -type f -exec sed -i -e 's/target.ptr_width/target.pointer_width/g' {} \;
./x.py fmt
Rename target_pointer_width to pointer_width because it is already
member of the Target struct.
The compiler supports only three valid values for target_pointer_width:
16, 32, 64. Thus it can safely be turned into an int.
This means less allocations and clones as well as easier handling of the type.
Also change target_pointer_width to pointer_width.
Preparation for a subsequent type change of
target_pointer_width to an integer together with a rename
to pointer_width.
On its own, this commit breaks the build. I don't like making
build-breaking commits, but in this instance I believe that it
makes review easier, as the "real" changes of this PR can be
seen much more easily.
Result of running:
find compiler/rustc_target/src/spec/ -type f -exec sed -i -e 's/target_pointer_width: "\(.*\)"\..*,/pointer_width: \1,/g' {} \;
Replace tuple of infer vars for upvar_tys with single infer var
This commit allows us to decide the number of captures required after
completing capture ananysis, which is required as part of implementing
RFC-2229.
closes https://github.com/rust-lang/project-rfc-2229/issues/4
r? `@nikomatsakis`
Remove unused code
Rustc has a builtin lint for detecting unused code inside a crate, but when an item is marked `pub`, the code, even if unused inside the entire workspace, is never marked as such. Therefore, I've built [warnalyzer](https://github.com/est31/warnalyzer) to detect unused items in a cross-crate setting.
Closes https://github.com/est31/warnalyzer/issues/2
Logically this first eliminates the innermost match by merging the patterns.
Then, in a second step, turns the newly innermost match into a `matches!` call.
Rollup of 8 pull requests
Successful merges:
- #77765 (Add LLVM flags to limit DWARF version to 2 on BSD)
- #77788 (BTreeMap: fix gdb provider on BTreeMap with ZST keys or values)
- #77795 (Codegen backend interface refactor)
- #77808 (Moved the main `impl` for FnCtxt to its own file.)
- #77817 (Switch rustdoc from `clean::Stability` to `rustc_attr::Stability`)
- #77829 (bootstrap: only use compiler-builtins-c if they exist)
- #77870 (Use intra-doc links for links to module-level docs)
- #77897 (Move `Strip` into a separate rustdoc pass)
Failed merges:
- #77879 (Provide better documentation and help messages for x.py setup)
- #77902 (Include aarch64-pc-windows-msvc in the dist manifests)
r? `@ghost`
Switch rustdoc from `clean::Stability` to `rustc_attr::Stability`
This gives greater type safety and is less work to maintain on the rustdoc end. It also makes rustdoc more consistent with rustc.
Noticed this while working on https://github.com/rust-lang/rust/issues/76998.
- Remove `clean::Stability` in favor of `rustc_attr::Stability`
- Remove `impl Clean for Stability`; it's no longer necessary
r? @GuillaumeGomez
cc @petrochenkov
Moved the main `impl` for FnCtxt to its own file.
Resolves#77085 without breaking the API of the `FnCtxt` struct.
This is a solution to the file length being over 3000 (see issue #60302).
The other solution to the file length is
1. to change the API of this struct by
2. encapulating certain fields of the struct into other structs.
Codegen backend interface refactor
This moves several things away from the codegen backend to rustc_interface. There are a few behavioral changes where previously the incremental cache (incorrectly) wouldn't get finalized, but now it does. See the individual commit messages.
Add LLVM flags to limit DWARF version to 2 on BSD
This has been a thorn in my side for a while, I can finally generate flamegraphs of rust programs on bsd again. This fixes dtrace profiling on freebsd, I think it might help with lldb as well but I can't test that because my current rust-lldb setup is messed up.
I'm limiting the dwarf version to 2 on all bsd's (netbsd/openbsd/freebsd) since it looks like this applies to all of them, but I have only tested on freebsd.
Let me know if there's anything I can improve!
---
Currently on FreeBSD dtrace profiling does not work and shows jumbled/incorrect
symbols in the backtraces. FreeBSD does not support the latest versions of DWARF
in dtrace (and lldb?) yet, and needs to be limited to DWARF2 in the same way as macos.
This adds an is_like_bsd flag since it was missing. NetBSD/OpenBSD/FreeBSD all
match this.
This effectively copies #11864 but targets FreeBSD instead of macos.
Refactor AST pretty-printing to allow skipping insertion of extra parens
Fixes#75734
Makes progress towards #43081
Unblocks PR #76130
When pretty-printing an AST node, we may insert additional parenthesis
to ensure that precedence is properly preserved in code we output.
However, the proc macro implementation relies on comparing a
pretty-printed AST node to the captured `TokenStream`. Inserting extra
parenthesis changes the structure of the reparsed `TokenStream`, making
the comparison fail.
This PR refactors the AST pretty-printing code to allow skipping the
insertion of additional parenthesis. Several freestanding methods are
moved to trait methods on `PrintState`, which keep track of an internal
`insert_extra_parens` flag. This flag is normally `true`, but we expose
a public method which allows pretty-printing a nonterminal with
`insert_extra_parens = false`.
To avoid changing the public interface of `rustc_ast_pretty`, the
freestanding `_to_string` methods are changed to delegate to a
newly-crated `State`. The main pretty-printing code is moved to a new
`state` module to ensure that it does not accidentally call any of these
public helper functions (instead, the internal functions with the same
name should be used).
A promoted inherits all scopes from the parent body. At the same time,
almost all statements and terminators inside the promoted body so far
refer only to one of those scopes: the outermost one.
Instead of inheriting all scopes, inherit only a single scope
corresponding to the location of the promoted, making sure that there
are no references to other scopes.
Replace absolute paths with relative ones
Modern compilers allow reaching external crates
like std or core via relative paths in modules
outside of lib.rs and main.rs.
Replace trivial bool matches with the `matches!` macro
This derives `PartialEq` on one enum (and two structs it contains) to enable the `==` operator for it. If there's some downside to this, I could respin with the `matches!` macro instead.
Certain platforms need to limit the DWARF version emitted (oxs, *bsd). This
change adds a dwarf_version entry to the options that allows a platform to
specify the dwarf version to use. By default this option is none and the default
DWARF version is selected.
Also adds an option for printing Option<u32> json keys
Use tracing spans in rustc_trait_selection
Spans are very helpful when debugging this code. It's also hot enough to make a good benchmark.
r? `@oli-obk`
Mono collector: replace pair of ints with Range
I found the initial PR (#33171) that introduced this piece of code but I didn't find any information about why a tuple was preferred over a `Range<usize>`.
I'm hoping there are no technical reasons to not do this.
Remove unnecessary unsafe block around calls to discriminant_value
Since 63793 the discriminant_value intrinsic is safe to call. Remove
unnecessary unsafe block around calls to this intrinsic in built-in
derive macros.
Use llvm::computeLTOCacheKey to determine post-ThinLTO CGU reuse
During incremental ThinLTO compilation, we attempt to re-use the
optimized (post-ThinLTO) bitcode file for a module if it is 'safe' to do
so.
Up until now, 'safe' has meant that the set of modules that our current
modules imports from/exports to is unchanged from the previous
compilation session. See PR #67020 and PR #71131 for more details.
However, this turns out be insufficient to guarantee that it's safe
to reuse the post-LTO module (i.e. that optimizing the pre-LTO module
would produce the same result). When LLVM optimizes a module during
ThinLTO, it may look at other information from the 'module index', such
as whether a (non-imported!) global variable is used. If this
information changes between compilation runs, we may end up re-using an
optimized module that (for example) had dead-code elimination run on a
function that is now used by another module.
Fortunately, LLVM implements its own ThinLTO module cache, which is used
when ThinLTO is performed by a linker plugin (e.g. when clang is used to
compile a C proect). Using this cache directly would require extensive
refactoring of our code - but fortunately for us, LLVM provides a
function that does exactly what we need.
The function `llvm::computeLTOCacheKey` is used to compute a SHA-1 hash
from all data that might influence the result of ThinLTO on a module.
In addition to the module imports/exports that we manually track, it
also hashes information about global variables (e.g. their liveness)
which might be used during optimization. By using this function, we
shouldn't have to worry about new LLVM passes breaking our module re-use
behavior.
In LLVM, the output of this function forms part of the filename used to
store the post-ThinLTO module. To keep our current filename structure
intact, this PR just writes out the mapping 'CGU name -> Hash' to a
file. To determine if a post-LTO module should be reused, we compare
hashes from the previous session.
This should unblock PR #75199 - by sheer chance, it seems to have hit
this issue due to the particular CGU partitioning and optimization
decisions that end up getting made.
Recognize discriminant reads as no-ops in RemoveNoopLandingPads
The cleanup blocks often contain read of discriminants. Teach
RemoveNoopLandingPads to recognize them as no-ops to remove
additional no-op landing pads.
Fixes#74616
Makes progress towards #43081
Unblocks PR #76130
When pretty-printing an AST node, we may insert additional parenthesis
to ensure that precedence is properly preserved in code we output.
However, the proc macro implementation relies on comparing a
pretty-printed AST node to the captured `TokenStream`. Inserting extra
parenthesis changes the structure of the reparsed `TokenStream`, making
the comparison fail.
This PR refactors the AST pretty-printing code to allow skipping the
insertion of additional parenthesis. Several freestanding methods are
moved to trait methods on `PrintState`, which keep track of an internal
`insert_extra_parens` flag. This flag is normally `true`, but we expose
a public method which allows pretty-printing a nonterminal with
`insert_extra_parens = false`.
To avoid changing the public interface of `rustc_ast_pretty`, the
freestanding `_to_string` methods are changed to delegate to a
newly-crated `State`. The main pretty-printing code is moved to a new
`state` module to ensure that it does not accidentally call any of these
public helper functions (instead, the internal functions with the same
name should be used).
Depending on if upvar_tys inferred or not, we were returning either an
inference variable which later resolves to a tuple or else the upvar tys
themselves
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
This commit allows us to decide the number of captures required after
completing capture ananysis, which is required as part of implementing
RFC-2229.
Co-authored-by: Aman Arora <me@aman-arora.com>
Co-authored-by: Jenny Wills <wills.jenniferg@gmail.com>
Add -Z codegen-backend dylib to deps
When the codegen-backend dylib changes, the program should be rebuilt.
---
Unfortunately I was unable to test this works locally due to running into a TLS issue when running the custom backend, `thread 'rustc' panicked at 'no ImplicitCtxt stored in tls', compiler/rustc_middle/src/ty/context.rs:1750:54`, which seems similar to https://github.com/rust-lang/rust/issues/62717 but has a completely different cause and backtrace.
`@eddyb` said to ping `@Mark-Simulacrum` about what they think about this, so, ping!
This is a solution to the file length being over 3000, something Clippy has a problem with.
The other solution to the file length is
1. to change the API of this struct by
2. encapulating certain fields of the struct into other structs.
Since 63793 the discriminant_value intrinsic is safe to call. Remove
unnecessary unsafe block around calls to this intrinsic in built-in
derive macros.
Provide structured suggestions when finding structs when expecting a trait
When finding an ADT in a trait object definition provide some solutions. Fix#45817.
Given `<Param as Trait>::Assoc: Ty` suggest `Param: Trait<Assoc = Ty>`. Fix#75829.
Allow generic parameters in intra-doc links
Fixes#62834.
---
The contents of the generics will be mostly ignored (except for warning
if fully-qualified syntax is used, which is currently unsupported in
intra-doc links - see issue #74563).
* Allow links like `Vec<T>`, `Result<T, E>`, and `Option<Box<T>>`
* Allow links like `Vec::<T>::new()`
* Warn on
* Unbalanced angle brackets (e.g. `Vec<T` or `Vec<T>>`)
* Missing type to apply generics to (`<T>` or `<Box<T>>`)
* Use of fully-qualified syntax (`<Vec as IntoIterator>::into_iter`)
* Invalid path separator (`Vec:<T>:new`)
* Too many angle brackets (`Vec<<T>>`)
* Empty angle brackets (`Vec<>`)
Note that this implementation *does* allow some constructs that aren't
valid in the actual Rust syntax, for example `Box::<T>new()`. That may
not be supported in rustdoc in the future; it is an implementation
detail.
They were not formatted correctly, so rustdoc was interpreting some
parts as code. Also cleaned up some other query docs that weren't
causing issues, but were formatted incorrectly.
Add TraitDef::find_map_relevant_impl
This PR adds a method to `TraitDef`. While `for_each_relevant_impl` covers the general use case, sometimes it's not necessary to scan through all the relevant implementations, so this PR introduces a new method, `find_map_relevant_impl`. I've also replaced the `for_each_relevant_impl` calls where possible.
I'm hoping for a tiny bit of efficiency gain here and there.
Cleanup of `eat_while()` in lexer
The size of a lexer Token was inflated by the largest `TokenKind` variants `LiteralKind::RawStr` and `RawByteStr`, because
* it used `usize` although `u32` is sufficient in rustc, since crates must be smaller than 4GB,
* and it stored the 20 bytes big `RawStrError` enum for error reporting.
If a raw string is invalid, it now needs to be reparsed to get the `RawStrError` data, but that is a very cold code path.
Technically this breaks other tools that depend on rustc_lexer because they are now also restricted to a max file size of 4GB. But this shouldn't matter in practice, and rustc_lexer isn't stable anyway.
Can I also get a perf run?
Edit: This makes no difference in performance. The PR now only contains a small cleanup.
Add asm! support for mips64
- [x] Updated `src/doc/unstable-book/src/library-features/asm.md`.
- [ ] No vector type support. I don't know much about those types.
cc #76839