Skip to content

Transitioning to superset enum variant causes unnecessary copy #146081

@erin-desu

Description

@erin-desu

When I have an enum whose variants are superset of the previous ones, transitioning to the superset variant unnecessarily copies the entire variant instead of just changing discriminant and copying the new data over.

https://rust.godbolt.org/z/Mjeq3d4MW

Example

use std::mem::{ManuallyDrop, take};

type Param = ManuallyDrop<String>;

#[derive(Default)]
enum State {
    #[default]
    None,
    A([Param; 16]),
    B([Param; 16], Param),
    C([Param; 16], Param, Param),
}

impl State {
    #[unsafe(no_mangle)]
    fn transition(&mut self, param: Param) {
        let taken = take(self);
        *self = match taken {
            Self::None | Self::C { .. } => Self::None,
            Self::A(a) => Self::B(a, param),
            Self::B(a, b) => Self::C(a, b, param),
        };
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-enumArea: Enums (discriminated unions, or more generally ADTs (algebraic data types))C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.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