| Age | Commit message (Collapse) | Author | Lines |
|
This is an annoying gotcha with the projection cache's handling of
nested obligations.
Nested projection obligations enter the issue in this case:
```
DEBUG:rustc::traits::project: AssociatedTypeNormalizer: depth=3
normalized
<std::iter::Map<std::ops::Range<i32>,
[closure@not-a-recursion-error.rs:5:30: 5:53]> as
std::iter::IntoIterator>::Item to _#7t with 12 add'l obligations
```
Here the normalization result is the result of the nested impl
`<[closure@not-a-recursion-error.rs:5:30: 5:53] as FnMut(i32)>::Output`,
which is an additional obligation that is a part of "add'l obligations".
By itself, this is proper behaviour - the additional obligation is
returned, and the RFC 447 rules ensure that it is processed before the
output `#_7t` is used in any way.
However, the projection cache breaks this - it caches the
`<std::iter::Map<std::ops::Range<i32>,[closure@not-a-recursion-error.rs:5:30:
5:53]> as std::iter::IntoIterator>::Item = #_7t` resolution. Now
everybody else that attempts to look up the projection will just get
`#_7t` *without* any additional obligations. This obviously causes all
sorts of trouble (here a spurious `EvaluatedToAmbig` results in
specializations not being discarded
[here](https://github.com/rust-lang/rust/blob/9ca50bd4d50b55456e88a8c3ad8fcc9798f57522/src/librustc/traits/select.rs#L1705)).
The compiler works even with this projection cache gotcha because in most
cases during "one-pass evaluation". we tend to process obligations in LIFO
order - after an obligation is added to the cache, we process its nested
obligations before we do anything else (and if we have a cycle, we handle
it specifically) - which makes sure the inference variables are resolved
before they are used.
That "LIFO" order That was not done when projecting out of a closure, so
let's just fix that for the time being.
Fixes #38033.
|
|
Stabilize `..` in tuple (struct) patterns
I'd like to nominate `..` in tuple and tuple struct patterns for stabilization.
This feature is a relatively small extension to existing stable functionality and doesn't have known blockers.
The feature first appeared in Rust 1.10 6 months ago.
An example of use: https://github.com/rust-lang/rust/pull/36203
Closes https://github.com/rust-lang/rust/issues/33627
r? @nikomatsakis
|
|
|
|
Add `-Z hir-stats` for collecting statistics on HIR and AST
The data collected will be printed to the commandline and looks like the following:
```
// stats for libcore
PRE EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
TypeBinding 2_280 57 40
Mod 3_560 89 40
PathListItem 6_516 181 36
Variant 7_872 82 96
LifetimeDef 21_280 380 56
StructField 22_880 260 88
Lifetime 23_800 1_190 20
Local 30_192 629 48
ForeignItem 31_504 179 176
Arm 42_880 670 64
Mac 46_960 587 80
FnDecl 57_792 1_204 48
TraitItem 69_504 362 192
TyParamBound 98_280 945 104
Block 108_384 2_258 48
Stmt 144_720 3_618 40
ImplItem 230_272 1_028 224
Item 467_456 1_826 256
Pat 517_776 4_623 112
Attribute 745_680 15_535 48
Ty 1_114_848 9_954 112
PathSegment 1_218_528 16_924 72
Expr 3_082_408 20_279 152
----------------------------------------------------------------
Total 8_095_372
POST EXPANSION AST STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
MacroDef 1_056 12 88
Mod 3_400 85 40
TypeBinding 4_280 107 40
PathListItem 6_516 181 36
Variant 7_872 82 96
StructField 24_904 283 88
ForeignItem 31_504 179 176
TraitItem 69_504 362 192
Local 85_008 1_771 48
Arm 100_288 1_567 64
Lifetime 123_980 6_199 20
LifetimeDef 126_728 2_263 56
TyParamBound 297_128 2_857 104
FnDecl 305_856 6_372 48
Block 481_104 10_023 48
Stmt 535_120 13_378 40
Item 1_469_952 5_742 256
Attribute 1_629_840 33_955 48
ImplItem 1_732_864 7_736 224
Pat 2_360_176 21_073 112
PathSegment 5_888_448 81_784 72
Ty 6_237_168 55_689 112
Expr 12_013_320 79_035 152
----------------------------------------------------------------
Total 33_536_016
HIR STATS
Name Accumulated Size Count Item Size
----------------------------------------------------------------
MacroDef 864 12 72
Mod 2_720 85 32
TypeBinding 3_424 107 32
PathListItem 5_068 181 28
Variant 6_560 82 80
StructField 20_376 283 72
ForeignItem 27_208 179 152
WherePredicate 43_776 684 64
TraitItem 52_128 362 144
Decl 68_992 2_156 32
Local 89_184 1_858 48
Arm 94_368 1_966 48
LifetimeDef 108_624 2_263 48
Lifetime 123_980 6_199 20
Stmt 168_000 4_200 40
TyParamBound 251_416 2_857 88
FnDecl 254_880 6_372 40
Block 583_968 12_166 48
Item 1_240_272 5_742 216
ImplItem 1_361_536 7_736 176
Attribute 1_620_480 33_760 48
Pat 2_073_120 21_595 96
Path 2_385_856 74_558 32
Ty 4_455_040 55_688 80
PathSegment 5_587_904 87_311 64
Expr 7_588_992 79_052 96
----------------------------------------------------------------
Total 28_218_736
```
|
|
Shrink `hir::Expr` slightly
r? @eddyb
|
|
macros: improve expansion performance
This PR fixes that regression, further improves performance on recursive, `tt`-heavy workloads, and makes a variety of other improvements to parsing and expansion performance.
Expansion performance improvements:
| Test case | Run-time | Memory usage |
| -------------- | -------- | ------------ |
| libsyntax | 8% | 10% |
| librustc | 15% | 6% |
| librustc_trans | 30% | 6% |
| #37074 | 20% | 15% |
| #34630 | 40% | 8% |
r? @eddyb
|
|
[5/n] rustc: record the target type of every adjustment.
_This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37404) | [next](https://github.com/rust-lang/rust/pull/37412)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments._
<hr>
The first commit rearranges `tcx.tables` so that all users go through `tcx.tables()`. This in preparation for per-body `Tables` where they will be requested for a specific `DefId`. Included to minimize churn.
The rest of the changes focus on adjustments, there are some renamings, but the main addition is the target type, always available in all cases (as opposed to just for unsizing where it was previously needed).
Possibly the most significant effect of this change is that figuring out the final type of an expression is now _always_ just one successful `HashMap` lookup (either the adjustment or, if that doesn't exist, the node type).
|
|
|
|
detect extra region requirements in impls
The current "compare method" check fails to check for the "region obligations" that accrue in the fulfillment context. This branch switches that code to create a `FnCtxt` so that it can invoke the regionck code. Previous crater runs (I haven't done one with the latest tip) have found some small number of affected crates, so I went ahead and introduced a warning cycle. I will kick off a crater run with this branch shortly.
This is a [breaking-change] because previously unsound code was accepted. The crater runs also revealed some cases where legitimate code was no longer type-checking, so the branch contains one additional (but orthogonal) change. It improves the elaborator so that we elaborate region requirements more thoroughly. In particular, if we know that `&'a T: 'b`, we now deduce that `T: 'b` and `'a: 'b`.
I invested a certain amount of effort in getting a good error message. The error message looks like this:
```
error[E0276]: impl has stricter requirements than trait
--> traits-elaborate-projection-region.rs:33:5
|
21 | fn foo() where T: 'a;
| --------------------- definition of `foo` from trait
...
33 | fn foo() where U: 'a { }
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
note: lint level defined here
--> traits-elaborate-projection-region.rs:12:9
|
12 | #![deny(extra_requirement_in_impl)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
```
Obviously the warning only prints if this is a _new_ error (that resulted from the bugfix). But all existing errors that fit this description are updated to follow the general template. In order to get the lint to preserve the span-labels and the error code, I separate out the core `Diagnostic` type (which encapsulates the error code, message, span, and children) from the `DiagnosticBuilder` (which layers on a `Handler` that can be used to report errors). I also extended `add_lint` with an alternative `add_lint_diagnostic` that takes in a full diagnostic (cc @jonathandturner for those changes). This doesn't feel ideal but feels like it's moving in the right direction =).
r? @pnkfelix
cc @arielb1
Fixes #18937
|
|
A way to remove otherwise unused locals from MIR
There is a certain amount of desire for a pass which cleans up the provably unused variables (no assignments or reads). There has been an implementation of such pass by @scottcarr, and another (two!) implementations by me in my own dataflow efforts.
PR like https://github.com/rust-lang/rust/pull/35916 proves that this pass is useful even on its own, which is why I cherry-picked it out from my dataflow effort.
@nikomatsakis previously expressed concerns over this pass not seeming to be very cheap to run and therefore unsuitable for regular cleanup duties. Turns out, regular cleanup of local declarations is not at all necessary, at least now, because majority of passes simply do not (or should not) care about them. That’s why it is viable to only run this pass once (perhaps a few more times in the future?) per function, right before translation.
r? @eddyb or @nikomatsakis
|
|
On 64-bit platforms this reduces the size of `Expr_` from 64 bytes to
56 bytes, and reduces the size of `Expr` from 88 bytes to 80 bytes.
|
|
On 64-bit platforms this reduces the size of `Expr` from 96 bytes to 88
bytes.
|
|
|
|
Replaces the hack where a similar thing is done within trans.
|
|
|
|
This seems better because I want to avoid the situation where unresolved
inference variables make it into the environment. On the other hand, I
am not 100% sure that this is correct. My assumption was that the WF
check should ensure that this normalization can succeed. But it occurs
to me that the WF checks may need to make use of the `specializes`
predicate themselves, and hence we may have a kind of cycle here (this
is a bigger problem with spec in any case that we need to resolve).
On the other hand, this should just cause extra errors I think, so it
seems like a safe thing to attempt. Certainly all tests pass.
|
|
The `specializes()` function was trying to normalize the impl trait in
an empty environment. This could lead to inexplicable failures.
|
|
Rollup of 7 pull requests
- Successful merges: #36849, #37059, #37296, #37316, #37484, #37485, #37495
- Failed merges:
|
|
|
|
|
|
Fix ICE when printing closures, and other similar types
Follow-up of https://github.com/rust-lang/rust/pull/37459, further fixes those problems.
Potentially actually fixes #36622, though @eddyb may want to not let that close if the rename of RUST_LOG is deemed part of that issue.
Potentially should be beta-nominated as well?
r? @eddyb
|
|
|
|
- correct indentation
- rename `from_cause` to `from_obligation_cause`
- break up `compare_impl_method` into fns
- delete some blank lines and correct comment
|
|
This helps us to preserve the existing errors.
|
|
|
|
|
|
|
|
|
|
|
|
For now, this type just replaces a tuple, but it will eventually grow
the ability to carry more structured information.
|
|
|
|
|
|
|
|
Remove TypeOrigin::RangeExpression
This variant became unused in #30884.
|
|
Most of the Rust community agrees that the vec! macro is clearer when
called using square brackets [] instead of regular brackets (). Most of
these ocurrences are from before macros allowed using different types of
brackets.
There is one left unchanged in a pretty-print test, as the pretty
printer still wants it to have regular brackets.
|
|
r=nikomatsakis
introing one-time diagnostics: only emit "lint level defined here" once
This is a revised resubmission of PR #34084 (which was closed due to inactivity on account of time constraints on the author's part).
---
We introduce a new `one_time_diagnostics` field on
`rustc::session::Session` to hold a hashset of diagnostic messages we've
set once but don't want to see again (as uniquified by span and message
text), "lint level defined here" being the motivating example dealt with
here.
This is in the matter of #24690.
---
r? @nikomatsakis
|
|
Replace all uses of SHA-256 with BLAKE2b.
Removes the SHA-256 implementation and replaces all uses of it with BLAKE2b, which we already use for debuginfo type guids and incremental compilation hashes. It doesn't make much sense to have two different cryptographic hash implementations in the compiler and Blake has a few advantages over SHA-2 (computationally less expensive, hashes of up to 512 bits).
|
|
Do not clone Mir unnecessarily
r? @eddyb
|
|
|
|
|
|
|
|
Fix ICE when attempting to print closure generics
Fixes #36622.
r? @eddyb or @arielb1
|
|
Shrink Expr_::ExprInlineAsm.
On 64-bit this reduces the size of `Expr_` from 144 to 64 bytes, and
reduces the size of `Expr` from 176 to 96 bytes.
For the workload in #36799 this reduces the RSS for the "lowering ast -> hir" phase and all subsequent phases by 50 MiB, which reduces the peak RSS for that workload by about 1%. Not huge, but it's a very easy improvement.
r? @eddyb
|
|
|
|
Move `CrateConfig` from `Crate` to `ParseSess`
This is a syntax-[breaking-change]. Most breakage can be fixed by removing a `CrateConfig` argument.
r? @eddyb
|
|
[2/n] rustc_metadata: move is_extern_item to trans.
*This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37400) | [next](https://github.com/rust-lang/rust/pull/37402)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments.*
<hr>
Minor cleanup missed by #36551: `is_extern_item` is one of, if not the only `CrateStore` method who takes a `TyCtxt` but doesn't produce something cached in it, and such methods are going away.
|
|
[1/n] Move the MIR map into the type context.
*This is part of a series ([prev]() | [next](https://github.com/rust-lang/rust/pull/37401)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments.*
<hr>
The first commit reorganizes the `rustc::mir` module to contain the MIR types directly without an extraneous `repr` module which serves no practical purpose but is rather an eyesore.
The second commit performs the actual move of the MIR map into the type context, for the purposes of future integration with requesting analysis/lowering by-products through `TyCtxt`.
Local `Mir` bodies need to be mutated by passes (hence `RefCell`), and at least one pass (`qualify_consts`) needs simultaneous access to multiple `Mir` bodies (hence arena-allocation).
`Mir` bodies loaded from other crates appear as if immutably borrowed (by `.borrow()`-ing one `Ref` and subsequently "leaking" it) to avoid, at least dynamically, *any* possibility of their local mutation.
One caveat is that lint passes can now snoop at the MIR (helpful) or even mutate it (dangerous).
However, lints are unstable anyway and we can find a way to deal with this in due time.
Future work will result in a tighter API, potentially hiding mutation *completely* outside of MIR passes.
|
|
Prohibit patterns in trait methods without bodies
They are not properly type checked
```rust
trait Tr {
fn f(&a: u8); // <- This compiles
}
```
, mostly rejected by the parser already and generally don't make much sense.
This PR is kind of a missing part of https://github.com/rust-lang/rust/pull/35015.
Given the [statistics from crater](https://github.com/rust-lang/rust/pull/37378#issuecomment-256154994), the effect of this PR is mostly equivalent to improving `unused_mut` lint.
cc https://github.com/rust-lang/rust/issues/35078#issuecomment-255707355 https://github.com/rust-lang/rust/pull/35015 https://github.com/rust-lang/rfcs/pull/1685 https://github.com/rust-lang/rust/issues/35203
r? @eddyb
|
|
|
|
|