-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
make &mut !Unpin not dereferenceable, and Box<!Unpin> not noalias #106180
Conversation
r? @jackh726 (rustbot has picked a reviewer for you, use r? to override) |
The Miri subtree was changed cc @rust-lang/miri |
Cc @nikic due to LLVM attribute involvement |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit 3dbce6b7db10c346bec633288dcd314e23b80a41 with merge d0517ed036a21986873e247b24636d0f55aadebb... |
This comment has been minimized.
This comment has been minimized.
No concerns from my side. |
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
3dbce6b
to
28ed626
Compare
Finished benchmarking commit (d0517ed036a21986873e247b24636d0f55aadebb): comparison URL. Overall result: no relevant changes - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesThis benchmark run did not return any relevant results for this metric. |
let raw = x as *mut _; | ||
drop(unsafe { Box::from_raw(raw) }); | ||
}); | ||
} |
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.
FWIW we could keep this as UB (by still protecting &mut !Unpin
references). But I don't see a good reason for doing that... and it would be asymmetric with &!Freeze
references.
28ed626
to
cea1604
Compare
@rust-lang/lang not sure if this needs a full FCP, but I nominated this anyway to bring it to your attention -- I think putting Put differently I think everywhere that we emit |
cea1604
to
e68533e
Compare
I have also added to this PR a commit which fixes a problem pointed out by @Darksonn: we are currently adding |
e68533e
to
f48d972
Compare
Cc @rust-lang/wg-mir-opt (AFAIK currently no MIR optimizations do anything aliasing-related but still) |
☔ The latest upstream changes (presumably #106371) made this pull request unmergeable. Please resolve the merge conflicts. |
All right, looks like I now need someone from t-compiler to review. @jackh726 you are currently assigned. Does that work or should I re-assign? |
The code that consumes PointerKind (`adjust_for_rust_scalar` in rustc_ty_utils) ended up using PointerKind variants to talk about Rust reference types (& and &mut) anyway, making the old code structure quite confusing: one always had to keep in mind which PointerKind corresponds to which type. So this changes PointerKind to directly reflect the type. This does not change behavior.
See rust-lang/unsafe-code-guidelines#381 for discussion.
20a42c8
to
675dffb
Compare
} | ||
} | ||
}; | ||
let pointee_info = match *this.ty.kind() { |
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.
For some reason rustfmt decided to completely change how this match
is formatted. Some recent other PR made the inverse change, and resolving those conflicts was quite painful (git is not great at handling whitespace differences during rebasing). @rust-lang/rustfmt any idea why this back-and-forth is happening? rustfmt seems to sometimes perefer
let var =
match expr {
pat => ...
};
over
let val = match expr {
pat => ...
};
even though I would think the latter is always preferable?
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 is where the inverse change recently happened.
675dffb
to
1ef1687
Compare
I can review, but I'm not sure if I'm the best person for it (so will need to allocate some time to actually grok what's going on) |
frozen: optimize && ty.is_freeze(tcx, cx.param_env()), | ||
}, | ||
hir::Mutability::Mut => PointerKind::MutableRef { | ||
unpin: optimize && ty.is_unpin(tcx, cx.param_env()), |
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 changed the behaviour of mutable ref in no-opt builds from SharedMutable
to UniqueBorrowedPinned
, as opposed to what is claimed in the commit message.
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.
That doesn't actually change the emitted flags though, so the commit message is still correct. Or did I miss a case?
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.
It changes the emitted flags if you only look at that commit, but of course the latter commits unify the behaviour of these two so the flags ended up being the same. I pointed this out because I'm reviewing per commit.
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.
It changes the emitted flags if you only look at that commit,
I don't think it does... in no-opt builds we don't emit any flags either way.
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.
If only this commit is applied then we will start emitting dereferenceable
for mutable refs? Or am I missing something obvious?
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.
When optimizations are disabled, we don't emit any of these attributes, no matter what happens here. That logic is... somewhere, I honestly don't know where exactly.
Happy to assign someone else, if you prefer (and maybe have an idea about who would be a good reviewer). |
r? @nbdd0121 |
Failed to set assignee to
|
Oh, lol... bummer.^^ |
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.
The compiler change looks correct and consistent with the PR description. I am not familiar enough with MIRI to comment about the MIRI change.
Yeah :) sorry. I work on the compiler a lot but isn't in the team. |
@bors delegate=nbdd0121 |
✌️ @nbdd0121 can now approve this pull request |
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (dffea43): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
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.
|
See rust-lang/unsafe-code-guidelines#381 and this LLVM discussion. The exact semantics of how
noalias
anddereferenceable
interact are unclear, and @comex found a case of LLVM actually exploiting that ambiguity for optimizations. I think for now we should treat LLVMdereferenceable
as implying a "fake read" to happen immediately at the top of the function (standing in for the spurious reads that LLVM might introduce), and that fake read is subject to all the usualnoalias
restrictions. This means we cannot putdereferenceable
on&mut !Unpin
references as those references can alias with other references that are being read and written inside the function (e.g. for self-referential generators), meaning the fake read introduces aliasing conflicts with those other accesses.For
&
this is already not a problem due to #98017 which removed thedereferenceable
attribute for other reasons.Regular
&mut Unpin
references are unaffected, so I hope the impact of this is going to be tiny.The first commit does some refactoring of the
PointerKind
enum since I found the old code very confusing each time I had to touch it. It doesn't change behavior.Fixes rust-lang/miri#2714
EDIT: Turns out our
Box<!Unpin>
treatment was incorrect, too, so the PR also fixes that now (in codegen and Miri): we do not putnoalias
on these boxes any more.