miri: require (almost) all 1-ZST arguments to be actually passed#156085
miri: require (almost) all 1-ZST arguments to be actually passed#156085RalfJung wants to merge 1 commit into
Conversation
|
rustbot has assigned @nikomatsakis. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
@bors try @rust-timer queue |
|
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
|
⌛ Trying commit 403e9b0 with merge 583ebe0… To cancel the try build, run the command Workflow: https://github.com/rust-lang/rust/actions/runs/25256422338 |
miri: require (almost) all 1-ZST arguments to be actually passed
403e9b0 to
e7467e2
Compare
| /// Determine whether this argument can be safely ignored. | ||
| /// We have to ignore closures that didn't capture anything to ensure that their | ||
| /// coercion to function pointers is sound. We don't want to ignore anything else | ||
| /// since we don't actually guarantee that anything is ever ignored. | ||
| fn is_ignored_arg(arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool { | ||
| let can_ignore = matches!(arg.layout.ty.kind(), ty::Closure (_def, closure_args) if { | ||
| closure_args.as_closure().upvar_tys().is_empty() | ||
| }); |
There was a problem hiding this comment.
I feel like this should mention that normally ZSTs are ignored. But maybe you disagree and think that's base knowledge for Rust argument passing, which would be fine with me.
The connection to closure coercion is turning my brain into a pretzel. Does this mean that we still ignore the argument in this?
fn func<T>(_: T) {}
func(|| {});There was a problem hiding this comment.
I have extended the comment, does that help?
The connection to closure coercion is turning my brain into a pretzel. Does this mean that we still ignore the argument in this?
Yes. That's unfortunate, ideally we'd still report UB if that argument gets ignored. However, I'm not sure it's worth trying to restrict this. It seems non-trivial to figure out whether the callee is actually a closure. But maybe you have a good idea for how to do that?
There was a problem hiding this comment.
Conceptually, I think of the closure captures being implicitly passed to closure calls, not literally self. But of course the FnOnce trait takes self so I suspect trying to implement my mental model would be really fiddly, if even possible.
There was a problem hiding this comment.
In MIR closures are just normal functions -- closure conversion already happened at that point. So we can't really treat them as anything else.
The best we could do is check the DefId of the callee and figure out if it is a closure, and then treat the first parameter different.
e7467e2 to
3427f02
Compare
|
The new explanation is much easier for me to follow. Thanks. r? saethlin |
|
@bors try- |
|
Unknown command "try-". Run |
|
@bors try cancel |
|
Try build cancelled. Cancelled workflows: |
This comment has been minimized.
This comment has been minimized.
3427f02 to
ec802b2
Compare
|
This pull request was unapproved. |
7aad1ad to
2763bb3
Compare
This comment has been minimized.
This comment has been minimized.
|
Miri reports no UB for this code with this PR. Is this intended? use std::mem::transmute;
fn main() {
let f: fn(i32) = |x: i32| {
println!("{x}");
};
let g: fn((), i32) = unsafe { transmute(f) };
g((), 123);
}I think Miri is treating the |
|
It is less intended and more unavoidable. Miri also doesn't report UB for code that incorrectly relies on |
This comment has been minimized.
This comment has been minimized.
|
@saethlin what do you think about the latest version of this? |
2763bb3 to
5d2de1b
Compare
This comment has been minimized.
This comment has been minimized.
|
@theemathas thinking about your example again I think it is in fact covered by our documented ABI guarantees since we say that all 1-ZST are ABI compatible, with both |
💯 We could avoid this complication by having the closure-to-fn-ptr coercion insert a shim that does the ABI adjustment. But that's outside the parts of the compiler I am comfortable in... |
…hlin miri: require (almost) all 1-ZST arguments to be actually passed We can't ignore *all* of them since the compiler itself relies on non-capturing closure arguments being ignored. Fixes rust-lang/miri#4993 Cc @folkertdev since it also changes the checks for variadics.
…hlin miri: require (almost) all 1-ZST arguments to be actually passed We can't ignore *all* of them since the compiler itself relies on non-capturing closure arguments being ignored. Fixes rust-lang/miri#4993 Cc @folkertdev since it also changes the checks for variadics.
|
This pull request was unapproved. This PR was contained in a rollup (#157225), which was unapproved. |
5d2de1b to
a96cc82
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
This PR was contained in a rollup (#157225), which was closed. |
|
@bors r=saethlin |
View all comments
We can't ignore all of them since the compiler itself relies on non-capturing closure arguments being ignored.
Fixes rust-lang/miri#4993
Cc @folkertdev since it also changes the checks for variadics.