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

Cleanup: Place::is_indirect vs Place::has_deref #114401

Closed
RalfJung opened this issue Aug 3, 2023 · 8 comments
Closed

Cleanup: Place::is_indirect vs Place::has_deref #114401

RalfJung opened this issue Aug 3, 2023 · 8 comments
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Aug 3, 2023

Since #97077 we have these two methods is_indirect and has_deref that are documented as doing the exact same thing, but don't even mention each other in the documentation. Calling the wrong one can either lead to slow code or to subtle bugs. That's pretty bad, we should find a way to clean this up -- and at the very least, this needs better documentation.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 3, 2023
@Noratrieb Noratrieb added C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 3, 2023
@saethlin
Copy link
Member

saethlin commented Aug 3, 2023

I think this is documented in Place::has_deref:

/// If MirPhase >= Derefered and if projection contains Deref,
/// It's guaranteed to be in the first place
pub fn has_deref(&self) -> bool {
// To make sure this is not accidentally used in wrong mir phase
debug_assert!(
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
);
self.projection.first() == Some(&PlaceElem::Deref)
}

Though why we have that assertion in only one place and not all the others, I have no idea.

@saethlin
Copy link
Member

saethlin commented Aug 3, 2023

I tried pasting this check into is_indirect and it fails in CopyProp so yeah I have no idea 🤷

@RalfJung
Copy link
Member Author

RalfJung commented Aug 4, 2023

That doc comment doesn't really tell a user much, does it? It should start by describing what the function does, which is the same as is_indirect. And then it should follow "WARNING: only call this in MIR passes with MirPhase >= Derefered! It will produce wrong results afterwards." But also is_indirect should probably say "If this is called in a MIR pass with MirPhase >= Derefered, use has_deref instead, it will be faster".

One of the two should probably be renamed, there's no good reason for them to have so different names when they implement almost the same spec.

The current comment is an implementation comment that could go inside the function, but not suitable as a doc comment.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 4, 2023

Also the methods on Place should probably just delegate to the ones on PlaceRef to avoid the duplication.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 4, 2023

I tried pasting this check into is_indirect and it fails in CopyProp so yeah I have no idea shrug

Uh, but doesn't that run sufficiently late that it should be allowed to use has_deref?

@saethlin
Copy link
Member

saethlin commented Aug 4, 2023

Uh, but doesn't that run sufficiently late that it should be allowed to use has_deref?

Yes. At a guess, there is MIR which is temporarily invalid during a pass.

@RalfJung
Copy link
Member Author

RalfJung commented Aug 4, 2023

Wow. That makes has_deref quite the footgun.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Aug 6, 2023
Add documentation to has_deref

Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose.

cc rust-lang#114401

r? `@RalfJung`
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Aug 10, 2023
Add documentation to has_deref

Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose.

cc rust-lang/rust#114401

r? `@RalfJung`
@ouz-a
Copy link
Contributor

ouz-a commented Aug 15, 2023

Maybe we can close this since #114505 is merged now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants