-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Allow reifying intrinsics to fn
pointers.
#86699
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
The implementation seems reasonable enough to me. |
The intrinsics lowering pass lowers some of intrinsics calls into MIR statements. Given that pass runs unconditionally for user constructed MIR, and coercing intrinsics into function pointers was so far impossible, the implementation of lowered intrinsics was removed from both codegen and interpreter. This will have to change now, possibly by reintroducing removed implementations or by running the pass for shims. |
The DRY thing to do would be to run the pass for shims, I suppose, but thanks for pointing that out, I wasn't aware such a pass got added. I'm not sure it's a priority, given the dearth of stably exposed intrinsics, and the fact that reification is a somewhat intentional action, but I will look into it if it's blocking landing this PR. (For the record, I'd rather have codegen ICEs, or working reification, than split up intrinsics into reifiable vs not, because it forces us to not add/modify intrinsics in a way that is incompatible with reification) |
I'm tagging this as T-lang and nominating, as it seems like a lang change. It'd perhaps be nice to write up a lang proposal or something that summarizes it. It's a short PR. The details are:
|
Note to self: still need to check whether |
The |
1ebdd02
to
2e00f3d
Compare
Discussed in T-compiler meeting (Zulip thread) @rustbot label -I-nominated |
@apiraino that was already handled in #86699 (comment) - the current nomination was for lang team. I will remove |
Thanks for the help with this! On top of all that, the module doesn't have a stability attribute, and so I believe it will inherit this from #[unstable(feature = "stdsimd", issue = "48556")]
mod core_arch; Also, I just re-checked everything else, and it does seem like |
To prevent this PR from being insta-stable, maybe the function pointer cast could be feature-gated for all intrinsics or prevented just for |
That might be possible, though it would defeat the goal of being able to revert #86003, and publicly expose those intrinsics. |
In case of preventing it just for |
We discussed this in the @rust-lang/lang meeting today, and we have no objections to the compiler team resolving this issue as planned. Our understanding is that the plan is to make intrinsics usable as if they were functions, and we agree with that plan. We don't have any concerns about however the compiler team plans to make that work. Let's use an FCP to confirm that: @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
☔ The latest upstream changes (presumably #86155) made this pull request unmergeable. Please resolve the merge conflicts. |
@rustbot label -to-announce |
Avoid using the `copy_nonoverlapping` wrapper through `mem::replace`. This is a much simpler way to achieve the pre-rust-lang#86003 behavior of `mem::replace` not needing dynamically-sized `memcpy`s (at least before inlining), than re-doing rust-lang#81238 (which needs rust-lang#86699 or something similar). I didn't notice it until recently, but `ptr::write` already explicitly avoided using the wrapper, while `ptr::read` just called the wrapper (and was the reason for us observing any behavior change from rust-lang#86003 in Rust-GPU). <hr/> The codegen test I've added fails without the change to `core::ptr::read` like this (ignore the `v0` mangling, I was using a worktree with it turned on by default, for this): ```llvm 13: ; core::intrinsics::copy_nonoverlapping::<u8> 14: ; Function Attrs: inlinehint nonlazybind uwtable 15: define internal void `@_RINvNtCscK5tvALCJol_4core10intrinsics19copy_nonoverlappinghECsaS4X3EinRE8_25mem_replace_direct_memcpy(i8*` %src, i8* %dst, i64 %count) unnamed_addr #0 { 16: start: 17: %0 = mul i64 %count, 1 18: call void `@llvm.memcpy.p0i8.p0i8.i64(i8*` align 1 %dst, i8* align 1 %src, i64 %0, i1 false) not:17 !~~~~~~~~~~~~~~~~~~~~~ error: no match expected 19: ret void 20: } ``` With the `core::ptr::read` change, `core::intrinsics::copy_nonoverlapping` doesn't get instantiated and the test passes. <hr/> r? `@m-ou-se` cc `@nagisa` (codegen test) `@oli-obk` / `@RalfJung` (miri diagnostic changes)
Triage: this still has merge conflicts |
2e00f3d
to
fddc321
Compare
Rebased, but switched to draft because the feature-gating part (#86699 (comment)) isn't done yet. For the record, the regression this was meant to solve, has been worked around by #87827. |
☔ The latest upstream changes (presumably #91475) made this pull request unmergeable. Please resolve the merge conflicts. |
The main change is in
ty/instance.rs
, which is to simply haveresolve_for_fn_ptr
handleInstanceDef::Intrinsic
the same way it does the other existing cases where a shim is needed to be able to have afn
pointer in the first place (virtual methods i.e.<dyn Trait as Trait>::method
, and#[track_caller]
functions).However, there is another important change, which is that unlike other functions, intrinsics have their type-level ABI change from the
extern "rust-intrinsic" fn
"pseudo-ABI" to the normal Rust ABI.This is possible because pseudo-ABIs like
extern "rust-intrinsic"
do not actually change the call ABI, but rather are used as a side-channel (instead of a more principled solution, like some#[rustc_intrinsic]
attribute).What this all means for the user is that they can/have to do
transmute as unsafe fn(T) -> U
, without the fact that the function was an intrinsic showing up in the typesystem at all.That type-level ABI aspect also ties in with the motivation for finally fixing this, which is #84297, where
ptr::{copy,copy_nonoverlapping}
becoming stable reexports of the intrinsics in #81238 was backwards incompatible - with this PR, that shouldn't be an issue anymore.(I also have a revert for #86003 ready - at least the parts not reverted already by e.g. #86295, if this PR is accepted; cc @pnkfelix)
In terms of this capability being insta-stable, we still get to control that via which intrinsics we mark stable.
The only one I could find right now is
mem::transmute
(and I've added a test that its size check still works when going through afn
pointer), and if we do the above mentioned #86003 revert, we'd also haveptr::{copy,copy_nonoverlapping}
.