Skip to content

Warn when using [foo; 0] where foo is a non-const expression that evaluates to a Drop type #79580

Open

Description

In #74836 it was discovered that [foo; 0] will leak foo, causing observable effects if foo has a destructor. In response #74857 was opened in order to warn users against using [foo; 0] to construct a zero-length array in favor of [], but this was deemed to be overkill.

However, since then some new information has emerged that I believe calls for re-evaluating this decision. The problem comes from the use of array-repeat expressions in constant contexts. Consider the following program, which works on stable Rust today:

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("dropped!")
    }
}

const FOO: Foo = Foo;

fn main() {
    println!("0 drops follow this");
    [FOO; 0];
    println!("1 drops follow this");
    [FOO; 1];
    println!("2 drops follow this");
    [FOO; 2];
}

While the stabilization of array-repeat expressions on constant values was accidental (#79270), people appear to be in agreement that this behavior is correct: #79270 (comment) . Specifically, it is considered correct that a constant array repeat expression [FOO; N] will run FOO's destructor N times.

Consider how this compares to the use of array-repeat expressions in non-constant contexts. For some non-constant expression [foo; N] where foo impls Drop:

  • When N is greater than 2, this will produce an insurmountable compile-time error (the compiler requires Copy, which is incompatible with Drop).

  • When N is 1, this will have identical results to the const-context array-repeat expression, and is not a problem.

  • When N is 0, this will run the destructor exactly once, which differs from the behavior of const-context array-repeat expressions, which will not run any destructor. (Technically this is contingent on Initializing a zero-length array leaks the initializer #74836 being fixed, but everybody agrees that the current leaking behavior is incorrect).

In light of this divergence of behavior between const and non-const array-repeat expressions, it's worth discussing whether #74857 should be revived, especially since the fix is as simple as not using [foo; 0] and simply using [] instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation (MIR interpretation)A-destructorsArea: Destructors (`Drop`, …)A-lintArea: Lints (warnings about flaws in source code) such as unused_mut.A-zstArea: Zero-sized types (ZST).T-langRelevant to the language 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