Skip to content
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

Taking a raw ref (&raw (const|mut)) of a deref of pointer (*ptr) is always safe #129248

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

compiler-errors
Copy link
Member

T-opsem decided in rust-lang/reference#1387 that *ptr is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read.

This also relaxes the DEREF_NULLPTR lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification.

This does not change the behavior of addr_of!((*ptr).field), since field projections still require the projection is in-bounds.

I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc @rust-lang/opsem

@rustbot
Copy link
Collaborator

rustbot commented Aug 18, 2024

r? @nnethercote

rustbot has assigned @nnethercote.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 18, 2024
@RalfJung
Copy link
Member

Seems more like a lang question to me than an opsem question -- from an opsem side, the relevant question is whether there is UB, and the answer is "no". But from a lang perspective, it may seem odd to have unsafe rules that depend on the place-vs-value distinction, as many programmers do not properly understand this distinction. But maybe it's good that they will wonder " 🤔 why is this safe?" and then can be taught about said distinction?

Also note that due to #117288, sometimes we do have UB just from constructing a place. That's a MIR building bug but we should probably fix it before accepting such code as safe. (Sorry I didn't remember this when we spoke earlier.)

@compiler-errors
Copy link
Member Author

👍 yep, this could be blocked on #117288 then. I think we can probably T-lang-nominate this regardless for discussion.

@compiler-errors compiler-errors added T-lang Relevant to the language team, which will review and decide on the PR/issue. I-lang-nominated Nominated for discussion during a lang team meeting. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 18, 2024
@nnethercote
Copy link
Contributor

The code changes seem fine, so r=me on them if/when lang/opsem are happy with this.

@scottmcm
Copy link
Member

Thinking about the DEREF_NULLPTR relaxation, I was pondering whether we should still lint -- but not say "this is UB" when it's not, of course -- on this as something that we might want you to do in a different way instead. @compiler-errors convinced me that rustc is not the correct place for that, however, and a "clippy suspicious" or similar would be the place to do that instead, if useful.

@traviscross
Copy link
Contributor

@rustbot labels -I-lang-nominated

We discussed this in lang triage today and agreed that this was both a good idea and one that's a natural consequence of our other recent decisions and so can go without FCP.

@bors r=nnethercode

@rustbot rustbot removed the I-lang-nominated Nominated for discussion during a lang team meeting. label Aug 21, 2024
@bors
Copy link
Contributor

bors commented Aug 21, 2024

📌 Commit 25d617f has been approved by nnethercode

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 21, 2024
@compiler-errors
Copy link
Member Author

@bors r-

This is still unsound!! #117288

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 21, 2024
@compiler-errors compiler-errors added S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 21, 2024
@traviscross
Copy link
Contributor

Good catch. Thanks.

@rust-log-analyzer

This comment has been minimized.

@workingjubilee
Copy link
Member

warning: the feature raw_ref_op has been stable since 1.82.0-nightly and no longer requires an attribute to enable

Truly?!

@RalfJung
Copy link
Member

Yes, truly. :)

#127679

@RalfJung
Copy link
Member

So let _ = *raw_ptr; and match *raw_ptr { _ => ... } are not affected by this?

That does seem a bit inconsistent. It doesn't seem super useful to write code like that, but then it doesn't seem super useful to write &raw const *ptr either.

@compiler-errors
Copy link
Member Author

@RalfJung: No, that would need to have another special case in the THIR.

@bors
Copy link
Contributor

bors commented Sep 15, 2024

☔ The latest upstream changes (presumably #130390) made this pull request unmergeable. Please resolve the merge conflicts.

@compiler-errors
Copy link
Member Author

That does seem a bit inconsistent. It doesn't seem super useful to write code like that, but then it doesn't seem super useful to write &raw const *ptr either.

🤷 I'd still like to fix it, regardless, I think, especially now that #117288 is closed. I'd also like if let _ = *raw_ptr; weren't unsafe, but that's far more difficult for unsafeck to implement.

@scottmcm
Copy link
Member

scottmcm commented Oct 7, 2024

I'd also like if let _ = *raw_ptr; weren't unsafe

I mean, we intentionally changed it to require being in an unsafe block...

@compiler-errors
Copy link
Member Author

compiler-errors commented Oct 7, 2024

Because it was unsound? Could you provide some context?

@compiler-errors
Copy link
Member Author

also this is

@rustbot ready

:D

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Oct 11, 2024
@nnethercote
Copy link
Contributor

@RalfJung, @scottmcm: any objections before I approve this?

@RalfJung
Copy link
Member

Procedurally it has been approved by t-lang. I'm not very familiar with THIR so it's hard for me to say whether the implementation matches the intent. We don't have a dedicated test for the cases that should be rejected, but tests/ui/lint/lint-deref-nullptr.rs and tests/ui/static/raw-ref-deref-without-unsafe.rs to cover the most important cases I can think of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants