Skip to content

stop adding dropck outlives requirements for [T; 0] #110288

Description

@lcnr

[T; 0] currently doesn't need drop glue by itself but still adds liveness requirements for T when used in a more complex value which already needs drop.

This behavior is identitical to PhantomData, which also does not need drop glue by itself but adds liveness requirements when used in values who do. I do not propose to change anything about PhantomData with this issue.

Example

playground

struct PrintOnDrop<'s>(&'s str);
impl<'s> Drop for PrintOnDrop<'s> {
    fn drop(&mut self) {
        println!("{}", self.0);
    }
}

fn to_array_zero<T>(_: T) -> [T; 0] {
    []
}

pub fn array_zero_by_itself() {
    let mut x = [];
    {
        let s = String::from("temporary");
        let p = PrintOnDrop(&s);
        x = to_array_zero(p)
    }
    // implicitly dropping `x` here, no drop glue needed,
    // so ignoring outlives requirements. NO ERROR
}

pub fn array_zero_in_tuple() {
    let mut x = ([], String::new());
    {
        let s = String::from("temporary");
        let p = PrintOnDrop(&s);
        x.0 = to_array_zero(p)
    }
    // implicitly dropping `x` here, drop glue needed to drop the `String`,
    // adding outlives requirements for the zero array. ERROR
}

This behavior is confusing. I propose that we don't add any dropck outlives requirements for arrays of length zero. This allows strictly more code to compile, it may however result in unsoundness if people rely on this behavior to guarantee errors.

Activity

  1. added
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Apr 13, 2023
  2. lcnr commented on Apr 13, 2023

    @lcnr
    ContributorAuthor

    cc #103413 for more details about dropck

    @rfcbot fcp merge

  3. rfcbot commented on Apr 13, 2023

    @rfcbot

    Team member @lcnr has proposed to merge this. The next step is review by the rest of the tagged team members:

    Concerns:

    Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

    See this document for info about what commands tagged team members can give me.

  4. added
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    on Apr 13, 2023
  5. RalfJung commented on Apr 13, 2023

    @RalfJung
    Member

    How (if at all) does this interact with const generics? What if the length is unknown but could be zero? Seems surprising that behavior depends so heavily on whether the compiler can "figure out" the length.

  6. lcnr commented on Apr 14, 2023

    @lcnr
    ContributorAuthor

    This happens after type inference, so we should only fail to evaluate for generic constants. In this case they are always considered to be potentially non-zero.

    Seems surprising that behavior depends so heavily on whether the compiler can "figure out" the length.

    yes, I considered to propose changing the behavior for arrays to always require drop glue, even for N == 0 because relying on the value of constants in this way is always a bit sketchy. The problem is that this is actually quite useful.

    I am a bit confused by why exactly this errors, but the following snippet would fail if we remove the special case for zero length arrays in needs_drop

    const fn zero_sized<T>() -> &'static [T; 0] {
        &[]
    }
    error[E0493]: destructor of `[T; 0]` cannot be evaluated at compile-time
     --> src/main.rs:2:6
      |
    2 |     &[]
      |      ^^ the destructor for this type cannot be evaluated in constant functions
    3 | }
      | - value is dropped here

    opened #110322 if you want to take a deeper look at this. Afaict we never actually drop [T; 0] here so this is the const check being too pessimistic (iirc using dataflow for that was too involved so we didn't end up stabilizing precise const drop).

    @rfcbot concern we could instead stop specialcasing [T; 0] in needs_drop

  7. added
    I-types-nominatedNominated for discussion during a types team meeting.
    on Apr 14, 2023
  8. RalfJung commented on Apr 14, 2023

    @RalfJung
    Member

    Afaict we never actually drop [T; 0] here so this is the const check being too pessimistic (iirc using dataflow for that was too involved so we didn't end up stabilizing precise const drop).

    What probably happens is that [] cannot get promoted any more because it looks like that would skip some drop glue. Presumably this also fails with your patch, saying the value does not live long enough?

    fn zero_sized<T>() -> &'static [T; 0] {
        &[]
    }
  9. lcnr commented on Apr 14, 2023

    @lcnr
    ContributorAuthor

    no, this still works 😅 apparently promotion does work. Had the same idea at first when seeing the test failures

  10. RalfJung commented on Apr 14, 2023

    @RalfJung
    Member

    Hm, maybe promotion has its own knowledge that [] never needs to run any drop glue...

  11. steffahn commented on Apr 16, 2023

    @steffahn
    Member

    Promotion for arrays (unlike any other type) even supports mutable references, i.e. &mut [] promotes, so I wouldn’t be surprised if &[] hits some special case as well.

  12. lcnr commented on Apr 18, 2023

    @lcnr
    ContributorAuthor

    @rfcbot resolve we could instead stop specialcasing [T; 0] in needs_drop

    doing so results in too many regressions, see #110322

  13. changed the title [-]`[T; 0]` adding outlives requirements to dropck[/-] [+]drop adding outlives requirements to dropck for `[T; 0]`[/+] on Apr 18, 2023
  14. 19 remaining items

  15. removed
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Aug 29, 2023
  16. rfcbot commented on Aug 29, 2023

    @rfcbot

    The final comment period, with a disposition to merge, as per the review above, is now complete.

    As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

    This will be merged soon.

  17. added a commit that references this issue on Jul 31, 2024
    b22c48e
  18. added a commit that references this issue on Aug 1, 2024
    78f2641
  19. lcnr commented on Aug 1, 2024

    @lcnr
    ContributorAuthor

    implemented in #128438, we still need to update the documentation however, cc @Bryanskiy

  20. reopened this on Aug 1, 2024
  21. SoniEx2 commented on Aug 1, 2024

    @SoniEx2
  22. added 2 commits that reference this issue on Aug 1, 2024
  23. added a commit that references this issue on Aug 1, 2024
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

    T-typesRelevant to the types team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions