Skip to content

Miscompilation where binding only some fields leaks the others #90752

Closed
@mk12

Description

@mk12

I found a bug where Rust leaks values (never calls drop). This is the root cause of a memory leak we saw in a Fuchsia test, caught by LeakSanitizer: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=87961.

This is as far as I could minimize it:

#![allow(unused)]

struct S(u32);

impl Drop for S {
    fn drop(&mut self) {
        println!("dropping {}", self.0);
    }
}

enum E {
    A,
    B((S, S)),
}

fn main() {
    let mut foo = Some(E::A);
    match foo {
        Some(E::A) => (),
        _ => return,
    }
    foo.insert(E::B((S(1), S(2))));
    match foo {
        Some(E::B((x, _))) => {}
        _ => {}
    }
}

Expected output:

dropping 2
dropping 1

Actual output:

dropping 1

It leaked S(2). If you change (x, _) to (_, x) in the second match statement, it leaks S(1) instead. If you bind neither (_, _) or both (x, y), then both get dropped as expected.

If you use Box<u8> instead of S, you can detect a memory leak using LeakSanitizer or Valgrind.

Meta

I reproduced this on stable:

rustc 1.56.1 (59eed8a2a 2021-11-01)
binary: rustc
commit-hash: 59eed8a2aac0230a8b53e89d4e99d55912ba6b35
commit-date: 2021-11-01
host: x86_64-unknown-linux-gnu
release: 1.56.1
LLVM version: 13.0.0

And on nightly:

rustc 1.58.0-nightly (8b09ba6a5 2021-11-09)
binary: rustc
commit-hash: 8b09ba6a5d5c644fe0f1c27c7f9c80b334241707
commit-date: 2021-11-09
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0

Metadata

Metadata

Labels

A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-destructorsArea: Destructors (`Drop`, …)A-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.P-criticalCritical priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions