Make WhereClause optional in generics - #160680
Conversation
|
The parser was modified, potentially altering the grammar of (stable) Rust cc @fmease Changes to the size of AST and/or HIR nodes. cc @nnethercote
cc @rust-lang/clippy |
Many items don't have generics, and many generics don't have where
clauses. `WhereClause` is 24 bytes: a `bool`, a `ThinVec` of predicates,
and a `Span`. Reduce that to 8 bytes by making it an `Option` wrapper.
The `has_where_token` case gets encoded in the `Option`: a
`WhereClause(None)` has no `where` token, while a
`WhereClause(Some(...))` with a non-empty span has one (even if the
predicate list is empty, like `where {}`).
This reduces the size of several key AST structures:
- `Impl` goes from 80 bytes to 64, making it one cache line.
- `Item` goes from 144 bytes to 128, making it two cache lines and
bringing it below the threshold where copies don't use `memcpy`.
- `ItemKind` goes from 88 bytes to 72, tantalizingly close to 64.
- `Fn` goes from 192 bytes to 176.
- `Generics` goes from 40 bytes to 24.
rustc_builtin_macros now collects predicates and creates a `WhereClause`
at the end.
rustc_ast_lowering now needs another way to get the span for inserting a
`where` clause if there isn't already one. Add that as a parameter to
`lower_generics`, and pass it in from the various callers, determined
from other spans we already have. This requires a little care, but
allows us to avoid an allocation for common cases of items that don't
have `where` clauses.
As an exception, we do capture the insertion span for `Impl` block
`where` clauses, because reconstructing those hits a corner case with
spans partially coming coming from macros; in that case, the logic to
find the `def_span` needs the where-clause span, so we ensure we have it
in that case. We also record an insertion span for synthetic derives,
pointing to the original structure definition.
Relevant `-Zinput-stats` diff for compiling the huge `aws-sdk-ec2` crate:
```diff
-ast-stats Item 14_353_632 ( 4.4%) 99_678 144
-ast-stats - ExternCrate 144 ( 0.0%) 1
-ast-stats - MacroDef 144 ( 0.0%) 1
-ast-stats - Trait 576 ( 0.0%) 4
-ast-stats - TyAlias 12_960 ( 0.0%) 90
-ast-stats - Const 114_768 ( 0.0%) 797
-ast-stats - Enum 180_432 ( 0.1%) 1_253
-ast-stats - Static 453_312 ( 0.1%) 3_148
-ast-stats - Fn 976_320 ( 0.3%) 6_780
-ast-stats - Mod 1_241_136 ( 0.4%) 8_619
-ast-stats - Struct 1_351_152 ( 0.4%) 9_383
-ast-stats - Use 1_488_672 ( 0.5%) 10_338
-ast-stats - Impl 8_534_016 ( 2.6%) 59_264
+ast-stats Item 12_758_784 ( 4.0%) 99_678 128
+ast-stats - ExternCrate 128 ( 0.0%) 1
+ast-stats - MacroDef 128 ( 0.0%) 1
+ast-stats - Trait 512 ( 0.0%) 4
+ast-stats - TyAlias 11_520 ( 0.0%) 90
+ast-stats - Const 102_016 ( 0.0%) 797
+ast-stats - Enum 160_384 ( 0.0%) 1_253
+ast-stats - Static 402_944 ( 0.1%) 3_148
+ast-stats - Fn 867_840 ( 0.3%) 6_780
+ast-stats - Mod 1_103_232 ( 0.3%) 8_619
+ast-stats - Struct 1_201_024 ( 0.4%) 9_383
+ast-stats - Use 1_323_264 ( 0.4%) 10_338
+ast-stats - Impl 7_585_792 ( 2.4%) 59_264
[...]
-ast-stats Total 322_653_552 7_596_184
+ast-stats Total 321_058_704 7_596_184
```
85f566c to
88efab5
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
cc @rust-lang/rustfmt |
|
I've now fixed up clippy and rustfmt, which needed updating for the new |
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Make `WhereClause` optional in generics
This comment has been minimized.
This comment has been minimized.
|
I'll review later, one comment on the description:
|
|
Finished benchmarking commit (34031bf): comparison URL. Overall result: ❌✅ regressions and improvements - please read:Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. Next, please: If you can, justify the regressions found in this try perf run in writing along with @bors rollup=never rustc-perf Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary 0.1%, secondary -0.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 3.0%, secondary 0.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 461.168s -> 459.151s (-0.44%) |
Many items don't have generics, and many generics don't have where
clauses.
WhereClauseis 24 bytes: abool, aThinVecof predicates,and a
Span. Reduce that to 8 bytes by making it anOptionwrapper.The
has_where_tokencase gets encoded in theOption: aWhereClause(None)has nowheretoken, while aWhereClause(Some(...))with a non-empty span has one (even if thepredicate list is empty, like
where {}).This reduces the size of several key AST structures:
Implgoes from 80 bytes to 64, making it one cache line.Itemgoes from 144 bytes to 128, making it two cache lines andbringing it below the threshold where copies don't use
memcpy.ItemKindgoes from 88 bytes to 72, helping everything it's embedded in.Fngoes from 192 bytes to 176.Genericsgoes from 40 bytes to 24.rustc_builtin_macros now collects predicates and creates a
WhereClauseat the end.
rustc_ast_lowering now needs another way to get the span for inserting a
whereclause if there isn't already one. Add that as a parameter tolower_generics, and pass it in from the various callers, determinedfrom other spans we already have. This requires a little care, but
allows us to avoid an allocation for common cases of items that don't
have
whereclauses.As an exception, we do capture the insertion span for
Implblockwhereclauses, because reconstructing those hits a corner case withspans partially coming coming from macros; in that case, the logic to
find the
def_spanneeds the where-clause span, so we ensure we have itin that case. We also record an insertion span for synthetic derives,
pointing to the original structure definition.
Relevant
-Zinput-statsdiff for compiling the hugeaws-sdk-ec2crate:r? nnethercote