-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Refactor TraitObject to Slice<ExistentialPredicate> #37965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor TraitObject to Slice<ExistentialPredicate> #37965
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo comments. cc @nikomatsakis about Binder
discipline.
src/librustc/traits/coherence.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need ref
in positions by this, the match is on an rvalue anyway.
src/librustc/traits/coherence.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same extraneous ref
. It might be worth using map_or
in cases like this, I'm not sure.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an if-else chain.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same extraneous ref
.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same extraneous ref
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same odd reg
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be written using map_or
.
src/librustc_typeck/collect.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this partitioning should even exist until a TyDynamic
is created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be wrapped in an if let Some
instead of using .unwrap()
.
src/librustc/ty/sty.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't .unwrap()
.
b475ea0
to
2c1ec2f
Compare
☔ The latest upstream changes (presumably #37890) made this pull request unmergeable. Please resolve the merge conflicts. |
3c63d7c
to
8d76e7e
Compare
@eddyb Ready for the crater run, I think, but might want to review before? |
90d69cd
to
72f54e0
Compare
src/librustc_trans/trans_item.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't allocate.
src/librustc_typeck/check/wfcheck.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace with require_lang_item
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reg
fdb5b7b
to
c0eca6a
Compare
Expanded the description with discussion and elaboration on what this PR does. @eddyb Let me know what parts of that should be transferred into documentation comments in the code. |
c0eca6a
to
eb7bb54
Compare
Squashed the remaining fix commits. r? @eddyb |
Started crater run. |
src/librustc/infer/mod.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy_trait
or copy_def_id
.
src/librustc/traits/coherence.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (and other places) could use map_or
for brevity.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is unnecessary/misleading.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessary in this PR, but these push
calls could be replaced with collecting an iterator to a Vec
.
src/librustc/ty/context.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this to mk_dynamic
?
src/librustc_typeck/astconv.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use if let Some
here.
src/librustc_typeck/check/wfcheck.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this check necessary anymore? AFAIK trait_has_default_impl
returns true for Send
and Sync
.
src/librustc_typeck/collect.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to .clone()
.
src/librustc_typeck/collect.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary ref
.
src/librustc_typeck/diagnostics.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/type/trait
Crater report contains no legitimate regressions (ignoring uses of |
6b84098
to
17ac55e
Compare
☔ The latest upstream changes (presumably #37676) made this pull request unmergeable. Please resolve the merge conflicts. |
17ac55e
to
0ae852c
Compare
@eddyb Rebased, but haven't run tests--started those locally (and Travis will test too, of course). |
src/librustc/ty/walk.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion was to move the .types().rev()
here.
src/librustc/traits/mod.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few indentation aberrations, here and in a few other places. Let me know if you want a list.
src/librustc/traits/select.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, to make this nicer I think you should call .skip_binder
on data_a
and data_b
(with a comment that it's reintroduced below).
src/librustc_typeck/astconv.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least use .skip_binder()
instead of .0
.
Renames TyTrait to TyDynamic.
Replaces instances of tcx.lang_items.require(..) with fatal unwrap with this method.
0ae852c
to
8b82fd7
Compare
Fixed review comments. r? @eddyb |
@bors r+ |
📌 Commit 8b82fd7 has been approved by |
…=eddyb Refactor TraitObject to Slice<ExistentialPredicate> For reference, the primary types changes in this PR are shown below. They may add in the understanding of what is discussed below, though they should not be required. We change `TraitObject` into a list of `ExistentialPredicate`s to allow for a couple of things: - Principal (ExistentialPredicate::Trait) is now optional. - Region bounds are moved out of `TraitObject` into `TyDynamic`. This permits wrapping only the `ExistentialPredicate` list in `Binder`. - `BuiltinBounds` and `BuiltinBound` are removed entirely from the codebase, to permit future non-constrained auto traits. These are replaced with `ExistentialPredicate::AutoTrait`, which only requires a `DefId`. For the time being, only `Send` and `Sync` are supported; this constraint can be lifted in a future pull request. - Binder-related logic is extracted from `ExistentialPredicate` into the parent (`Binder<Slice<EP>>`), so `PolyX`s are inside `TraitObject` are replaced with `X`. The code requires a sorting order for `ExistentialPredicate`s in the interned `Slice`. The sort order is asserted to be correct during interning, but the slices are not sorted at that point. 1. `ExistentialPredicate::Trait` are defined as always equal; **This may be wrong; should we be comparing them and sorting them in some way?** 1. `ExistentialPredicate::Projection`: Compared by `ExistentialProjection::sort_key`. 1. `ExistentialPredicate::AutoTrait`: Compared by `TraitDef.def_path_hash`. Construction of `ExistentialPredicate`s is conducted through `TyCtxt::mk_existential_predicates`, which interns a passed iterator as a `Slice`. There are no convenience functions to construct from a set of separate iterators; callers must pass an iterator chain. The lack of convenience functions is primarily due to few uses and the relative difficulty in defining a nice API due to optional parts and difficulty in recognizing which argument goes where. It is also true that the current situation isn't significantly better than 4 arguments to a constructor function; but the extra work is deemed unnecessary as of this time. ```rust // before this PR struct TraitObject<'tcx> { pub principal: PolyExistentialTraitRef<'tcx>, pub region_bound: &'tcx ty::Region, pub builtin_bounds: BuiltinBounds, pub projection_bounds: Vec<PolyExistentialProjection<'tcx>>, } // after pub enum ExistentialPredicate<'tcx> { // e.g. Iterator Trait(ExistentialTraitRef<'tcx>), // e.g. Iterator::Item = T Projection(ExistentialProjection<'tcx>), // e.g. Send AutoTrait(DefId), } ```
⌛ Testing commit 8b82fd7 with merge 8e373b4... |
Refactor ty::FnSig to contain a &'tcx Slice<Ty<'tcx>> We refactor this in order to achieve the following wins: - Decrease the size of `FnSig` (`Vec` + `bool`: 32, `&Slice` + `bool`: 24). - Potentially decrease total allocated memory due to arena-allocating `FnSig` inputs/output; since they are allocated in the type list arena, other users of type lists can reuse the same allocation for an equivalent type list. - Remove the last part of the type system which needs drop glue (#37965 removed the other remaining part). This makes arenas containing `FnSig` faster to drop (since we don't need to drop a Vec for each one), and makes reusing them without clearing/dropping potentially possible. r? @eddyb
@Mark-Simulacrum: Very late to the party, but I just ran into the the sort order while spelunking for #41444, and I'm curious about:
What does "correct" mean? I can see from the code that the only time the assertion runs is when it is passed something that has previously been sorted using the same
Why not just tie-break by |
Since we now represent I think I answered the second question as well. You do make a good point about possibly more efficient interning if we sorted with tie-breaking by Let me know if you have any more questions! |
You simply can't have more than one |
@Mark-Simulacrum: Thanks for the explanation. I have one follow-up question on the following (and it's not really a question about this code in particular any more):
The comment on
I guess it depends on what is meant by "same contents", but it would seem to me that at this point you could wind up interning both of the slices |
Slices can be compared by pointer and length because they're always interned, which means that |
For reference, the primary types changes in this PR are shown below. They may add in the understanding of what is discussed below, though they should not be required.
We change
TraitObject
into a list ofExistentialPredicate
s to allow for a couple of things:TraitObject
intoTyDynamic
. This permits wrapping only theExistentialPredicate
list inBinder
.BuiltinBounds
andBuiltinBound
are removed entirely from the codebase, to permit future non-constrained auto traits. These are replaced withExistentialPredicate::AutoTrait
, which only requires aDefId
. For the time being, onlySend
andSync
are supported; this constraint can be lifted in a future pull request.ExistentialPredicate
into the parent (Binder<Slice<EP>>
), soPolyX
s are insideTraitObject
are replaced withX
.The code requires a sorting order for
ExistentialPredicate
s in the internedSlice
. The sort order is asserted to be correct during interning, but the slices are not sorted at that point.ExistentialPredicate::Trait
are defined as always equal; This may be wrong; should we be comparing them and sorting them in some way?ExistentialPredicate::Projection
: Compared byExistentialProjection::sort_key
.ExistentialPredicate::AutoTrait
: Compared byTraitDef.def_path_hash
.Construction of
ExistentialPredicate
s is conducted throughTyCtxt::mk_existential_predicates
, which interns a passed iterator as aSlice
. There are no convenience functions to construct from a set of separate iterators; callers must pass an iterator chain. The lack of convenience functions is primarily due to few uses and the relative difficulty in defining a nice API due to optional parts and difficulty in recognizing which argument goes where. It is also true that the current situation isn't significantly better than 4 arguments to a constructor function; but the extra work is deemed unnecessary as of this time.