These docs were very out of date and misleading. They even said that
they codegen'd the *AST*!
For some reason, the `rustc_codegen_ssa::base` docs were exactly
identical to the `rustc_codegen_llvm::base` docs. They didn't really
make sense, because they had LLVM-specific information even though
`rustc_codegen_ssa` is supposed to be somewhat generic. So I removed
them as they were misleading.
Turn helper method into a closure
`replace_prefix` is currently implemented as a method but has no real relation
to the struct it is implemented on. Turn it into a closure and move it into the
only method from which it is called.
`@rustbot` modify labels +C-cleanup +T-compiler
r? `@lcnr`
rustc_span: Provide a reserved identifier check for a specific edition
while keeping edition evaluation lazy because it may be expensive.
Needed for https://github.com/rust-lang/rust/pull/80226.
Add module-level docs to rustc_middle::ty
I thought it would be nice to point out `Ty` and `TyCtxt` on the module page, and link out to the [rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/ty.html).
docs: Edit rustc_middle::ty::query::on_disk_cache
Expand abbreviations for "incremental compliation".
Also added the word "to" to the description of CacheEncoder.
Reduce memory consumption by sharing the previous dependency graph's
edges with the current graph when it is known to be valid to do so. It
is known to be valid whenever we mark a node green because all of its
dependencies were green. It is *not* known to be valid when we mark a
node green because we re-executed its query and its result was the same
as in the previous compilation session. In that case, the dependency set
might have changed (we don't try to determine whether or not it changed
and whether or not we can share).
Reduce memory consumption by taking advantage of red/green algorithm
properties to share the previous dependency graph's node data with the
current graph instead of storing node data redundantly. Red nodes can
share the `DepNode`, and green nodes can share the `DepNode` and
`Fingerprint`. Edges will be shared when possible in a later change.
Clarify constructor splitting in exhaustiveness checking
I reworked the explanation of the algorithm completely to make it properly account for the various extensions we've added. This includes constructor splitting, which was previously not clearly included in the algorithm. This makes wildcards less magical; I added some detailed examples; and this distinguishes clearly between constructors that only make sense in patterns (like ranges) and those that make sense for values (like `Some`). This reformulation had been floating around in my mind for a while, and I'm quite happy with how it turned out. Let me know how you feel about it.
I also factored out all three cases of splitting (wildcards, ranges and slices) into dedicated structs to encapsulate the complicated bits.
I measured no perf impact but I don't trust my local measurements for refactors since https://github.com/rust-lang/rust/pull/79284.
r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
rustc_query_system: explicitly register reused dep nodes
Register nodes that we've reused from the previous session explicitly
with `OnDiskCache`. Previously, we relied on this happening as a side
effect of accessing the nodes in the `PreviousDepGraph`. For the sake of
performance and avoiding unintended side effects, register explictily.
`replace_prefix` is currently implemented as a method but has no real relation
to the struct it is implemented on. Turn it into a closure and move it into the
only method from which it is called.
Rename `overlapping_patterns` lint
As discussed in https://github.com/rust-lang/rust/issues/65477. I also tweaked a few things along the way.
r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
Reserve necessary space for params in generics_of
Always reserve space for the exact number of generic parameters we need in generics_of. As far as I can see, the default is 0/4 elements based on has_self, and the vector grows on after that.
Acknowledge that `[CONST; N]` is stable
When `const_in_array_repeat_expressions` (RFC 2203) got unstably implemented as part of https://github.com/rust-lang/rust/pull/61749, accidentally, the special case of repeating a *constant* got stabilized immediately. That is why the following code works on stable:
```rust
const EMPTY: Vec<i32> = Vec::new();
pub const fn bar() -> [Vec<i32>; 2] {
[EMPTY; 2]
}
fn main() {
let x = bar();
}
```
In contrast, if we had written `[expr; 2]` for some expression that is not *literally* a constant but could be evaluated at compile-time (e.g. `(EMPTY,).0`), this would have failed.
We could take back this stabilization as it was clearly accidental. However, I propose we instead just officially accept this and stabilize a small subset of RFC 2203, while leaving the more complex case of general expressions that could be evaluated at compile-time unstable. Making that case work well is pretty much blocked on inline `const` expressions (to avoid relying too much on [implicit promotion](https://github.com/rust-lang/const-eval/blob/master/promotion.md)), so it could take a bit until it comes to full fruition. `[CONST; N]` is an uncontroversial subset of this feature that has no semantic ambiguities, does not rely on promotion, and basically provides the full expressive power of RFC 2203 but without the convenience (people have to define constants to repeat them, possibly using associated consts if generics are involved).
Well, I said "no semantic ambiguities", that is only almost true... the one point I am not sure about is `[CONST; 0]`. There are two possible behaviors here: either this is equivalent to `let x = CONST; [x; 0]`, or it is a NOP (if we argue that the constant is never actually instantiated). The difference between the two is that if `CONST` has a destructor, it should run in the former case (but currently doesn't, due to https://github.com/rust-lang/rust/issues/74836); but should not run if it is considered a NOP. For regular `[x; 0]` there seems to be consensus on running drop (there isn't really an alternative); any opinions for the `CONST` special case? Should this instantiate the const only to immediately run its destructors? That seems somewhat silly to me. After all, the `let`-expansion does *not* work in general, for `N > 1`.
Cc `@rust-lang/lang` `@rust-lang/wg-const-eval`
Cc https://github.com/rust-lang/rust/issues/49147
Ran the tidy check
Following the diagnostic guide better
Diagnostic generation is now relegated to its own function in the diagnostics module.
Added tests
Fixed the ui test
Fix pretty printing an AST representing `&(mut ident)`
The PR fixes a misguiding help diagnostic in the parser that I reported in #80186. I discovered that the parsers recovery and reporting logic was correct but the pretty printer produced wrong code for the example. (Details in https://github.com/rust-lang/rust/issues/80186#issuecomment-748498676)
Example:
```rust
#![allow(unused_variables)]
fn main() {
let mut &x = &0;
}
```
The AST fragment
`PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..), Mutability::Not)`
was printed to be `&mut ident`. But this wouldn't round trip through parsing again, because then it would be:
`PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Not), ..), Mutability::Mut)`
Now the pretty-printer prints `&(mut ident)`. Reparsing that code results in the AST fragment
`PatKind::Ref(PatKind::Paren(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..)), Mutability::Not)`
which I think should behave like the original pattern.
Old diagnostic:
```
error: `mut` must be attached to each individual binding
--> src/main.rs:3:9
|
3 | let mut &x = &0;
| ^^^^^^ help: add `mut` to each binding: `&mut x`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`
```
New diagnostic:
```
error: `mut` must be attached to each individual binding
--> src/main.rs:3:9
|
3 | let mut &x = &0;
| ^^^^^^ help: add `mut` to each binding: `&(mut x)`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`
```
Fixes#80186
Minor cleanups in LateResolver
- Avoid calculating hash twice
- Avoid creating a closure in every iteration of a loop
- Reserve space for path in advance
- Some readability changes
Handle desugaring in impl trait bound suggestion
Fixes#79843.
When an associated type of a generic function parameter needs extra bounds, the diagnostics may suggest replacing an `impl Trait` with a named type parameter so that it can be referenced in the where clause. On stable and nightly, the suggestion can be malformed, for instance transforming:
```rust
async fn run(_: &(), foo: impl Foo) -> std::io::Result<()>
```
Into:
```rust
async fn run(_: &, F: Foo(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Where we want something like:
```rust
async fn run<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send
^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
The problem is that the elided lifetime of `&()` is added as a generic parameter when desugaring the async fn; the suggestion code sees this as an existing generic parameter and tries to use its span as an anchor to inject `F` into the parameter list. There doesn't seem to be an entirely principled way to check which generic parameters in the HIR were explicitly named in the source, so this commit changes the heuristics when generating the suggestion to only consider type parameters whose spans are contained within the span of the `Generics` when determining how to insert an additional type parameter into the declaration. (And to be safe it also excludes parameters whose spans are marked as originating from desugaring, although that doesn't seem to handle this elided lifetime.)
Edit rustc_middle docs
Re-word doc comment for rustc_middle::hir::place::Projection.
Also adds:
- Missing end stop punctuation, and
- Documentation links to `rustc_middle::mir::Place`.
When normalizing a projection which results in a cycle, we would
cache the result of `project_type` without the nested obligations
(because they're not needed for inference). This would result in
the nested obligations only being handled once in fulfill, which
would avoid the cycle error.
Fixes#79714, a regresion from #79305 caused by the removal of
`get_paranoid_cache_value_obligation`.
Turn quadratic time on number of impl blocks into linear time
Previously, if you had a lot of inherent impl blocks on a type like:
```Rust
struct Foo;
impl Foo { fn foo_1() {} }
// ...
impl Foo { fn foo_100_000() {} }
```
The compiler would be very slow at processing it, because
an internal algorithm would run in O(n^2), where n is the number
of impl blocks. Now, we add a new algorithm that allocates but
is faster asymptotically.
Comparing rustc nightly with a local build of rustc as of this PR (results in seconds):
| N | real time before | real time after |
| - | - | - |
| 4_000 | 0.57 | 0.46 |
| 8_000 | 1.31 | 0.84 |
| 16_000 | 3.56 | 1.69 |
| 32_000 | 10.60 | 3.73 |
I've tuned up the numbers to make the effect larger than the startup noise of rustc, but the asymptotic difference should hold for smaller n as well.
Note: current state of the PR omits error messages if there are other errors present already. For now, I'm mainly interested in a perf run to study whether this issue is present at all. Please queue one for this PR. Thanks!
Re-word doc comment for rustc_middle::hir::place::Projection.
Also adds:
- Missing end stop punctuation, and
- Documentation links to `rustc_middle::mir::Place`.
`PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..), ..)`
is an AST representing `&(mut ident)`. It was errorneously printed as
`&mut ident` which reparsed into a syntactically different AST.
This affected help diagnostics in the parser.
Make BoundRegion have a kind of BoungRegionKind
Split from #76814
Also includes making `replace_escaping_bound_vars` only return `T`
Going to r? `@lcnr`
Feel free to reassign
or_patterns: implement :pat edition-specific behavior
cc #54883 `@joshtriplett`
This PR implements the edition-specific behavior of `:pat` wrt or-patterns, as determined by the crater runs and T-lang consensus in https://github.com/rust-lang/rust/issues/54883#issuecomment-745509090.
I believe this can unblock stabilization of or_patterns.
r? `@petrochenkov`
const_evaluatable_checked: fix occurs check
fixes#79615
this is kind of a hack because we use `TypeRelation` for both the `Generalizer` and the `ConstInferUnifier` but i am not sure if there is a useful way to disentangle this without unnecessarily duplicating some code.
The error in the added test is kind of unavoidable until we erase the unused substs of `ConstKind::Unevaluated`. We talked a bit about this in the cg lazy norm meeting (https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/lazy_normalization_consts)
Improve and fix diagnostics of exhaustiveness checking
Primarily, this fixes https://github.com/rust-lang/rust/issues/56379. This also fixes incorrect interactions between or-patterns and slice patterns that I discovered while working on #56379. Those two examples show the incorrect diagnostics:
```rust
match &[][..] {
[true] => {}
[true // detected as unreachable but that's not true
| false, ..] => {}
_ => {}
}
match (true, None) {
(true, Some(_)) => {}
(false, Some(true)) => {}
(true | false, None | Some(true // should be detected as unreachable
| false)) => {}
}
```
I did not measure any perf impact. However, I suspect that [`616ba9f`](616ba9f9f7) should have a negative impact on large or-patterns. I'll see what the perf run says; I have optimization ideas up my sleeve if needed.
EDIT: I initially had a noticeable perf impact that I thought unavoidable. I then proceeded to avoid it x)
r? `@varkor`
`@rustbot` label +A-exhaustiveness-checking
Stabilize or_insert_with_key
Stabilizes the `or_insert_with_key` feature from https://github.com/rust-lang/rust/issues/71024. This allows inserting key-derived values when a `HashMap`/`BTreeMap` entry is vacant.
The difference between this and `.or_insert_with(|| ... )` is that this provides a reference to the key to the closure after it is moved with `.entry(key_being_moved)`, avoiding the need to copy or clone the key.
passes: prohibit invalid attrs on generic params
Fixes#78957.
This PR modifies the `check_attr` pass so that attribute placement on generic parameters is checked for validity.
r? `@lcnr`
Register nodes that we've reused from the previous session explicitly
with `OnDiskCache`. Previously, we relied on this happening as a side
effect of accessing the nodes in the `PreviousDepGraph`. For the sake of
performance and avoiding unintended side effects, register explictily.
This is elegant but a bit of a perf gamble. That said, or-patterns
rarely have many branches and it's easy to optimize or revert if we ever
need to. In the meantime simpler code is worth it.
Stop using intermediate macros in definition of symbols
Currently, the rustc_macros::symbols macro generates two
`macro_rules!` macros as its output. These two macros are
used in rustc_span/src/symbol.rs.
This means that each Symbol that we define is represented
in the AST of rustc_symbols twice: once in the definition
of the `define_symbols!` macro (similarly for the
`keywords! macro), and once in the rustc_span::symbols
definition.
That would be OK if there were only a handful of symbols,
but currently we define over 1100 symbols. The definition
of the `define_symbols!` macro contains the expanded definition
of each symbol, so that's a lot of AST storage wasted on a
macro that is used exactly once.
This commit removes the `define_symbols` macro, and simply
allows the proc macro to directly generate the
`rustc_symbols::symbol::sym` module.
The benefit is mainly in reducing memory wasted during
compilation of rustc itself. It should also reduce memory used
by Rust Analyzer.
This commit also reduces the size of the AST for symbol
definitions, by moving two `#[allow(...)]` attributes from
the symbol constants to the `sym` module. This eliminates 2200+
attribute nodes.
This commit also eliminates the need for the `digits_array`
constant. There's no need to store an array of Symbol values
for digits. We can simply define a constant of the base value,
and add to that base value.
I left the `sym::integer` function in rustc_span/src/symbol.rs
instead of moving it into rustc_macros/src/symbols.rs for two
reasons. First, because it's human-written code; it doesn't need
to be generated by the proc-macro. Second, because I didn't want
the `#[allow(...)]` attributes that I moved to the `sym` module
scope to apply to this function. The `sym` module re-exports the
`integer` function from its parent module.
Rollup of 5 pull requests
Successful merges:
- #78164 (Prefer regions with an `external_name` in `approx_universal_upper_bound`)
- #80003 (Fix overflow when converting ZST Vec to VecDeque)
- #80023 (Enhance error message when misspelled label to value in break expression)
- #80046 (Add more documentation to `Diagnostic` and `DiagnosticBuilder`)
- #80109 (Remove redundant and unreliable coverage test results)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Prefer regions with an `external_name` in `approx_universal_upper_bound`
Fixes#75785
When displaying a MIR borrowcheck error, we may need to find an upper
bound for a region, which gives us a region to point to in the error
message. However, a region might outlive multiple distinct universal
regions, in which case the only upper bound is 'static
To try to display a meaningful error message, we compute an
'approximate' upper bound by picking one of the universal regions.
Currently, we pick the region with the lowest index - however, this
caused us to produce a suboptimal error message in issue #75785
This PR `approx_universal_upper_bound` to prefer regions with an
`external_name`. This causes us to prefer regions from function
arguments/upvars, which seems to lead to a nicer error message in some
cases.
Currently, the rustc_macros::symbols macro generates two
`macro_rules!` macros as its output. These two macros are
used in rustc_span/src/symbol.rs.
This means that each Symbol that we define is represented
in the AST of rustc_symbols twice: once in the definition
of the `define_symbols!` macro (similarly for the
`keywords! macro), and once in the rustc_span::symbols
definition.
That would be OK if there were only a handful of symbols,
but currently we define over 1100 symbols. The definition
of the `define_symbols!` macro contains the expanded definition
of each symbol, so that's a lot of AST storage wasted on a
macro that is used exactly once.
This commit removes the `define_symbols` macro, and simply
allows the proc macro to directly generate the
`rustc_symbols::symbol::sym` module.
The benefit is mainly in reducing memory wasted during
compilation of rustc itself. It should also reduce memory used
by Rust Analyzer.
This commit also reduces the size of the AST for symbol
definitions, by moving two `#[allow(...)]` attributes from
the symbol constants to the `sym` module. This eliminates 2200+
attribute nodes.
This commit also eliminates the need for the `digits_array`
constant. There's no need to store an array of Symbol values
for digits. We can simply define a constant of the base value,
and add to that base value.
Fixes#75785
When displaying a MIR borrowcheck error, we may need to find an upper
bound for a region, which gives us a region to point to in the error
message. However, a region might outlive multiple distinct universal
regions, in which case the only upper bound is 'static
To try to display a meaningful error message, we compute an
'approximate' upper bound by picking one of the universal regions.
Currently, we pick the region with the lowest index - however, this
caused us to produce a suboptimal error message in issue #75785
This PR `approx_universal_upper_bound` to prefer regions with an
`external_name`. This causes us to prefer regions from function
arguments/upvars, which seems to lead to a nicer error message in some
cases.
Move binder for dyn to each list item
This essentially changes `ty::Binder<&'tcx List<ExistentialTraitRef>>` to `&'tcx List<ty::Binder<ExistentialTraitRef>>`.
This is a first step in moving the `dyn Trait` representation closer to Chalk, which we've talked about in `@rust-lang/wg-traits.`
r? `@nikomatsakis`