Skip to content

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

Closed

Description

@RalfJung

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.

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 3, 2023
  2. added
    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 3, 2023
  3. saethlin commented on Aug 3, 2023

    @saethlin
    Member

    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.

  4. saethlin commented on Aug 3, 2023

    @saethlin
    Member

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

  5. RalfJung commented on Aug 4, 2023

    @RalfJung
    MemberAuthor

    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.

  6. RalfJung commented on Aug 4, 2023

    @RalfJung
    MemberAuthor

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

  7. RalfJung commented on Aug 4, 2023

    @RalfJung
    MemberAuthor

    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?

  8. saethlin commented on Aug 4, 2023

    @saethlin
    Member

    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.

  9. RalfJung commented on Aug 4, 2023

    @RalfJung
    MemberAuthor

    Wow. That makes has_deref quite the footgun.

  10. added a commit that references this issue on Aug 6, 2023
  11. ouz-a commented on Aug 15, 2023

    @ouz-a
    Contributor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-cleanupCategory: PRs that clean code up or issues documenting cleanup.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions