-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Add ability to transmute (somewhat) with generic consts in arrays #106281
Conversation
r? @nagisa (rustbot has picked a reviewer for you, use r? to override) |
98c8e16
to
72f169a
Compare
This comment has been minimized.
This comment has been minimized.
80f2358
to
42ca47c
Compare
This comment has been minimized.
This comment has been minimized.
42ca47c
to
5dc4705
Compare
cc @eddyb may have some thoughts on the changes to the layout code. |
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.
Overall the approach looks sound (if compiler/lang teams are fine with it etc.), left some comments, don't really have much to say other than nitpicking though.
// constants are always pre-normalized into a canonical form so this | ||
// only needs to check if their pointers are identical. | ||
(SizeSkeleton::Generic(a), SizeSkeleton::Generic(b)) => a == b, |
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 doesn't need to be cheap, we could plausibly run a SAT/SMT solver here (since this is for "proving" two types have the same size). Feels weird to canonicalize ahead of time when ty::Const
itself doesn't do it, but I don't know much about "generic consts".
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 whether putting a whole SMT solver here would be reasonable, that seems like a lot of extra baggage for something that only gets rarely invoked.
I think just normalizing it for this specific use case is alright. I was also thinking about e graphs, but I'm not too familiar with it, and seems their library is a bit heavy
will update this after I get back from vacation in a week or so edit: am back! |
264454d
to
15ef66d
Compare
15ef66d
to
001f46d
Compare
r? rust-lang/compiler |
r? rust-lang/compiler |
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.
Probably need to take a second look at this in a couple of days, but have added some thoughts now.
001f46d
to
57ec610
Compare
5d9d218
to
9a0e99e
Compare
9a0e99e
to
b76dd8c
Compare
Should be good now! |
Can anybody please explain why this needs |
nvm, just saw @klensy's post. @bors r+ rollup |
☀️ Test successful - checks-actions |
Finished benchmarking commit (af06dce): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
|
@b-naber The meta-reason is that it avoids the "oops, the fork happened, need to unapprove all the PRs with the version in them so they get updated with the new number" problem. A new or stabilized gate always just uses the magic constant, and the release branching scripts make sure they get the real number. |
This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`. Added to enable experimenting with the request in <rust-lang#106281 (comment)> and because the portable-simd folks might be interested for dependently-sized array-vector conversions. It also simplifies a couple places in `core`.
…i-obk Add `intrinsics::transmute_unchecked` This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`. Added to enable experimenting with the request in <rust-lang#106281 (comment)> and because the portable-simd folks might be interested for dependently-sized array-vector conversions. It also simplifies a couple places in `core`. See also rust-lang#108442 (comment), where `CastKind::Transmute` was added having exactly these semantics before the lang meeting (which I wasn't in) independently expressed interest.
This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`. Added to enable experimenting with the request in <rust-lang/rust#106281 (comment)> and because the portable-simd folks might be interested for dependently-sized array-vector conversions. It also simplifies a couple places in `core`.
Add `intrinsics::transmute_unchecked` This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`. Added to enable experimenting with the request in <rust-lang/rust#106281 (comment)> and because the portable-simd folks might be interested for dependently-sized array-vector conversions. It also simplifies a couple places in `core`. See also rust-lang/rust#108442 (comment), where `CastKind::Transmute` was added having exactly these semantics before the lang meeting (which I wasn't in) independently expressed interest.
Stop using `<DefId as Ord>` in various diagnostic situations work towards rust-lang#90317 Reverts part of rust-lang#106281, as it sorts constants and that's problematic since it can contain `ParamConst`, which contains `DefId`s
Rollup merge of rust-lang#122820 - oli-obk:no_ord_def_id, r=estebank Stop using `<DefId as Ord>` in various diagnostic situations work towards rust-lang#90317 Reverts part of rust-lang#106281, as it sorts constants and that's problematic since it can contain `ParamConst`, which contains `DefId`s
Previously if the expression contained generic consts and did not have a directly equivalent type, transmuting the type in this way was forbidden, despite the two sizes being identical. Instead, we should be able to lazily tell if the two consts are identical, and if so allow them to be transmuted.
This is done by normalizing the forms of expressions into sorted order of multiplied terms, which is not generic over all expressions, but should handle most cases.
This allows for some basic transmutations between types that are equivalent in size without requiring additional stack space at runtime.
I only see one other location at which
SizeSkeleton
is being used, and it checks for equality so this shouldn't affect anywhere else that I can tell.See this Stackoverflow post for what was previously necessary to convert between types. This PR makes converting nested
T -> [T; 1]
transmutes possible, and[uB*2; N] -> [uB; N * 2]
possible as well.I'm not sure whether this is something that would be wanted, and if it is it definitely should not be insta-stable, so I'd add a feature gate.